Tracing user input (source to sink)
TL;DR
“Source to sink” is the whole game: input enters at a source, and if it reaches a dangerous sink without being cleaned on the way, you have a bug. Everything in between is validation and encoding — or the lack of it.
What it is
Think of untrusted input as “tainted”. It becomes safe only when it’s validated or encoded. Your job in review is to follow the taint from where it enters to where it’s used, and see whether it got cleaned along the way.
How to trace it
- Start at the source: a request parameter, header, uploaded file, or message.
- Follow it through the functions it’s passed into — assignments, helpers, objects.
- Watch for cleansing: is it validated against an allow-list, parameterised, or encoded for its destination?
- Stop at the sink: if tainted input arrives at a dangerous sink still dirty, that’s the vulnerability.
Why it matters
This one habit explains most web bugs at once — SQLi, XSS, command injection and path traversal are all the same story: tainted input reached a sink unsanitised. Once you see code this way, they stop being separate things to memorise.