A scanner reports three places in a codebase where a request value reaches a file operation. How do you reason about what an attacker actually gains from each, and how do you rank them against one another for fixing?
answer
- reachability × privilege × sensitivity, multiplied not averaged
- write > read: writes become execution via interpreted directories
- traversal grants only what the process already has
- silent sink is still an oracle: error shape and timing
- containment ≠ authorisation — same base, different tenant
basics
~20 sRank by reachability × privilege × sensitivity. Ask who can reach the sink, what the executing process can already touch, whether the sink reads, writes or deletes, and whether the result or an error timing leaks. Writes outrank reads because writes become execution.
solid answer
~50 sThree axes, multiplied. **Reachability:** pre-authentication beats authenticated beats admin-only beats a queue consumer an attacker can only influence indirectly. A sink no attacker input reaches is not a finding. **Privilege of the executing principal:** traversal never grants more than the process already has. The blast radius is that process's effective reach — its mounted secret volumes, its credential files, its instance-metadata caches — not the whole host. Two identical defects in a locked-down worker and a broadly-privileged service are not the same defect. **Sensitivity and operation:** a read gives disclosure, and disclosure of a signing key or database credential chains to a full compromise. A **write** gives execution as soon as something interprets the written file. Delete and move give destruction and can be used to unlink a check. Even a sink that returns nothing is an oracle: different errors or timings enumerate the filesystem. One trap: containment can hold while authorisation fails, so a resolved path inside the base can still be another tenant's file.
go deeper
Know the two primitives — read and write — and that a write is worse because something may later execute what was written. Know the process cannot reach files it never had permission for.
Apply the three axes explicitly to a given finding and justify a rating, including the case where the endpoint returns no content but leaks through error differences.
Triage a set of findings against each other, name the worst reachable object per process, and separate the containment obligation from the authorisation obligation.
Turn the model into an inventory — sinks annotated with reachability, privilege and worst reachable object — and use it to choose one architectural control that retires many rows rather than patching each.
## What an attacker gains, precisely Start from primitives rather than from severity words. A path-traversal defect yields one of: - **Arbitrary read.** Configuration files, private keys, session or token stores, credential files, source code, backups. The interesting question is never "can they read a file" but "which single file turns this into something worse" — a signing key breaks authentication for every user, a database credential moves the attacker to a different system entirely, a source tree yields the next defect. - **Arbitrary write.** Strictly worse, because writes become execution. Landing content in anything later interpreted — a scheduled-job directory, a startup script location, a web root, a plugin or template directory, a shell profile, a configuration file a privileged process re-reads — converts the write into code running at the consumer's privilege. This is why extraction and upload sinks outrank download sinks. - **Delete or move.** Destruction of availability, and sometimes a step: removing a file whose presence gates a check, or displacing a legitimate file so a fallback path is taken. - **An oracle.** Even a sink that returns nothing usable leaks. "Not found" versus "permission denied", a slower response for a large file, a different error shape — each lets an attacker map the filesystem, confirm a deployment layout, or verify a guess about where secrets live. Treat a defect as exploitable-for-information even when it is not exploitable-for-content. ## The three ranking axes **Reachability.** Who can drive input into this sink, and how many steps does it take? Pre-authentication is the top band. Then authenticated-any-user, then a privileged role, then indirect reachability — a background job that consumes a queue an attacker can only write to through another feature. Reachability is where most scanner findings die: a sink fed exclusively by a compile-time constant is not a finding, and saying so quickly is part of doing this well. **Privilege of the executing principal.** Traversal grants exactly what the process could already do, no more. So the real blast radius is that process's effective reach: which filesystems it has mounted, which credential files sit inside them, whether an orchestrator has mounted a token or a secret volume into it, whether it holds an identity that further systems trust. A tightly-confined worker with a read-only root and no mounted secrets and a broadly-privileged service with database credentials on disk produce very different outcomes from an identical bug. Confinement does not fix the defect, but it genuinely bounds it — the same relationship least privilege has to every other injection class. **Sensitivity of what is reachable, and the operation.** Combine the primitive above with what actually lies within the process's reach. Ask concretely: from this process, at this privilege, what is the worst single file? If the answer is a signing key, the finding is critical regardless of how modest the endpoint looks. Multiply, do not average. A pre-auth write in a privileged process is an emergency. A post-auth read in a confined worker whose filesystem holds nothing but public assets can wait for the normal queue — and saying that out loud, with the reasoning, is more valuable to an interviewer than treating every finding as critical. ## The trap: containment is not authorisation The most-missed case in triage is the defect that never leaves the base directory. If every tenant's uploads live under one root and the resolved path is verified to be under that root, containment holds perfectly — and tenant A can still read tenant B's file by naming it. Namespace containment answers "is this object inside my intended set"; it does not answer "may this caller have this object". These are two obligations and a traversal fix satisfies only the first. When triaging, always ask the second question separately, because scanners never do. ## Ranking exposure across a whole codebase The same model scales up. Enumerate the sinks first — every place a name reaches a file operation — then annotate each with reachability, executing privilege, and the worst reachable object. That inventory is far more durable than a scan, because it survives refactors and tells you where to put a control rather than which lines to patch. It also tends to reveal that the right fix is architectural: one confined I/O layer, or a rule that names never cross a module boundary as strings, retires whole rows at once. Finally, the model transfers. Reachability × privilege × sensitivity is how you rank any sink-shaped defect — a shell invocation, a query interpreter, a deserialiser. Only the primitive differs, and knowing the primitive precisely is what makes the ranking honest instead of a colour on a dashboard.
- Does running the service in a container change your severity rating?It bounds it rather than removing it. The reachable filesystem becomes the container's, which usually excludes host secrets — but orchestrators routinely mount service-account tokens, TLS material and configuration secrets into that same filesystem, so the highest-value targets are often inside the container rather than outside. Rate it on what is actually mounted and on what identity the process carries, not on the presence of a container.
- The traversal is confirmed but the endpoint only ever returns HTTP 404 or 500 and never file content. How do you rate it?Still a finding, on the oracle axis. Distinguishable responses let an attacker confirm which files exist, infer the deployment layout, and validate guesses about where credentials live — reconnaissance that raises the value of every other defect. Rate it below a disclosure of content and well above nothing, and check whether timing differences leak size or content even when the status code does not.
saying these in an interview costs you the question
- Rating every traversal finding as critical without asking who can reach the sink or what the process can already read.
- Assuming a read-only defect is minor, ignoring that one credential or signing key converts it into full compromise.
- Believing a container makes traversal harmless, when mounted tokens and secret volumes are inside that same filesystem.
- Closing a finding because the resolved path stays under the base, without checking whether the caller was entitled to that object.
- Dismissing a sink that returns no content, when distinguishable errors and timings still enumerate the filesystem.