API security · input validation · JSON Schema · REST API · defensive coding · OWASP
Input Validation for Small Public APIs: A Technically Conservative Guide
A practical, opinionated guide to input validation for indie developers and small teams building public APIs. Learn when to use JSON Schema, how to reject early, and what pitfalls to avoid.
Published:
Why Input Validation Matters for Small APIs
If you are running a public API with a small team, input validation is not optional. It is the first line of defense against injection attacks, data corruption, and service abuse. The OWASP Top 10 consistently ranks broken access control and injection vulnerabilities among the most critical risks, and both stem from inadequate input validation at the API boundary.
This guide takes a technically conservative stance. We will not recommend complex validation frameworks or enterprise tooling. Instead, we will focus on practical, maintainable approaches that small teams can implement without sacrificing security.
Validate at the Boundary, Reject Early
The most important principle in input validation is simple: validate every input at the API boundary before it reaches your application logic. Do not trust client-side validation. Do not assume that because a request comes from your own frontend, it is safe.
OWASP recommends that all validation failures should result in input rejection. This means returning a clear error response and stopping processing immediately. The earlier you reject invalid input, the less attack surface you expose.
Consider a simple user registration endpoint. If the email field is required and must be a valid email address, validate this before querying your database. If validation fails, return a 400 Bad Request with a descriptive error message. Do not proceed to password hashing or user creation.
JSON Schema: When to Use It
JSON Schema is a practical tool for defining and validating the structure of JSON data. It acts as a contract between API producers and consumers, specifying which fields must be present, what data types they must contain, and what constraints apply to their values.
For straightforward APIs, JSON Schema is quite useful. It provides a single source of truth for what your messages look like that you can share with frontend developers, backend teams, and external customers. Postman’s documentation highlights that JSON Schema can catch errors early, enforce consistency across services, and clearly document data contracts.
However, JSON Schema has limitations. Expressing non-trivial constraints can be verbose and hard to extend. Conditional logic such as “if field X is set to 123 then fields Y and Z are mandatory” becomes cumbersome. For complex validation rules, manual checks may be more appropriate.
The Hacker News discussion on JSON Schema practicality reveals that many developers use it for straightforward APIs but switch to custom validation for complex business logic. One developer noted that they ended up switching from JSON Schema to Marshmallow schemas because they needed more control and less shoehorning.
Manual Validation: When Schema Falls Short
Not all validation can be expressed in JSON Schema. Some constraints require business logic that goes beyond type checking. For these cases, manual validation is necessary.
OWASP recommends using a centralized input validation library or framework for the whole application. If the standard validation routine cannot address some inputs, use extra discrete checks. Always validate for expected data types using an allowlist rather than a denylist.
For example, if you need to validate that a phone number is only accepted in search endpoints but not in POST or PATCH operations, JSON Schema cannot express this constraint. You would need manual validation in your route handlers.
Similarly, if field Y is valid only in searches and field Z is valid only in PUT/PATCH but not POST, you need custom logic. This is where manual validation shines.
Avoiding Common Pitfalls
Regex Denial of Service
Regular expressions can be powerful but also dangerous. Complex regex patterns can lead to regex denial of service (ReDoS) attacks, where a specially crafted input causes the regex engine to take exponential time. For small APIs, keep regex patterns simple and test them against malicious inputs.
Implicit Type Coercion
Many programming languages perform implicit type coercion, which can lead to unexpected behavior. A string “123” might be automatically converted to an integer, or “true” might become a boolean. This can bypass validation checks and introduce security vulnerabilities.
Always validate types explicitly. Do not rely on implicit coercion. If a field should be an integer, ensure it is an integer before proceeding.
Character Set Validation
OWASP recommends specifying character sets such as UTF-8 for all input sources. If the system supports UTF-8 extended character sets, validate after UTF-8 decoding is completed. Verify that protocol header values in both requests and responses contain only ASCII characters.
File Upload Validation
If your API accepts file uploads, do not pass user-supplied data directly to any dynamic include function. Limit the type of files that can be uploaded to only those types needed for business purposes. Validate uploaded files by checking file headers rather than file extensions, as extensions can be easily spoofed.
Practical Implementation Steps
-
Identify all data sources and classify them into trusted and untrusted. Client-provided data is untrusted until proven otherwise.
-
Validate all input data from untrusted sources. This includes query parameters, path parameters, headers, and request bodies.
-
Encode input to a common character set before validating. This prevents encoding-based attacks.
-
Use allowlists, not denylists. Specify what is allowed rather than what is forbidden. Denylists can be bypassed with unexpected inputs.
-
Validate data range and length. Check that numeric values are within expected ranges and that strings do not exceed maximum lengths.
-
Log validation failures. This helps you detect attack attempts and tune your validation rules.
-
Test your validators. Ensure that your validation logic correctly rejects malicious inputs and accepts valid ones.
FAQ
Q: Should I validate on the client side too?
Client-side validation is important for user experience, providing immediate feedback. However, it should never be your only validation layer. Always validate on the server side as well. Client-side validation can be bypassed easily.
Q: How do I handle nested objects in JSON Schema?
JSON Schema supports nested objects by defining schemas inside the properties field. You can create deeply nested validation rules by referencing other schemas or defining them inline.
Q: What about validation errors in responses?
Validation errors should be clear and actionable. Include the field name, the expected type or format, and a brief description of what went wrong. Avoid exposing internal implementation details.
Q: Can I use JSON Schema for both requests and responses?
Yes. JSON Schema can validate both incoming requests and outgoing responses. This ensures consistency throughout your API and helps catch bugs early.
Q: How do I handle conditional validation?
For conditional validation that JSON Schema cannot express, use manual validation in your route handlers. Combine schema validation for structural checks with custom logic for business rules.
Sources
- OWASP Input Validation Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html
- OWASP Validate All Inputs Developer Guide: https://devguide.owasp.org/en/04-design/02-web-app-checklist/05-validate-inputs
- OWASP REST Security Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html
- Postman JSON Schema Guide: https://blog.postman.com/json-schema-data-types
- Hacker News JSON Schema Discussion: https://news.ycombinator.com/item?id=16406855
- PactFlow Contract Testing with JSON Schemas: https://pactflow.io/blog/contract-testing-using-json-schemas-and-open-api-part-1
- APIs You Won’t Hate JSON Schema Article: https://medium.com/apis-you-wont-hate/the-many-amazing-uses-of-json-schema-client-side-validation-c78a11fbde45
