Source-Code Analysis
What this domain tests
Source-Code Analysis presents snippets, diffs or small repositories and asks where untrusted data lands, whether a sanitizer is sound, and which construct is actually dangerous. The skill under test is precise reading: taint path, guard placement, resolved dependency version.
Method
- Map sources to sinks. Sources: request parameters, headers, cookies, uploaded files, database rows, queue messages, environment variables. Sinks: SQL builders,
eval/exec, template rendering, filesystem paths, deserializers, XML parsers, redirects, loggers, HTTP clients. - Judge sanitizer soundness, not existence. Does it run on every branch? Is it applied to the same variable that reaches the sink? Does it match the target grammar? Check early returns and exception handlers that skip the guard.
- Know the language-specific killers: Java
ObjectInputStreamand XStream, Pythonpickleandyaml.loadversusyaml.safe_load, RubyMarshal, PHPunserializewith type juggling, Node recursive merge causing prototype pollution, andpath.resolvediscarding earlier segments when a later segment is absolute. - Treat dependencies as resolved artifacts. A CVE matters only if the lockfile resolves the vulnerable version and the vulnerable function is reachable; manifests alone prove nothing.
Worked example
def download(name):
p = os.path.join("/srv/files", name)
if not os.path.realpath(p).startswith("/srv/files"):
abort(403)
return send_file(p)
name is user-controlled and reaches send_file. A guard exists, so the naive answer is no finding. The guard is unsound: a prefix comparison without a path separator accepts any sibling directory, so ../../files_backup/secret resolves to /srv/files_backup/secret, which passes startswith. The correct control compares against the base plus os.sep, or uses a common-path check, and rejects symlinks by resolving before comparison.
Traps that cost marks
- Assuming one sanitizer call dominates every path through the function.
- Confusing
yaml.safe_loadwithyaml.load(..., Loader=FullLoader). - Reporting a CVE from a manifest line without checking the lockfile or reachability.
- Missing second-order flows where data is stored safely and concatenated later.
- Ignoring configuration and CI files when hunting hard-coded credentials.