← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · ✎ updated 7d
← Back to glossary

Input Validation vs Output Encoding

General PHP 5.0+ Beginner
debt(d7/e5/b7/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The detection_hints specify phpstan, psalm, and semgrep with automated=no. These specialist tools can flag unvalidated input in some patterns, but the code_pattern note shows it requires recognising absence of validation — something these tools cannot reliably catch automatically, pushing it toward d7 rather than d5. Missing validation is typically found via manual code review or when attacks succeed in production.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix describes validating type, format, length, and range at entry points across web, api, and cli contexts. Retrofitting server-side validation across all entry points — user input, API payloads, file uploads, query strings — touches multiple controllers, request handlers, and possibly a shared validation layer. This is more than a single-line fix but less than a full architectural rework.

b7 Burden Structural debt — long-term weight of choosing wrong

Closest to 'strong gravitational pull' (b7). The applies_to covers web, api, and cli contexts from PHP 5.0 onward, meaning every external data entry point in the system must account for this choice. The common_mistakes include second-order attacks (stored data reused without re-validation), meaning validation decisions at ingestion shape how data is trusted throughout the entire codebase. Every new feature accepting external input must be written with this discipline in mind.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap (contradicts how a similar concept works elsewhere)' (t7). The misconception field directly states the canonical wrong belief: 'Client-side validation is sufficient if it covers all cases.' This is a well-documented but persistently harmful mistake — developers coming from frontend contexts naturally conflate UX validation with security validation. The common_mistakes reinforce this: trusting client-side JavaScript, validating format but not range, and blocklisting instead of allowlisting are all intuitive-seeming but wrong approaches that a competent developer can easily fall into.

About DEBT scoring →

Also Known As

Input Validation and Output Encoding Validation vs Encoding Input Sanitization vs Output Escaping

TL;DR

Validation checks that input is acceptable; output encoding makes data safe for the context it's rendered in. Both are required.

Explanation

Input validation and output encoding are complementary — not alternatives. Validation (reject unexpected characters, enforce length and format) reduces the attack surface and catches mistakes early. Output encoding (htmlspecialchars for HTML, parameterised queries for SQL, json_encode for JS) makes data structurally safe for its destination context. Relying on validation alone fails because valid-looking data can still be malicious in a different context. Encode for the output context regardless of how the input was validated.

Common Misconception

✗ Client-side validation is sufficient if it covers all cases. Client-side validation is UX — it can be bypassed by disabling JavaScript or crafting raw HTTP requests. Server-side validation is the security control; client-side is purely for user experience.

Why It Matters

Unvalidated input is the root cause of injection attacks, unexpected behaviour, and data corruption. Validating on the server side — not just the client — ensures your application only processes data it was designed to handle.

Common Mistakes

  • Relying on client-side (JavaScript) validation alone — it is trivially bypassed with browser dev tools.
  • Validating format but not range — accepting a birth year of 9999 is a validation failure.
  • Blocklisting known bad input instead of allowlisting known good — attackers always find new bypass strings.
  • Validating on the way in but re-using stored data later without re-validation (second-order attacks).

Avoid When

  • Validating only on the client side — client-side validation is for UX; server-side validation is for security.
  • Using validation as a substitute for parameterised queries — validate AND use prepared statements.
  • Allowlist validation that is too permissive — a regex that allows < and > defeats XSS protection.
  • Validating after business logic has already acted on the input — validate at the entry point, before any processing.

When To Use

  • Every piece of data entering the system from an external source — user input, API payloads, file uploads, query strings.
  • Allowlist validation (accept only known-good patterns) rather than blocklist (reject known-bad).
  • Before passing data to any downstream system — database, shell command, template engine, serialiser.
  • Structured data like emails, URLs, dates — use format-specific validators, not generic string checks.

Code Examples

✗ Vulnerable
// Sanitising instead of validating — trying to fix bad input rather than reject it
$email = strip_tags($_POST['email']);
$age   = (int) $_POST['age']; // -1 passes silently
✓ Fixed
// Validate — reject anything that doesn't match expectations
$email = filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL)
    ?: throw new \InvalidArgumentException('Invalid email');

$age = filter_var($_POST['age'] ?? '', FILTER_VALIDATE_INT,
    ['options' => ['min_range' => 0, 'max_range' => 150]])
    ?: throw new \InvalidArgumentException('Invalid age');

// In Laravel — Form Request
class StoreUserRequest extends FormRequest {
    public function rules(): array {
        return [
            'email' => ['required', 'email:rfc,dns', 'max:255', 'unique:users'],
            'age'   => ['required', 'integer', 'between:0,150'],
            'role'  => ['required', Rule::in(['user', 'editor'])],
        ];
    }
}

Added 13 Mar 2026
Edited 21 Aug 2026
Views 220
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 1 ping M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 1 ping S 1 ping M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 1 ping T 2 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M
No pings yet today
No pings yesterday
Scrapy 63 Perplexity 15 Amazonbot 15 PetalBot 13 Ahrefs 10 SEMrush 10 Google 8 Bing 8 ChatGPT 6 Claude 4 Unknown AI 3 Twitter/X 2 Applebot 2 Majestic 1 Qwen 1 Common Crawl 1 Brave Search 1 Baidu 1
crawler 160 crawler_json 3 pre-tracking 1
🧱 FUNDAMENTALS — new to this? Start with the ground floor.
Input general Input is any data that comes into your program from the outside world—typed text, clicked buttons, uploaded files, or information sent from other systems.

Understanding input is essential because most bugs and security vulnerabilities come from unexpected input. Every skill level requires thinking carefully about what data is coming in and whether it's safe to use.

💡 Treat every piece of input as potentially wrong, empty, or malicious until your code has explicitly checked it.

Ask Codex about Input →
Validation general Validation is checking that data meets specific rules before your program uses it—like confirming an email has an @ symbol or a number falls within an expected range.

Every application accepts user input, and users make mistakes—or try to exploit your system. Validation is your first defense against corrupted data and security vulnerabilities at any scale.

💡 Always validate on the server, even if you already validated in the browser.

Ask Codex about Validation →
⚡ DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Low
⚡ Quick Fix
Validate type, format, length, and range at the entry point; use allowlists not blocklists; reject invalid input early with a 400 response
📦 Applies To
PHP 5.0+ web api cli
🔗 Prerequisites
🔍 Detection Hints
User input used in business logic without type cast, filter_var, or validation before use
Auto-detectable: ✗ No phpstan psalm semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Medium ✗ Manual fix Fix: Medium Context: Function Tests: Update
CWE-20 CWE-807


✓ schema.org compliant