API & Automation·7 min read·

Input Validation and Payload Size Limits

Apply layered input validation and payload limits to stop malformed data, injection, and oversized request attacks against your API endpoints.

NB

Netbay Engineering

Netbay Engineering

On this page

The less your API trusts about incoming requests, the safer and more predictable it is. Two cheap, high-return controls belong at the very front of every endpoint: strict input validation and hard payload size limits. Together they form a layered defense that rejects bad data before it reaches your business logic.

Why validate at multiple layers

Validation is not one thing. It is a stack: the web server caps the body, the framework enforces schema, and your domain code asserts invariants. Relying on any single layer invites a bypass when a team forgets a field or a framework version changes behavior. Staging the same checks at several layers is the practical definition of defense in depth.

  • **Transport layer** enforces byte limits and content-type so oversized or malformed requests never reach an application.
  • **Schema layer** (JSON schema, DTOs) rejects unknown fields, wrong types, and missing required ones.
  • **Domain layer** validates *semantics* — ranges, business rules, and cross-field consistency that a generic schema cannot know.
raw request transport size + content-type schema types + required domain ranges + invariants reject 400/413 early clean request reaches logic

Payload size limits

Oversized uploads are a denial-of-service primitive: an attacker streams gigabytes at a parser that buffers it all into memory. Set a realistic cap and enforce it *before* the body is fully read. Even a JSON body parser that trusts 'Content-Length' can be fooled by chunked encoding, so enforce the limit while reading, not from the header alone.

Choose limits per endpoint. A small JSON create should cap at a few hundred KB; a file upload may allow tens of MB — but never unbounded. Reject over-limit requests with '413 Payload Too Large'.

Two subtleties keep limits honest. First, enforce on bytes actually read, not the declared Content-Length, because chunked transfer-encoding lets a client send far more than the header claims and a naive server that trusts the header will keep buffering past its budget. Second, pick limits with an eye toward the decoded size, not just the wire size: a highly nested or heavily escaped payload can expand several-fold once parsed, so a generous raw cap can still produce an enormous in-memory object. Set a nesting depth and an iteration ceiling alongside the byte cap, or a small compressed blob wrapped in valid JSON will do the damage a large request could.

Validating a JSON body with schema and limits

javascript
const AJV = require("ajv");
const ajv = new AJV();

const orderSchema = {
  type: "object",
  required: ["items", "email"],
  additionalProperties: false,
  properties: {
    items: { type: "array", maxItems: 100 },
    email: { type: "string", format: "email", maxLength: 200 },
    note: { type: "string", maxLength: 1000 },
  },
};

function parseOrder(rawBody) {
  if (Buffer.byteLength(rawBody) > 64 * 1024) {
    throw new Error("payload too large");
  }
  const body = JSON.parse(rawBody);
  if (!ajv.validate(orderSchema, body)) {
    throw new Error("schema validation failed: " + ajv.errorsText());
  }
  return body;
}

Enforcing a body cap at the reverse proxy layer

nginx
server {
    location /api/ {
        client_max_body_size 256k;
        limit_except GET { deny all; }
        proxy_pass http://127.0.0.1:8080;
    }
}

Validation failures deserve the same discipline as successful requests. Keep the error message generic but the *logging* rich — record which field failed and why, without echoing the submitted value, so you can spot attackers probing your schema without handing them a roadmap. And remember that validation is cheapest at the boundary: the earlier a malformed request is rejected, the less work your parsers, watchers, and database connections do. That is why the transport-limit check at the proxy is not optional decoration but the first and cheapest line of an input-defense stack.

A few validation rules to internalize

  1. Reject unknown fields ('additionalProperties: false') to keep payloads forward-compatible and reserved-key attacks out.
  2. Always cap string lengths and array sizes, not just types.
  3. Use semantic formats (email, date, int range) and check the *range*, not just that a number exists.
  4. Return generic, non-verbose errors so validation failures do not leak schema internals useful to an attacker.

Takeaway

Layered validation — transport, schema, domain — plus hard size caps turns a flood of bad input into a small set of early 4xx responses. It is cheap, deterministic, and dramatically shrinks your attack surface. Put these guards in front of a production API on a Netbay VPS at netbayhosts.in and sleep easier.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance