Skip to content
Back to skills

Path Traversal

BSecurity

Detect path traversal and Zip Slip vulnerabilities where user-controlled path components can escape intended directories.

  • 46 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added May 26, 2026
securityjavascripttypescriptpythongojavabashnode

Security analysis

B88/100
  • criticalAccesses sensitive system or user directories

Pro scans all 4 files and shows the line behind each finding

Scanned May 27, 2026

npx -y skills add ByamB4/find-cve-agent --skill path-traversal --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Path Traversal?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Path Traversal
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/byamb4-path-traversal/badge)](https://www.skillsdirectory.com/skills/byamb4-path-traversal)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: path-traversal
description: "Detect path traversal and Zip Slip vulnerabilities where user-controlled path components can escape intended directories."
metadata:
  filePattern:
    - "**/*.js"
    - "**/*.ts"
    - "**/*.py"
    - "**/*.go"
  bashPattern:
    - "semgrep.*path"
    - "grep.*(path\\.join|writeFile|extractall)"
  priority: 90
---

# Path Traversal & Zip Slip Detection

## When to Use

Audit archive extraction libraries, file upload handlers, static file servers, file path utilities, and any package that writes files based on user-controlled names.

~85% CVE acceptance rate when confirmed.

## Key Insight

`path.join()` does NOT prevent `..` traversal in Node.js:
```js
path.join('/uploads', '../../../etc/passwd')
// Returns: '/etc/passwd' -- NOT '/uploads/etc/passwd'
```

`path.resolve()` returns an absolute path but also does NOT validate that it stays within a base directory.

## Variants

### 1. Classic Path Traversal
User controls a filename/path parameter that is concatenated with a base directory:
```js
const filePath = path.join(uploadDir, req.params.filename);
fs.readFileSync(filePath); // ../../../etc/passwd
```

### 2. Zip Slip
Malicious archive entries contain `../` in their filenames. During extraction, files are written outside the intended directory:
```
malicious.zip contains:
  ../../../../tmp/pwned.txt
```

### 3. Symlink Following
Archive contains a symlink pointing outside the target directory, then a file targeting that symlink. During extraction, the file follows the symlink and writes to an arbitrary location.

### 4. Backslash Bypass
On Windows or with naive path checks, `..\` bypasses `../` filtering:
```js
filename = "..\\..\\..\\etc\\passwd"
```

### 5. URL Encoding Bypass
```
%2e%2e%2f = ../
%2e%2e/ = ../
..%2f = ../
Double encoding: %252e%252e%252f
```

### 6. Null Byte (Legacy)
```
../../etc/passwd%00.png
```
Older systems truncate at null byte. Rare in modern runtimes.

## Process

### Step 1: Find File Operations

```
# JavaScript/TypeScript
grep -rn "fs\.writeFile\|fs\.createWriteStream\|fs\.rename\|fs\.copyFile" .
grep -rn "fs\.readFile\|fs\.readFileSync\|fs\.createReadStream" .
grep -rn "path\.join\|path\.resolve" .

# Python
grep -rn "open(.*w\|shutil\.copy\|shutil\.move\|os\.rename" .
grep -rn "extractall\|extract(" .

# Go
grep -rn "os\.Create\|os\.OpenFile\|io\.Copy\|filepath\.Join" .
grep -rn "archive/zip\|archive/tar" .
```

### Step 2: Check Archive Extraction

```
grep -rn "unzip\|extract\|decompress\|gunzip\|untar" .
grep -rn "adm-zip\|yauzl\|unzipper\|archiver\|tar\|fflate\|JSZip\|node-7z" .
grep -rn "zipfile\|tarfile\|py7zr\|patool" .
```

### Step 3: Check Path Validation

```
grep -rn "startsWith\|indexOf\|includes\|realpath\|normalize" .
grep -rn "\.\." . --include="*.js" | grep -i "reject\|deny\|block\|filter"
```

### Step 4: Verify Validation Effectiveness

Common INCORRECT validations:
- `path.join(base, input)` -- does NOT prevent traversal
- `input.indexOf('..') === -1` -- can be bypassed with `....//` or encoding
- `input.replace('../', '')` -- bypassed with `....//` (after removal, `../` remains)

CORRECT validations:
- `path.resolve(base, input)` then `result.startsWith(base + path.sep)` -- verifies result is within base
- `fs.realpathSync()` to resolve symlinks before checking

## CVSS Guidance

- Arbitrary file read (unauthenticated): HIGH 7.5
- Arbitrary file write via Zip Slip: HIGH 7.5-8.1
- File write + code execution (overwrite config/executable): CRITICAL 9.8
- Authenticated file read: MEDIUM 6.5

## References

- [Sinks](references/sinks.md) -- File operation sinks by language
- [False Positive Indicators](references/false-positive-indicators.md) -- When this isn't exploitable
- [PoC Skeleton](references/poc-skeleton.md) -- Path traversal and Zip Slip PoC templates

Files in this skill

  • SKILL.md3.7 KB
  • references/false-positive-indicators.md1.4 KB
  • references/poc-skeleton.md2.8 KB
  • references/sinks.md2.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.