pi-lens
Version:
Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo
72 lines (61 loc) • 2.12 kB
YAML
# TypeScript Path Traversal
# Detects fs and path API calls with potentially user-controlled paths.
id: ts-path-traversal
name: Path Traversal Risk
severity: error
category: security
defect_class: injection
inline_tier: blocking
language: typescript
message: "Potential path traversal sink — avoid filesystem I/O with untrusted input"
description: |
File-system APIs (`fs.readFile`, `fs.writeFile`, `path.join`, etc.) are
vulnerable when path arguments include untrusted input. An attacker can
inject `../` sequences to access files outside the intended directory.
✅ FIX: validate and sanitize paths; use allowlists or chroot jails.
query: |
(call_expression
function: (member_expression
object: (identifier) @MOD
property: (property_identifier) @FN)
arguments: (arguments
[(identifier) (member_expression) (template_string) (call_expression) (binary_expression)] @PATH)
(#eq? @MOD "fs"))
(call_expression
function: (member_expression
object: (identifier) @MOD
property: (property_identifier) @FN)
arguments: (arguments
[(identifier) (member_expression) (template_string) (call_expression) (binary_expression)] @PATH)
(#eq? @MOD "path")
(#match? @FN "^(join|resolve)$"))
(call_expression
function: (member_expression
object: (member_expression
object: (identifier) @MOD
property: (property_identifier) @PROMISES)
property: (property_identifier) @FN)
arguments: (arguments
[(identifier) (member_expression) (template_string) (call_expression) (binary_expression)] @PATH)
(#eq? @MOD "fs")
(#eq? @PROMISES "promises"))
metavars:
- MOD
- PROMISES
- FN
- PATH
post_filter: ts_path_traversal_sink
has_fix: false
tags:
- typescript
- security
- path-traversal
- cwe-22
- owasp-a01
examples:
bad: |
fs.readFile(req.query.path); // BAD — user controls path
path.join(baseDir, userFile); // BAD — user controls segment
good: |
fs.readFile("./safe.txt"); // OK — literal path
path.join(baseDir, "static"); // OK — literal segment