Compare commits
3
Commits
657f50a135
..
v1.0.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5aa66ff37a | ||
|
|
eb043bba4a | ||
|
|
68560534ac |
+14
-2
@@ -1,6 +1,16 @@
|
|||||||
/** Field block types that don't carry a submittable value. */ const NON_DATA_BLOCKS = new Set([
|
/** Field block types that don't carry a submittable value. */ const NON_DATA_BLOCKS = new Set([
|
||||||
'message'
|
'message'
|
||||||
]);
|
]);
|
||||||
|
/**
|
||||||
|
* Keys injected by the captcha widget itself, not by the form definition.
|
||||||
|
* Cloudflare Turnstile adds a hidden <input name="cf-turnstile-response"> after
|
||||||
|
* a successful challenge; reCAPTCHA adds 'g-recaptcha-response'. Since the
|
||||||
|
* plugin drives Turnstile end-to-end, these are legitimate artifacts — they
|
||||||
|
* must not count as "unknown fields" and trip the anti-tampering check.
|
||||||
|
*/ const CAPTCHA_KEYS = new Set([
|
||||||
|
'cf-turnstile-response',
|
||||||
|
'g-recaptcha-response'
|
||||||
|
]);
|
||||||
/** Hard ceiling on a single field's length, independent of the form config. */ const MAX_FIELD_LENGTH = 5000;
|
/** Hard ceiling on a single field's length, independent of the form config. */ const MAX_FIELD_LENGTH = 5000;
|
||||||
/**
|
/**
|
||||||
* Checks submitted data against the form's own definition, rather than trusting
|
* Checks submitted data against the form's own definition, rather than trusting
|
||||||
@@ -60,8 +70,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Reject outright if the payload carried keys the form doesn't define — a
|
// Reject outright if the payload carried keys the form doesn't define — a
|
||||||
// sign the request wasn't produced by the rendered form.
|
// sign the request wasn't produced by the rendered form. Captcha keys are
|
||||||
const unknownKeys = Object.keys(data).filter((k)=>!known.has(k));
|
// exempt: the widget injects them into the rendered form, so they're expected,
|
||||||
|
// not tampering.
|
||||||
|
const unknownKeys = Object.keys(data).filter((k)=>!known.has(k) && !CAPTCHA_KEYS.has(k));
|
||||||
if (unknownKeys.length > 0) {
|
if (unknownKeys.length > 0) {
|
||||||
return {
|
return {
|
||||||
kind: 'unknown_fields',
|
kind: 'unknown_fields',
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@intecion/ipal-kit",
|
"name": "@intecion/ipal-kit",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"description": "Intecion Payload Advanced Library — a Payload CMS 3 plugin: i18n, SEO, forms, consent, analytics, blog/archives.",
|
"description": "Intecion Payload Advanced Library — a Payload CMS 3 plugin: i18n, SEO, forms, consent, analytics, blog/archives.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -34,6 +34,15 @@ export type FormValidationResult =
|
|||||||
/** Field block types that don't carry a submittable value. */
|
/** Field block types that don't carry a submittable value. */
|
||||||
const NON_DATA_BLOCKS = new Set(['message'])
|
const NON_DATA_BLOCKS = new Set(['message'])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keys injected by the captcha widget itself, not by the form definition.
|
||||||
|
* Cloudflare Turnstile adds a hidden <input name="cf-turnstile-response"> after
|
||||||
|
* a successful challenge; reCAPTCHA adds 'g-recaptcha-response'. Since the
|
||||||
|
* plugin drives Turnstile end-to-end, these are legitimate artifacts — they
|
||||||
|
* must not count as "unknown fields" and trip the anti-tampering check.
|
||||||
|
*/
|
||||||
|
const CAPTCHA_KEYS = new Set(['cf-turnstile-response', 'g-recaptcha-response'])
|
||||||
|
|
||||||
/** Hard ceiling on a single field's length, independent of the form config. */
|
/** Hard ceiling on a single field's length, independent of the form config. */
|
||||||
const MAX_FIELD_LENGTH = 5000
|
const MAX_FIELD_LENGTH = 5000
|
||||||
|
|
||||||
@@ -95,8 +104,10 @@ export async function validateSubmission(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reject outright if the payload carried keys the form doesn't define — a
|
// Reject outright if the payload carried keys the form doesn't define — a
|
||||||
// sign the request wasn't produced by the rendered form.
|
// sign the request wasn't produced by the rendered form. Captcha keys are
|
||||||
const unknownKeys = Object.keys(data).filter((k) => !known.has(k))
|
// exempt: the widget injects them into the rendered form, so they're expected,
|
||||||
|
// not tampering.
|
||||||
|
const unknownKeys = Object.keys(data).filter((k) => !known.has(k) && !CAPTCHA_KEYS.has(k))
|
||||||
if (unknownKeys.length > 0) {
|
if (unknownKeys.length > 0) {
|
||||||
return { kind: 'unknown_fields', ok: false, reason: 'invalid' }
|
return { kind: 'unknown_fields', ok: false, reason: 'invalid' }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user