Table of Contents
2. Input Validation & Data Shape — The First Security Boundary
This page builds directly on the previous idea that security begins with predictable shape.
Security begins at the boundary.
Before escaping, before hashing, before permissions, before anything else
— the system must decide what it will accept and what it will reject.
Modern PHP makes this easier,
but only if we treat input shape as a first‑class concept.
A secure system does not accept “almost valid” data.
It accepts only what it understands.
This page introduces the mindset of shaping, validating,
and rejecting input with clarity.
1. Validation Is Not About Checking — It’s About Shaping
Validation is not a series of checks.
It is the act of shaping untrusted data
into a predictable form.
A secure system:
- defines the shape it expects
- rejects anything outside that shape
- never guesses
- never coerces
- never fills in missing meaning
If the input doesn’t match the shape,
the system says no.
2. Reject Unknown Fields
One of the most overlooked security principles is
Unknown fields are not harmless
— they are untrusted.
A secure boundary
- accepts only known fields,
- rejects everything else,
- never silently ignores extra data.
Silent acceptance is how vulnerabilities slip in.
3. Validate at the Boundary, Not Deep Inside
Validation belongs at the edge of the system:
- HTTP request → validate
- CLI input → validate
- API payload → validate
- file upload → validate
Once data crosses the boundary,
it should already be
- typed
- shaped
- predictable
- safe
Internal code should never wonder whether
the input is valid.
4. Prefer DTOs Over Arrays
Arrays are flexible.
Flexibility is the opposite of security.
DTOs give you:
- stable shape
- typed properties
- predictable structure
- no dynamic keys
- no silent coercion
A DTO is a contract.
An array is a suggestion.
5. Avoid Implicit Coercion
PHP will happily coerce
- strings to numbers,
- numbers to strings,
- empty strings to false,
- null to empty arrays,
- arrays to booleans.
This is convenient
— and dangerous.
Safe defaults:
- cast explicitly
- convert intentionally
- reject ambiguous values
- avoid “truthy” logic
- avoid loose comparisons
Predictability
is security.
6. Validate Types, Not Just Values
A value can be “valid”
but still unsafe.
Examples:
"123" is not an integer
"true" is not a boolean
"[]" is not an array
"null" is not null
"5" is not a float
Safe validation → checks for
- type
- shape
- structure
- domain
- intent
Security is not about correctness
— it's about clarity.
7. Validate Structure Before Content
Before checking meaning,
check shape.
Example for a user registration payload:
- Is it an object?
- Does it contain exactly the expected fields?
- Are the fields the correct types?
Only then: check length, format, domain rules.
Structure first.
Meaning second.
8. Fail Fast, Fail Loudly
A secure system:
- rejects early
- rejects clearly
- rejects loudly
So, do not:
- sanitize silently
- guess intent
- auto‑correct
- fill in missing fields
- “fix” malformed data
A system that fails loudly
is harder to exploit.
9. Validation Is a Security Boundary, Not a UX Feature
User‑friendly error messages belong in the UI.
Strict validation belongs in the backend.
Security validation should be
- strict
- unforgiving
- predictable
- consistent
Friendly messages can wrap strict rules
— not replace them.
Summary
Input validation
is the first and most important security boundary.
A secure system
- shapes data,
- rejects unknown fields,
- validates at the boundary,
- uses DTOs for stable structure,
- avoids implicit coercion,
- validates types and shape,
- checks structure before meaning,
- fails fast and loudly
Security begins with predictable input.
Everything else builds on that foundation.
This page describes secure defaults and common practices in modern PHP. It is not a complete security guide, and it does not replace formal audits or framework‑specific documentation. These principles are consistent enough to be useful, but security always requires context, judgment, and ongoing review.
