Repository navigation
Rule proposal: form-prefill-sanitize — extend checkout-checkbox-sanitize to text/email/select prefills #121
Copy link
Copy link
Open
Labels
enhancementNew feature or requestNew feature or requestrule-proposalProposed new defense rule, pending triage/citation reviewProposed new defense rule, pending triage/citation review
Description
Category
New defense rule (extension of the checkout-checkbox-sanitize family)
What problem does this solve?
checkout-checkbox-sanitize clears pre-checked checkboxes on checkout pages so the agent doesn't inherit silent opt-ins. The same dark pattern — Mathur et al.'s Preselection — exists for non-checkbox inputs:
- Pre-populated
<select>defaults that pick the costliest shipping speed - Pre-filled hidden inputs carrying affiliate / referral / promo IDs that bias pricing or attribution
- Pre-filled email/phone fields nudging the user toward marketing signup
- Pre-selected radio defaults on tipping prompts ("18% / 20% / 22% / Custom" with 22% pre-checked)
The agent is then expected to re-select what it actually wants, same contract as the existing checkbox rule.
Proposed solution
On the same checkout-shaped URL gate, walk form controls and:
- Clear pre-populated
<input type="text|email|tel|number">values when the page state suggests pre-fill (value present without user input — detectable on initial DOM). - Reset
<select>to its first option (or a blank option if one exists) when the default differs from the natural-first choice. - Reset
<input type="radio">groups to unchecked when a default is server-supplied. - Clear
valueon<input type="hidden">whosenamematches a curated affiliate/referral/promo pattern (*aff*,*ref*,*promo*,*utm_*,coupon_id,discount_code) — but only on payment/order pages.
Out of scope for v1: role="textbox" / contenteditable widgets, complex date pickers, anything inside a payment-processor iframe.
Alternatives considered
- Bundle into
checkout-checkbox-sanitizeinstead of a new rule. Reasonable; the toggle becomes a bigger hammer. Splitting keeps user control finer-grained because text-field clearing has higher FP risk than checkbox clearing. - Synthetic blur/change event after clearing. Some sites recalc totals on input events; consider v2 if sites silently re-prefill on
inputwithout it.
Controlling false positives
- Strict URL gate. Payment/order paths only (
/cart,/checkout,/basket,/bag,/payment,/order) — never login or arbitrary forms. Reuse the exact gate ofcart-addon-annotateandcheckout-checkbox-sanitizeso the surface is identical to a rule that's already in production. - Hard denylist for safety-critical hidden inputs. Never clear
<input type="hidden">whosenamematches CSRF/cart/session shapes:_csrf,csrf_token,authenticity_token,cart_id,order_id,session*,nonce,state,_token, anything containingsignature. Failure mode here is the form silently rejecting submit, which is worse than the original dark pattern. - Allowlist for hidden-input clearing. Only clear hidden inputs whose
namematches the affiliate/promo pattern set above. Anything outside the allowlist is preserved. <select>: only reset when the default value is NOT the first option. If the first option is selected (natural default — common pattern is<option value="">Select…</option>or<option>Standard shipping</option>first), the rule does nothing. Avoids clobbering legitimate first-option defaults.- Timing. Run on
DOMContentLoaded, before browser autofill. Browser autofill that runs after the rule is preserved — meaning the user's password manager and saved addresses still work for inputs the rule has already cleared. Document the ordering explicitly so the contract is clear. - Geofencing-aware select defaults. Country/state preselection based on geo is usually legitimate. Mitigation: only reset
<select>when the default deviates from the first option AND the field name is in a sneaking-prone set (shipping speed, tip percent, delivery slot, donation amount, insurance plan). Don't touch country/state/region selects. - Per-host kill-switch. Loyalty-program checkouts where saved details reappear by design (Amazon 1-Click, Apple Pay flows) can be denylisted by host. These flows are the user's intent.
- No-op on inputs the user has actually focused. If
document.activeElementor:focus-visiblematched a field at any point, skip clearing it on rescan. - Graceful-failure mode. The worst user-facing outcome is "I need to retype" — recoverable. Document this so a user can clearly attribute the friction to the rule and toggle it off.
Prior art / references
- Mathur et al. (CSCW 2019), Dark Patterns at Scale. — Preselection category; already cited.
- Brignull, deceptive.design — Preselection.
- WHATWG HTML autocomplete attribute spec — informs which fields are legitimate autofill targets vs. server-pushed prefills.
- Adjacent OSS: Consent-O-Matic sets values to opt out on consent forms — same mechanic, different intent.
Tagged Impact L–M / Complexity M.
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestrule-proposalProposed new defense rule, pending triage/citation reviewProposed new defense rule, pending triage/citation review
Activity
[-]Rule proposal: form-prefill-clear — extend checkout-checkbox-sanitize to text/email/select prefills[/-][+]Rule proposal: form-prefill-sanitize — extend checkout-checkbox-sanitize to text/email/select prefills[/+]twschiller commentedon Jun 6, 2026
Proposal: split into an annotate-first rule and a narrow sanitize rule
This proposal bundles five categories (text/email/tel, select, radio, hidden affiliate) under one sanitize contract. The FP profile across those categories isn't uniform — visible inputs are nearly indistinguishable from legitimate browser autofill / multi-step persistence / remembered preferences, while hidden affiliate inputs are allowlist-narrow and unambiguous. Annotation absorbs the high-FP categories at lower cost; sanitize stays for the one category where annotation can't do the job.
Rule 1:
form-prefill-annotate(default-on, sibling ofcart-addon-annotate/hidden-fee-annotate)Annotate-only — no values are cleared. Prepends an inline chip near the field so the agent reads "pre-populated" in its snapshot and decides whether to overwrite.
Scope by category:
valueon initial DOM → chip on the field's label/wrapper:[abs: pre-populated — verify before submit]. URL-gated to checkout. Skip if the input hasautocomplete=matching a legitimate target (name,email,tel,street-address, etc.) and the value matches the autofill shape (rough heuristic, accept FPs here).<select>whose initialselectedIndex !== 0and not in the geo/country/state allowlist → chip:[abs: default "<label>" is not first option]. No reset. Geo selects are explicitly excluded.[abs: "<label>" pre-selected]. No deselect (would break required-selection submits).[abs: form carries pre-filled affiliate/promo metadata]. Value not touched here — handled by Rule 2.FP control: URL gate (
isCheckoutUrl), per-host denylist, skip ifdocument.activeElementhas ever matched the field (cooperate with autofill ordering), cap chip count per form to avoid noise on long forms.Rule 2:
hidden-affiliate-sanitize(default-on, narrow allowlist)The only sanitize action that stays in v1. Clears
valueon<input type=\"hidden\">whosenamematches a curated allowlist (utm_*,aff*,ref*,promo*,coupon_id,discount_code). Annotation is the wrong tool here — the value is submitted regardless of any chip, and the agent never reads hidden values into a decision.Hard denylist (CSRF/cart/session shapes) takes precedence, matching the original list above. Per-host kill-switch for known Amazon-1-Click / Apple Pay flows.
Why split
hidden-fee-annotate(Rule proposal: hidden-fee-annotate — annotate drip-pricing fees added during checkout #119).Open questions before coding
value=on hidden inputs into their state, or only visible text? If they ignore hidden inputs entirely, Rule 2's "annotate alternative" is moot and sanitize is the only useful posture (assumed above, worth confirming).Feat: hidden-affiliate-sanitize rule for affiliate/UTM/promo metadata (…
Feat: form-prefill-annotate rule for preselected form controls (#121) (…
Feat: hidden-affiliate-sanitize rule for affiliate/UTM/promo metadata (…
Feat: hidden-affiliate-sanitize rule for affiliate/UTM/referral metad…