,

5 Input Validation Rules Every Developer Should Follow

Posted by

Because one unchecked input can destroy your database, crash your app, or leak your users’ data.

Because one unchecked input can destroy your database, crash your app, or leak your users’ data.

Introduction: The Most Boring Topic That Breaks the Most Apps

Every time a breach happens, developers imagine hackers using complex exploits or zero-days.
In reality, most attacks don’t start that way.
They start with bad input handling.

A missing check.
A poorly validated field.
An assumption that the frontend “already took care of it.”

Input validation isn’t glamorous, but it’s the first wall between your system and chaos.
Get it wrong, and everything from your database to your users’ browsers is at risk.

In this article, we’ll cover five practical, universal input validation rules that every developer should follow regardless of language, framework, or tech stack.


1. Never Trust the Client

The first rule is simple: assume all input is malicious until proven otherwise.

If you rely on client-side validation (HTML5 rules, React forms, or mobile app checks), you’re already vulnerable.
Attackers don’t care about your UI; they send raw HTTP requests using tools like cURL, Postman, or custom scripts.

Example

You might have a frontend form with a numeric “age” field that only allows values between 1 and 120.
But an attacker can bypass that easily:

curl -X POST https://yourapp.com/api/register \
-d '{"name": "test", "age": -999}'

If your backend doesn’t validate age, your database now stores invalid data or worse, causes logic bugs downstream.

The Fix

  • Always validate data on the server, even if you already validate on the client.
  • Treat client validation as a user experience feature, not a security layer.
  • Design APIs that assume hostile clients.

In other words, “Trust, but verify” is still too weak; just verify.


2. Validate Type, Format, and Range

It’s not enough to check if a value exists. You need to ensure it’s the right type, format, and within safe limits.

Most injection and overflow vulnerabilities begin when apps accept arbitrary or oversized data.

Example

// ❌ Bad
const { email, age } = req.body;

// just inserting directly
await db.insert({ email, age });

What if:

  • email = "abc' OR '1'='1" → SQL injection
  • age = "999999999999999999999999" → overflow or crash
  • email = "not-an-email" → broken downstream logic

The Fix

  1. Validate types: Ensure numbers are numbers, strings are strings, etc.
  2. Validate format: Use regex or schema validators for emails, URLs, and phone numbers.
  3. Validate ranges: Apply min/max lengths or numerical limits.
  4. Reject unexpected data: If you expect 5 fields, reject 6.

Example with Zod

import { z } from 'zod';

const userSchema = z.object({
name: z.string().min(1).max(50),
age: z.number().int().min(0).max(120),
email: z.string().email(),
});

const result = userSchema.safeParse(req.body);
if (!result.success) return res.status(400).send('Invalid input');

By combining type and format validation, you not only prevent attacks, you prevent weird bugs caused by invalid assumptions.


3. Whitelist, Don’t Blacklist

Many developers try to secure inputs by filtering out “bad” characters:
 <, >;, ', --, etc.

That’s a losing battle.
Attackers always find new ways to encode or bypass filters.

Instead, use a whitelist approach to explicitly define what’s allowed.

Example

Blacklist approach (unsafe):

if (username.includes('<') || username.includes('>')) throw Error('Invalid');

An attacker can encode those symbols as HTML entities or use Unicode lookalikes.

Whitelist approach (safe):

const valid = /^[a-zA-Z0-9_-]{3,20}$/.test(username);
if (!valid) throw Error('Invalid username');

This approach doesn’t care about every possible “bad” input; it defines the only valid ones.

Key Takeaway

Stop trying to detect evil.
Start defining what “good” looks like.

Whitelist validation drastically reduces your attack surface, especially for form fields like usernames, file names, and identifiers.


4. Sanitize and Escape Where Validation Isn’t Enough

Even well-validated input can still be dangerous when used in different contexts, especially HTML, SQL, and command-line operations.

Validation checks that input is “well-formed.”
Sanitization ensures it’s “safe to use.”

Example: XSS

// user comment
<div>${comment}</div>

Even if you validate that comment is a string, a malicious user can submit:

<script>alert('Hacked')</script>

That’s valid text, but unsafe to render.

Fix

  • Escape or sanitize before displaying:
import DOMPurify from 'dompurify'; const safeComment = DOMPurify.sanitize(comment);
  • Escape before inserting into SQL, shell commands, or file paths.
  • Use parameterized queries, prepared statements, and template-safe renderers (React, Vue).

Sanitization complements validation; they’re not the same.
Validation checks the rules; sanitization enforces safety.


5. Validate Everything Always, Everywhere

If it comes from outside your direct control, validate it.
 That includes:

  • Request body (req.body)
  • Query strings (req.query)
  • Path params (req.params)
  • Headers
  • Cookies
  • File uploads
  • Webhooks and third-party API payloads
  • Even environment variables, in some cases

Example

// GET /users/:id
app.get('/users/:id', (req, res) => {
const id = parseInt(req.params.id, 10);
if (isNaN(id) || id < 1) return res.status(400).send('Invalid ID');
// proceed safely
});

Or, when receiving external webhooks:

// Verify signature + payload schema
if (!verifySignature(req.headers, req.body)) return res.status(401).send('Invalid signature');
if (!schema.safeParse(req.body).success) return res.status(400).send('Invalid payload');

Don’t assume that “internal” APIs or background jobs can’t be abused; all unvalidated data is potential chaos.


Bonus: Make Validation Part of Your Culture

Security often fails because validation feels like busywork.
Make it automatic.

  • Write schemas first. Define data contracts before coding logic.
  • Share reusable validators. Don’t rewrite regexes in every service.
  • Add validation tests. Verify your API rejects bad data.
  • Automate it in CI. Run schema checks on pull requests.

Validation is easiest when it’s part of your engineering culture, not an afterthought.


Conclusion: One Missed Check Is All It Takes

Most breaches don’t require advanced exploits.
They start with missing or broken validation, a route that accepted more than it should, a field that allowed unexpected characters, a backend that assumed the frontend would “handle it.”

You don’t have to memorize hundreds of attacks to protect your app.
Follow these five rules consistently, and you’ve already eliminated 90% of input-related risks:

  1. Never trust the client.
  2. Validate type, format, and range.
  3. Whitelist instead of blacklist.
  4. Sanitize and escape properly.
  5. Validate every single input source.

That’s not paranoia, that’s professionalism.


Call to Action

When’s the last time you reviewed your API’s input validation?
Pick one route, any route, and inspect what assumptions it makes.

If this article helped clarify how simple validation can prevent serious damage, bookmark it and share it with your team.
Because the most powerful security fix isn’t a firewall, it’s a well-placed if.

Leave a Reply

Your email address will not be published. Required fields are marked *