Step 3 / Select topic Frontend Security Hard
What this bank covers
- Tag blacklists miss event handlers
- How the fragment source is serialised
- searchParams decodes automatically
- Not every insertion API is an HTML sink
- String-to-code sinks
- Double decoding a fragment source
- Sanitizers must walk the whole subtree
- Single-pass regex stripping reassembles the payload
- textContent writes data, not markup
- Template content is a separate document fragment
- Foreign-content breakout moves tags out of SVG
- Duplicate attributes: the first one wins
- textarea content is escapable raw text
- Live collections break removal loops
- URL parsing strips tabs and newlines
- The parser lowercases HTML attribute names
- SVG tag names get case-adjusted
- innerHTML round trip does not re-escape angle brackets
- Root-relative references drop the base path
- Origin is scheme, host and non-default port only
- Scheme-relative references replace the authority
- encodeURI preserves reserved delimiters
- URLSearchParams decodes '+' as a space
- Dot-segment removal keeps empty segments
- Hosts are case-folded, paths are not
- Tabs and newlines are stripped before parsing
- Special schemes always get a path
- Backslashes end the authority for special schemes
- Prefix matching on event.origin
- Exact origin allowlists
- once listeners and repeated messages
- isTrusted on scripted message events
- Assuming message data is a JSON string
- Functions are not structured-cloneable
- Structured clone preserves Date objects
- Cyclic payloads in structured clone
- The ports list of a plain message
- The opaque origin arrives as the string 'null'
- Recursive merge walks into __proto__
- __proto__ on a null-prototype object
- Freezing Object.prototype
- constructor.prototype is a second pollution path
- JSON.parse does not invoke the __proto__ setter
- Polluting Array.prototype breaks for-in
- Dot access vs hasOwnProperty after pollution
- Pollution turns an allowlist into an allow-everything list
- Map lookups ignore the prototype chain
- A null-prototype target absorbs the payload harmlessly
- endsWith allowlists miss the dot boundary
- One decode step keeps percent-encoded slashes
- Path-relative targets cannot change the host
- Collapsing leading forward slashes is not enough
- hostname ignores the port, origin does not
- Leading control characters are stripped before parsing
- searchParams percent-encodes slashes in values
- Userinfo before @ is not the host
- Prefix allowlists leak open redirects
- Directive fallback to default-src
- Nonces neutralise 'unsafe-inline'
- Multiple policies intersect
- form-action has no default-src fallback
- 'self' is an exact origin match
- Wildcard host sources
- Path matching uses whole segments
- 'strict-dynamic' ignores host sources
- Scheme sources match only their own scheme
- upgrade-insecure-requests runs before the check
- Cookie identity is name + domain + path
- Cookie header ordering by path length
- Domain matching is suffix plus dot boundary
- Only the first '=' separates name from value
- __Secure- vs __Host- requirements
- SameSite=Lax only rides safe top-level navigations
- SameSite=None requires Secure
- Max-Age overrides Expires
- What document.cookie exposes
- Simple requests vs preflight
- Counting preflights
- Credentialed requests reject the wildcard
- CORS-safelisted response headers
- Access-Control-Allow-Headers matching
- Origin comparison for CORS
- Checking origin and method together
- Why reflected origins need Vary: Origin
- Preflight result cache
- Prefix matching leaks origins
- frame-ancestors host-source matching
- top, self and parent on an unframed page
- Choosing the directive that controls embedding
- frame-src fallback chain
- Counting frame-ancestors matches
- allow-scripts plus allow-same-origin defeats sandboxing
- ALLOW-FROM is a dead X-Frame-Options value
- frame-ancestors overrides X-Frame-Options
- Sandboxed frames cannot retarget the top window
- frame-ancestors checks every ancestor
- insertAdjacentHTML position semantics
- Live attribute maps break index loops
- Backslashes make a path look protocol-relative
- Cookie path matching is segment-based, not string-prefix-based