Skip to content
Paul Marinos
Menu

Common Insecure Coding Pitfalls

The recurring vulnerability families in real code — injection, deserialization, SSRF into cloud metadata, broken object-level authorization, TOCTOU, and leaked secrets — organized by the failure mode underneath them.

The OWASP Top 10 is a useful map and a poor teacher, because a category name doesn’t build the pattern-recognition that catches the bug in a diff. This is the same ground from the implementation side — the specific shapes these flaws take in real code, and why each one recurs. The secure-coding paradigms are the fixes; this is what they’re fixing.

Three failure modes underneath the families

Section titled “Three failure modes underneath the families”

The families read as a long list, but most reduce to three underlying mistakes — and learning the mistake, not the category name, is what transfers to code you have not seen before:

  • Untrusted data crosses into an interpreter. The data is treated as instructions instead of values. The interpreter varies — a SQL engine, a shell, a template, an object deserializer, an outbound HTTP client — but the tell is the same: user-influenced data reaching something that acts on it. This is injection, deserialization, and SSRF.
  • A required check is absent. The code does what it says; what is missing is the guard. Nothing looks wrong on the line, because the bug is the line that is not there. This is broken authorization and race conditions — one missing an ownership check, the other missing atomicity.
  • You trusted your own supply. The risk is in what you shipped, not in the request: a secret committed to the repo, or a dependency you executed without reading.

Each family has its own page — the code shapes it takes, why it recurs, and the fix — grouped by the mode above.

Family Failure mode The tell
Injection Untrusted → interpreter Untrusted data concatenated into a query, command or template
Deserialization Untrusted → interpreter A format that instantiates objects, fed from a trust boundary
SSRF Untrusted → interpreter The server fetches a URL the user influenced
Broken authorization Absent check An object returned by id with no owner check
Race conditions & TOCTOU Absent check A check and an action on shared state, with a gap between
Secrets in source control Trusted supply A key in the code, or in the git history
Dependency confusion & supply chain Trusted supply Code you run but did not write or read

Two recurring traps cut across the families and belong here rather than in any one page:

  • “Sanitize on input” is the wrong mental model. Second-order injection stores data safely and uses it unsafely later; the dangerous line contains no user input at all. The fix is to handle data safely at the sink, which is why taint analysis tracks flow across the whole program rather than checking the entry point.
  • The worst bugs are absences, and tools are bad at absences. A missing authorization check and a non-atomic update both read as correct code executed once. That is precisely why scanners miss them and manual review and authorization testing find them.

These are the exploited findings in pentesting, read from the defender’s side. The paradigms prevent them by construction, and scanning is how you find the instances already written. SSRF and secrets reach into cloud; authorization reaches into IAM; and every one of them reappears in AI systems as the same failure in new clothing.

Graph View

Spotted an error on this page? Report it.