Class SafePath
- Namespace
- Kuestenlogik.Bowire
- Assembly
- Kuestenlogik.Bowire.dll
Path-traversal-safe wrapper around Combine(string, string).
The BCL Combine(string, string) silently drops earlier
arguments when a later one is an absolute path (e.g.
Path.Combine("/var/bowire", "/etc/passwd") == "/etc/passwd"). When
the right-hand side comes from caller input that's a classic
path-traversal footgun — flagged by CodeQL cs/path-combine.
public static class SafePath
- Inheritance
-
SafePath
- Inherited Members
Remarks
Combine(string, string) rejects an absolute
relative outright (the contract is "relative segment under
root", so an absolute path is a programmer error, not a
request to escape the root). It also rejects ../ escapes by
normalising the combined path and verifying it still lives under
the (normalised) root.
Use this anywhere a path segment came from outside the assembly —
HTTP request bodies, query strings, environment variables, on-disk
JSON, &c. Compile-time-constant segments (e.g. "recording.json")
can keep using Combine(string, string) directly;
the rule's there to catch attacker-controlled inputs, not to ban
the BCL helper outright.
Methods
Combine(string, string)
Combine root with the relative segment
relative and verify the result still lives
under the normalised root.
public static string Combine(string root, string relative)
Parameters
rootstringAbsolute (or rooted-relative) path the combined result must stay under. Passed verbatim into GetFullPath(string) for the containment check; callers should normalise it upstream when they care about a specific layout.
relativestringRelative path segment to append. Must not be empty and must not itself be a rooted path (the BCL's Combine(string, string) would silently drop
rootin that case, which is the bug this helper exists to prevent).
Returns
- string
The fully-normalised combined path, guaranteed to be under
root.
Exceptions
- ArgumentException
rootorrelativeis null or empty;relativeis a rooted path; or the combined path escapesrootafter normalisation (e.g. via../segments).
Combine(string, string, string)
Three-segment variant — chains
Combine(string, string) so each pair is
independently validated. Use when the caller has two
attacker-controlled segments to anchor under root.
public static string Combine(string root, string seg1, string seg2)