Part 1 · 3 chapters · ~18 min

Application Security II: Injection, SSRF, Deserialisation, Secrets

SQL, NoSQL, command and template injection with parameterisation, SSRF and egress controls, unsafe deserialisation (pickle, Java serialization, YAML), prototype pollution in Node, secrets in code and how to find and rotate them, and dependency risk.

3

Input is data, never code

code
-- SQL injection: build queries with parameters, never string concatenation
db.query(`SELECT * FROM users WHERE email = '${email}'`)          -- vulnerable
db.query('SELECT * FROM users WHERE email = $1', [email])          -- safe: the driver sends data separately
-- dynamic ORDER BY: allow-list column names; identifiers cannot be parameters
const col = { created: 'created_at', amount: 'amount_kobo' }[req.query.sort] ?? 'created_at';

// NoSQL injection: { "email": { "$ne": null } } matches everyone → validate types with a schema (zod)
// command injection: execFile('convert', [inPath, outPath]), never exec(`convert ${name}`)
// prototype pollution: JSON with "__proto__" merged into objects → use Object.create(null) maps, schema validation

# unsafe deserialisation: never unpickle or Java-deserialise untrusted bytes; yaml.safe_load, not yaml.load
pickle.loads(request.data)     # remote code execution by design
4

SSRF

code
import { lookup } from 'node:dns/promises'; import ipaddr from 'ipaddr.js';
async function safeTarget(url: string) {
  const u = new URL(url);
  if (u.protocol !== 'https:' || (u.port && u.port !== '443')) throw new Error('scheme/port not allowed');
  const { address } = await lookup(u.hostname);
  if (ipaddr.parse(address).range() !== 'unicast') throw new Error('private address');   // loopback, private, linkLocal…
  return { url: u, address };   // connect to this address (pin it) so DNS cannot change between check and use
}
SERVER-SIDE REQUEST FORGERY
your server fetches a URL the attacker chose
attackerwebhook url = http://169.254.169.254/...your APIfetches the URLcloud metadata servicereturns credentialsinternal admin serviceno auth inside VPC
swipe the figure sideways, or tap expand for full screen
1/4
the feature
Features that fetch user-supplied URLs (webhooks, image import, PDF rendering, link previews) let attackers choose where your server connects.
your server fetches attacker URLswebhooks, imports, previews
5

Secrets in code

controlhow
preventpre-commit and CI scanning (gitleaks, trufflehog), GitHub push protection
storeVault or a cloud secret manager, injected at runtime (Config course)
responda leaked secret is rotated immediately; deleting the commit is not enough (forks, caches, clones)
reduceshort-lived credentials (workload identity, dynamic DB credentials) so leaks expire
dependencieslockfiles, Dependabot or Renovate, provenance (SLSA, npm provenance), review install scripts