Allowlist validation defines exactly what is acceptable and rejects everything else. Denylist validation tries to block known bad input. Allowlists are the safer choice.
Allowlist example rules:
- This field is a UUID.
- This field is an integer from 1 to 100.
- This field is either
ascordesc.
A denylist blocks patterns such as <script or DROP TABLE. It always misses other encodings and variations of the same attack.
How an API should validate input:
- Validate every request at the trust boundary (where outside data enters your server).
- Use a schema library like Zod, Joi, AJV or class-validator.
- Check types, lengths, ranges, formats and enums.
- Reject unknown properties.
- Limit the request body size.
- Validate on the server, even when the client also validates.
- Check both syntax ("it's a date") and meaning ("the start date is before the end date").
Validation makes the attack surface smaller. But it doesn't replace parameterised queries or output encoding.
- An allowlist defines what is valid and rejects everything else.
- Denylists miss variations and other encodings of bad input.
- Validate with a schema at the trust boundary and reject unknown keys.
- Validate on the server, check both syntax and meaning, and limit body size.
- Validation does not replace parameterised queries or output encoding.
Read more