Secure Coding Best Practices

Chapter 1 · Practice 1 of 4

Know every place untrusted data enters your code

From Treat all input as untrusted

Why it matters

You cannot validate input you did not notice. Most teams think of form fields and JSON bodies, but attackers control far more than that. Treat all of these as untrusted:

SourceEasy to forget because
Query strings, path segments, request bodiesobvious, but often only checked in the browser
Headers: Host, X-Forwarded-For, Referer, User-Agentthey look like infrastructure, not user data
Cookiesthe client can set any value it likes
Uploaded files and their namesthe name, the type and the bytes are all chosen by the sender
Webhooks and partner APIsthey come from "trusted" companies, over the internet
Rows written earlier by usersstored data becomes input again when you read it
Message queues and cachesother services may have been fed by users
Output from a language modelit can be steered by any text the model read

A trust boundary is any line where data moves from something you do not control into something you do. Draw them for each service: the HTTP edge, the queue consumer, the cron job that reads an S3 bucket. Every boundary needs validation on the inside, and every interpreter after it (SQL, shell, HTML, file system) needs its own safe API.

Do

  • List the trust boundaries of each service in its README or threat model
  • Treat headers, cookies and stored user content as input
  • Validate webhook payloads after verifying their signature

Avoid

  • Trusting a value because an internal service sent it
  • Relying on browser validation or disabled form fields
  • Using X-Forwarded-For from clients you do not proxy