← Back to appsec.fyi

Input Validation vs Output Encoding

Two different defenses that people constantly mix up. One checks format. The other prevents injection.

Input ValidationOutput Encoding
PurposeEnsure data matches expected formatMake data safe for a specific output context
When it runsOn input — before processingOn output — before rendering
ExampleReject if email doesn't match patternConvert < to &lt; before HTML
PreventsMalformed data, some injectionXSS, injection in the output context
Context-aware?No — validates against a generic ruleYes — different encoding for HTML, JS, URL, CSS
Sufficient alone for XSS?NoYes (when applied correctly in every context)
Can be bypassed?Often — via encoding tricks, edge casesRarely — if the right encoding is used

The mistake everyone makes

Teams implement input validation (reject anything with <script>) and think they're protected against XSS. They're not. Input validation is a denylist approach — you're trying to predict every possible attack string. Attackers have infinite creativity and encoding tricks.

Output encoding is an allowlist approach — you're saying "in this HTML context, these characters have special meaning, so escape them." It doesn't matter what the attacker sends because the encoding neutralizes it at render time.

Both have a role

Input validation is still valuable — reject obviously malformed data early, enforce length limits, check types. It reduces your attack surface and catches accidental garbage. But it's defense in depth, not your primary XSS defense.

Output encoding is the actual fix. And it has to be context-aware: HTML entities for HTML body, JavaScript escaping for inline JS, URL encoding for URL parameters, CSS escaping for style contexts. Using HTML encoding inside a JavaScript string doesn't help.

The framework advantage

Modern frameworks (React, Angular, Vue, Django templates, Rails ERB) auto-encode output by default. The danger is when you bypass it — React's dangerouslySetInnerHTML, Django's |safe filter, Rails' raw(). Every time you reach for one of those, you're opting out of your primary XSS defense.

More comparisons: SSRF vs CSRF XSS vs CSRF AuthN vs AuthZ IDOR vs BOLA XSS Types SQLi vs NoSQLi SAST vs DAST Bug Bounty vs Pentest SBOM vs SLSA Validation vs Encoding