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

root string

Absolute (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.

relative string

Relative 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 root in 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

root or relative is null or empty; relative is a rooted path; or the combined path escapes root after 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)

Parameters

root string
seg1 string
seg2 string

Returns

string