no-arbitrary-file-access
ESLint rule documentation for no-arbitrary-file-access
📡 Live from GitHub — This documentation is fetched directly from no-arbitrary-file-access.md and cached for 6 hours.
Keywords: path traversal, CWE-22, file access, LFI, directory traversal, fs, readFile, security
Prevents file system access with unsanitized user input to protect against path traversal attacks.
Prevents file system access with unsanitized user input to protect against path traversal attacks.
⚠️ This rule errors by default in the recommended config.
Quick Summary
| Aspect | Details |
|---|---|
| CWE Reference | CWE-22 (Improper Limitation of Pathname) |
| OWASP | A01:2021 Broken Access Control |
| Severity | High |
| Category | Security |
Rule Details
Path traversal vulnerabilities allow attackers to access files outside the intended directory using sequences like ../. This rule detects fs.* calls where the path comes from user input.
Smart Detection: This rule recognizes safe patterns including:
path.basename()sanitizationpath.join()with validated base directoriesstartsWith()validation guards
Examples
❌ Incorrect
// Direct user input to fs - DANGEROUS
app.get('/file', (req, res) => {
const content = fs.readFileSync(req.query.filename); // Path traversal!
res.send(content);
});
// User input from params
fs.readFile(req.params.path, callback);
// Unsanitized body input
fs.writeFileSync(req.body.filePath, data);✅ Correct
// Using path.basename() to strip directory components
const safeName = path.basename(req.query.filename);
const fullPath = path.join(UPLOAD_DIR, safeName);
fs.readFileSync(fullPath);
// Validation with startsWith() guard
const filePath = path.resolve(UPLOAD_DIR, req.query.filename);
if (!filePath.startsWith(UPLOAD_DIR)) {
throw new Error('Invalid path');
}
fs.readFileSync(filePath);
// Literal paths are always safe
fs.readFileSync('./config/app.json');
// Using allowlisted filenames
const ALLOWED_FILES = ['readme.txt', 'license.txt'];
if (ALLOWED_FILES.includes(req.query.file)) {
fs.readFileSync(path.join(PUBLIC_DIR, req.query.file));
}Error Message Format
The rule provides LLM-optimized error messages (Compact 2-line format) with actionable security guidance:
🔒 CWE-22 OWASP:A01 CVSS:7.5 | Path Traversal detected | HIGH [SOC2,PCI-DSS,HIPAA,ISO27001]
Fix: Review and apply the recommended fix | https://owasp.org/Top10/A01_2021/Message Components
| Component | Purpose | Example |
|---|---|---|
| Risk Standards | Security benchmarks | CWE-22 OWASP:A01 CVSS:7.5 |
| Issue Description | Specific vulnerability | Path Traversal detected |
| Severity & Compliance | Impact assessment | HIGH [SOC2,PCI-DSS,HIPAA,ISO27001] |
| Fix Instruction | Actionable remediation | Follow the remediation steps below |
| Technical Truth | Official reference | OWASP Top 10 |
Known False Negatives
The following patterns are not detected due to static analysis limitations:
Indirect User Input
Why: Data flow through multiple variables not traced.
// ❌ NOT DETECTED - Indirect flow
const userPath = getPathFromRequest(req);
fs.readFileSync(userPath);Mitigation: Apply validation at the source.
Custom File Wrappers
Why: Wrapper functions around fs not analyzed.
// ❌ NOT DETECTED - Custom wrapper
function readUserFile(path) {
return fs.readFileSync(path); // Called with user input elsewhere
}Mitigation: Apply rule to wrapper implementations.
Template Literals
Why: Complex template construction not fully traced.
// ❌ NOT DETECTED - Template literal
fs.readFileSync(`./uploads/${userId}/${req.query.file}`);Mitigation: Use path.join() with basename().
When Not To Use It
- In CLI tools where file paths come from command-line arguments (trusted)
- In build scripts processing known file trees
- When using a file access abstraction layer with built-in validation
Further Reading
Related Rules
- detect-non-literal-fs-filename
- no-unsafe-copy-from (in eslint-plugin-pg)
Category: Security
Type: Problem
Recommended: Yes