# Path traversal via normalization and alias quirks

Path guards that block only '..' but accept absolute paths, backslashes, colons, or 8.3 aliases

_Area: Web injection and code execution. Seen in 3 disclosed reports; latest 2026-06-23. Updated 2026-10-24._

## How it works
A path guard tries to keep user input inside a base directory by rejecting the literal string `..`. That assumption breaks because containment is not a property of the string `..` alone. `os.path.join(base, user)` silently discards `base` when `user` is absolute. On Windows, `\`, `:`, and 8.3 short-name aliases (`git~1`, `git~2`, ...) name the same protected files without any `..`. And a server that normalizes URLs differently from the guard lets encoded or doubled separators slip past the check but still resolve to a sensitive endpoint. In every case the guard checks a substring while the filesystem or router resolves a different path.

## Where it shows up
- Path filters that only test for `..` or a suffix, then call `join`/`resolve` [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-qxvg-h7q2-hcxh.md)
- Absolute-path inputs reaching file-read handlers [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-qxvg-h7q2-hcxh.md)
- Windows validators that reject `git~1` but not `\`, `:`, or `git~<N>` aliases [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-897w-fcg9-f6xj.md)
- Config options read under wrong names, so protection defaults differ by platform [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-897w-fcg9-f6xj.md)
- Archive/checkout code extracting into a trusted directory without sanitizing entries [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-qxvg-h7q2-hcxh.md)
- URL routers where `/+CSCOU+/../+CSCOE+/` reaches a protected endpoint unauthenticated [E3](https://bugbountylibrary.com/r/h1%3A694865.md)

## How to review
The invariant: after resolution, the canonical path must still be a descendant of the intended base, and the same normalization must be applied by both the guard and the consumer. Check that absolute inputs are rejected or rebased, that Windows structural characters and the full 8.3 alias space are enumerated, and that validators are diffed against the canonical upstream (Git's `is_ntfs_dotgit`) [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-897w-fcg9-f6xj.md). For routers, confirm the guard sees the same decoded path the handler resolves [E3](https://bugbountylibrary.com/r/h1%3A694865.md).

## Variants seen
- Absolute path bypassing `join` in a media handler [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-qxvg-h7q2-hcxh.md)
- NTFS alias/backslash/colon entries writing into `.git/hooks` [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-897w-fcg9-f6xj.md)
- URL normalization mismatch reaching an unauthenticated file-list endpoint [E3](https://bugbountylibrary.com/r/h1%3A694865.md)

## Why fixes fail
E2 shows a partial fix: blocking only literal `git~1` left other aliases and structural bytes open, and misnamed config keys meant protection was not reliably on.

## Impact and severity
High: E1 chained LFI to admin takeover and RCE; E2 gave arbitrary file write leading to RCE on Windows; E3 exposed files and VPN session data unauthenticated. Severity rises when the traversal feeds auth, restore, or execution paths.

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-qxvg-h7q2-hcxh.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-897w-fcg9-f6xj.md
- E3: https://bugbountylibrary.com/r/h1%3A694865.md
