skills/path-traversal-anti-pattern/SKILL.md
Security anti-pattern for path traversal vulnerabilities (CWE-22). Use when generating or reviewing code that handles file paths, reads or writes files based on user input, or serves static content. Detects joining user input to paths without proper sanitization or validation.
npx skillsauth add igbuend/grimbard path-traversal-anti-patternInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Severity: High
Attackers read or write files outside intended directories by manipulating user input in file paths. Using sequences like ../ without validation allows navigation up directory trees to access /etc/passwd, source code, or credentials.
The anti-pattern is concatenating user input into file paths without validating for directory traversal characters.
# VULNERABLE: User input joined directly to base path.
from flask import request
import os
BASE_DIR = "/var/www/uploads/"
@app.route("/files/view")
def view_file():
# Filename from request without validation.
filename = request.args.get("filename")
# User input concatenated with base directory.
# No path traversal validation.
file_path = os.path.join(BASE_DIR, filename)
# Attack: /files/view?filename=../../../../etc/passwd
# Result: /var/www/uploads/../../../../etc/passwd
# Resolves to: /etc/passwd
# Reads and returns system password file.
try:
with open(file_path, 'r') as f:
return f.read()
except FileNotFoundError:
return "File not found.", 404
# SECURE: Validate input and canonicalize path.
from flask import request
import os
BASE_DIR = "/var/www/uploads/"
@app.route("/files/view/secure")
def view_file_secure():
filename = request.args.get("filename")
# 1. Basic validation: check for malicious characters.
if ".." in filename or filename.startswith("/"):
return "Invalid filename.", 400
# 2. Construct full path.
file_path = os.path.join(BASE_DIR, filename)
# 3. Canonicalize: resolve symbolic links and `../` sequences.
# Most critical step.
real_path = os.path.realpath(file_path)
real_base_dir = os.path.realpath(BASE_DIR)
# 4. Ensure resolved path within intended base directory.
if not real_path.startswith(real_base_dir + os.sep):
return "Access denied: Path is outside of the allowed directory.", 403
# Safe to access file.
try:
with open(real_path, 'r') as f:
return f.read()
except FileNotFoundError:
return "File not found.", 404
os.path.join, + on strings).../, ..\). A simple search-and-replace for ../ is not sufficient due to potential bypasses like ....//.os.path.realpath() (Python), File.getCanonicalPath() (Java) to resolve to absolute form.development
Security anti-pattern for Cross-Site Scripting vulnerabilities (CWE-79). Use when generating or reviewing code that renders HTML, handles user input in web pages, uses innerHTML/document.write, or builds dynamic web content. Covers Reflected, Stored, and DOM-based XSS. AI code has 86% XSS failure rate.
development
Security anti-pattern for XPath injection vulnerabilities (CWE-643). Use when generating or reviewing code that queries XML documents, constructs XPath expressions, or handles user input in XML operations. Detects unescaped quotes and special characters in XPath queries.
development
Security anti-pattern for weak password hashing (CWE-327, CWE-759). Use when generating or reviewing code that stores or verifies user passwords. Detects use of MD5, SHA1, SHA256 without salt, or missing password hashing entirely. Recommends bcrypt, Argon2, or scrypt.
development
Security anti-pattern for weak encryption (CWE-326, CWE-327). Use when generating or reviewing code that encrypts data, handles encryption keys, or uses cryptographic modes. Detects DES, ECB mode, static IVs, and custom crypto implementations.