July 23, 2026
Input Validation: Because Users Are Creative, and Attackers Are More Creative
There is a special kind of optimism that exists in software development.

By Robert Broeckelmann
4 min read
It's the belief that users will read instructions.
Closely related is the belief that users will enter valid data.
Closely related to that is the belief that attackers will politely respect your API documentation.
None of these beliefs survive first contact with production.
If you've ever written an application, you've probably encountered some variation of:
{
"age": "banana"
}{
"age": "banana"
}or
{
"email": "DROP TABLE users"
}{
"email": "DROP TABLE users"
}or perhaps the timeless classic:
{
"firstName": "<script>alert('hello')</script>"
}{
"firstName": "<script>alert('hello')</script>"
}At some point, every application discovers a fundamental truth that input validation is not a feature. It is a survival mechanism.
The Good News
Modern architectures provide a surprising number of places where input validation can occur.
The bad news?
Most organizations assume the first one they find is sufficient.
It usually isn't.
Input validation works best as a layered defense, where multiple components verify different aspects of incoming data.
Think les_s, "Where should validation happen?"_ and more, "How many opportunities do I have to reject nonsense before it causes trouble?"
The API Gateway: The Front Door
The first line of defense is often the API Gateway.
API Gateway products support varying levels of request validation, including:
- Kong
- Apigee
- Azure API Management
- AWS API Gateway
- NGINX
- Gravitee
And, this is where OpenAPI becomes incredibly useful.
Consider a simple API definition:
type: object
required:
- email
- age
properties:
email:
type: string
format: email
age:
type: integer
minimum: 0
maximum: 120type: object
required:
- email
- age
properties:
email:
type: string
format: email
age:
type: integer
minimum: 0
maximum: 120A gateway can immediately reject:
{
"email": "not-an-email",
"age": "potato"
}{
"email": "not-an-email",
"age": "potato"
}before your application ever sees it.
This is fantastic.
Use it.
Enable it.
Turn it on.
Then, immediately realize it isn't enough.
OpenAPI Is Not a Security Policy
One of the most common misconceptions is:
"We validate against our OpenAPI specification, therefore we're secure."
Unfortunately, OpenAPI primarily answers:
"Does this request look like the request I expected?"
It does not answer:
"Is this request safe?"
For example:
{
"firstName": "<script>alert('owned')</script>"
}{
"firstName": "<script>alert('owned')</script>"
}might be perfectly valid according to your OpenAPI schema.
The gateway sees:
String?
Yes.
Required field?
Yes.
Maximum length?
Yes.
Approved.String?
Yes.
Required field?
Yes.
Maximum length?
Yes.
Approved.Meanwhile, your frontend is about to have a very exciting day.
Business Rules Live Elsewhere
Many validation requirements are business-specific.
For example:
{
"country": "US",
"state": ""
}{
"country": "US",
"state": ""
}Your OpenAPI document may happily accept it.
Your business rules may not.
Similarly:
{
"transferAmount": 1000000000
}{
"transferAmount": 1000000000
}might satisfy every schema requirement while simultaneously giving your compliance department a heart attack.
Business validation belongs in the application.
No gateway can know your business logic.
The Application Is Still Responsible
This is the part many developers dislike.
Even if the gateway validates requests, the application must still validate them.
Always.
Every time.
No exceptions.
Why?
Because eventually:
- A new endpoint bypasses the gateway
- An internal service calls another service directly
- A batch import arrives
- A message queue receives data
- A developer accidentally disables validation
Applications should assume all incoming data is hostile until proven otherwise.
Not because users are hostile.
Because reality is hostile.
Enter the Web Application Firewall
The next layer is the Web Application Firewall.
Or ,WAF.
The WAF occupies a fascinating position in security architecture.
It is simultaneously:
- Extremely useful
- Frequently misunderstood
- Occasionally treated like magic
A WAF cannot fix bad application design.
It cannot magically eliminate vulnerabilities.
It cannot turn a SQL injection vulnerability into secure code.
What it can do is detect and block a remarkable amount of obviously malicious traffic.
The Internet Is Full of Robots
The moment an application becomes publicly accessible, it starts receiving traffic from:
- Vulnerability scanners
- Search engines
- Botnets
- Security researchers
- Penetration testers
- Curious teenagers
- Less curious criminals
Many requests will look something like:
GET /index.php?id=1' OR 1=1--GET /index.php?id=1' OR 1=1--or
GET /?search=<script>alert(1)</script>GET /?search=<script>alert(1)</script>A properly configured WAF can often stop these before they ever reach your application.
This reduces noise.
Reduces risk.
And occasionally saves developers from having a very unpleasant afternoon.
WAFs Are Pattern Recognition Engines
Modern WAFs examine requests for indicators such as:
- SQL injection
- Cross-site scripting
- Command injection
- Protocol violations
- Malformed requests
- Known attack signatures
Cloud providers offer managed solutions:
- AWS WAF
- Azure WAF
- Cloudflare WAF
- Akamai WAF
Most organizations should seriously consider using one.
Not because it replaces secure coding.
Because it complements secure coding.
The Best Input Validation Strategy
The strongest architectures validate data repeatedly.
Something like:
Each layer checks different things.
WAF
Looks for attacks.
API Gateway
Validates structure.
Application
Validates business rules. Business rules in this context means message schemas, regular expressions that strings are supposed to support, or richer, application-specific rules of input data.
Database
Enforces constraints.
Together, these form a far stronger defense than any individual layer.
Don't Forget Output Validation
Input validation is only half the problem.
Applications also need output encoding and output validation.
Otherwise:
{
"comment": "<script>alert('oops')</script>"
}{
"comment": "<script>alert('oops')</script>"
}may pass validation perfectly and then execute in a browser later.
The industry has spent decades learning that safe storage does not imply safe display.
Input validation and output encoding are partners.
You need both.
I couldn't even tell you how many shops I've been in where I have someone who adamantly rejects the concept of output validation. You've heard my position.
The Goal
The purpose of input validation isn't to make data look nice.
It isn't to satisfy a compliance checklist.
It isn't to make auditors happy.
The goal is much simpler.
Every component in your system should be able to confidently say, "I know what valid input looks like, and I refuse everything else."
API Gateways help. OpenAPI helps. WAFs help. Application validation helps. Database constraints help.
None of them are the whole story.
Together, however, they create something surprisingly rare in software engineering:
A system that behaves exactly the way you expected when confronted with users who behave absolutely nothing like you expected.
Notes
- AI / GenAI / ChatGPT / etc were not used to generate the text of this article.
- ChatGPT was used to generate the images.
- I used em dashes in my writing before the current GenAI wave was a thing. Not planning on changing now.
- Names have been changed to protect the guilty.
- None of the hostnames or users used in examples actually exist.
- Feel free to post any comments or suggestions below.