The fix depends on where the string lands.

The same piece of user input needs a different defense depending on where it ends up. Pick a destination context — from a page body to a log line — and see why, character by character.

Untrusted input

What a user (or attacker) might type into this field.
0 characters
0 flagged

Where it goes

Same input, handled unsafely vs. handled correctly.
⚠ If concatenated directly
✓ Defended

Scan a snippet for risky patterns.

Paste a code snippet and get a heuristic pass over common anti-patterns — the kind a security-minded reviewer flags in a pull request. This only pattern-matches text; nothing you paste is executed.

Paste code

Any language — rules cover common risky calls across JS, Node, Python, PHP, and Java.
0 findings

Build a starting Content-Security-Policy.

Pick the sources this page actually needs. Everything not listed stays closed — loosen only what you must.

Sources

Toggle what this page legitimately needs.

Generated header

Content-Security-Policy

Test what actually sticks.

Eight scenario questions pulled from the contexts and fixes above. Guess before you check the explanation.

Common injection classes, and the actual fix.

Not payload lists — the defensive principle that closes each class of bug, so you recognize the fix pattern anywhere you meet it.

Framework defaults — what's safe out of the box

Most modern frameworks auto-escape by default. The risk is usually the explicit escape hatch, reached for out of habit rather than a reviewed decision.