Skip to content
Back to skills

Path Validator

BSecurity

Use when an org role acts as path validator and must stop path traversal by checking any user-influenced file path resolves inside its intended base directory. Covers canonicalize-then-prefix-check, decoding before validation, symlink escapes, null-byte tricks, filename allowlists and Windows vs POSIX differences.

  • 21 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 22, 2026
ai-agentsrustphpgitapisecurity

Works with

  • cli
  • api

Security analysis

B75/100
  • criticalAccesses sensitive system or user directories

Pro shows the line behind each finding and how to fix it

Scanned September 28, 2026

npx -y skills add monoes/monomind --skill path-validator --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Path Validator?

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

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

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-validator
description: "Use when an org role acts as path validator and must stop path traversal by checking any user-influenced file path resolves inside its intended base directory. Covers canonicalize-then-prefix-check, decoding before validation, symlink escapes, null-byte tricks, filename allowlists and Windows vs POSIX differences."
tags: ["security","audit","api"]
tools: ["monograph_query","monograph_context","monograph_impact"]
license: Apache-2.0
source: https://github.com/monoes/monomind
---
# Path Validator — Best Practices

## Focus
Guards filesystem access from path traversal and injection — ensures any user-influenced path resolves inside its intended base directory before it's ever opened, read, or written.

## Best practices
- Avoid passing user-supplied input to filesystem APIs at all where possible — offer a fixed set of choices (an ID mapped server-side to a path) instead of a raw path
- When a path must be accepted, canonicalize it first: resolve `.`, `..`, and symlinks to get the true final path before making any decision
- Validate *after* decoding, never before — attackers stack multiple encoding layers (`%2e%2e/`, double-encoding, unicode variants) specifically to slip past pre-decode filters
- After canonicalizing, verify the resolved path starts with the expected base directory (prefix check on the canonical form, not the raw string)
- Restrict accepted filenames/extensions to an explicit allowlist (alphanumeric plus a small safe character set) rather than trying to blocklist dangerous sequences
- Treat every uploaded filename as untrusted — never use the client-supplied filename directly for storage; generate or map it server-side
- Apply the same canonicalize-then-prefix-check logic on every OS you deploy to — Windows path semantics (`\`, drive letters, alternate streams) differ from POSIX and need their own checks

## Common pitfalls
- Blocklisting `../` as a raw string match — trivially defeated by encoding, mixed separators, or double-encoded sequences
- Doing the base-directory prefix check on the raw input instead of the canonicalized path, so `../../etc/passwd` slips through pre-resolution
- Forgetting symlinks: a filename can be "inside" the base directory while a symlink underneath it points somewhere else entirely
- Validating the extension but not the full path, letting `evil.php%00.jpg`-style null-byte or double-extension tricks through
- Assuming validation done once at upload time still holds when the file is later moved, renamed, or accessed via a different code path

## Tools & techniques
- Canonicalization APIs (`realpath`, `Path.resolve`/`Path.normalize` + prefix check, `os.path.realpath`) as the mandatory first step before any comparison
- Explicit base-directory containment check: canonical path must start with canonical base directory + separator, not just a substring match
- Filename allowlist regex (e.g. `^[a-zA-Z0-9._-]+$`) combined with a maximum length limit
- Chroot/jail, containerized filesystem mounts, or scoped storage buckets as a second layer of defense beyond application-level checks
- Automated test cases covering `../`, encoded traversal, symlink escapes, and null-byte injection for every path-accepting endpoint

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.