CWE-73: External Control of File Name
Overview
This guidance helps you interpret and remediate findings from DAST (Dynamic Application Security Testing) tools. The scanner detected that the application accepted user-controlled filenames in parameters that directly control file system operations, enabling path traversal, unauthorized file access, or file manipulation. DAST tools identify this by:
Detection Methods:
- Submitting path traversal sequences in filename parameters (
../../etc/passwd,..\..\Windows\win.ini) - Testing absolute paths in upload/download filename fields (
/tmp/shell.php,C:\backdoor.exe) - Injecting directory separators and special characters (
../,..\,/,\) - Testing null byte injection for extension bypasses (
safe.txt%00.php) - Monitoring responses for evidence of unauthorized file access or creation
- Observing error messages revealing file system operations or paths
HTTP Evidence:
- HTTP 200 responses containing content from files outside intended directories
- Successful creation of files in restricted locations (tested via subsequent requests)
- Error messages showing server-side file paths ("Could not open /var/www/../../etc/passwd")
- Response headers revealing actual file paths (Content-Disposition, X-Download-Filename)
- Different HTTP status codes for valid vs. invalid file operations
- Timing differences indicating file existence checks
Scanner Behavior: OWASP ZAP and PortSwigger Burp test file-related parameters (filename, file, path, document) with traversal sequences, absolute paths, and null bytes. They analyze responses for signs of successful file access, creation, or error messages revealing filesystem interaction. Some scanners perform two-stage testing: first creating a file with a known name, then verifying its existence.
Analyzing the Dynamic Scan Result
What the DAST Scanner Found
When reviewing your security scan results, you'll see:
HTTP Request Details
- URL and endpoint that triggered the finding
- HTTP method (GET, POST, etc.)
- Query parameters or form data with test payloads
- Request headers and body content
HTTP Response Evidence
- Response showing the vulnerability manifestation
- Evidence of improper handling or injection
- Runtime behavior indicators
Attack Vector
- Which parameter or input is vulnerable
- Type of exploitation possible
- Context where the vulnerability appears
Mapping DAST Findings to Source Code
Find the Vulnerable Endpoint
Use the HTTP request URL to locate the code:
# Search for the URL path in your codebase
grep -r "/save" src/
grep -r "/write" src/
grep -r "/create" src/
grep -r "/export" src/
grep -r "route.*save" src/
Locate the Route Handler
Common patterns to search for:
- Python Flask/Django:
@app.route('/save'), file writing operations - Node.js Express:
app.post('/save', ...),fs.writeFile() - Java Spring:
@PostMapping("/save"),Fileobject creation - ASP.NET:
[HttpPost("save")],File.WriteAllText() - PHP:
fopen(),file_put_contents()with user input
Find the Parameter Handling
Search for filename parameters:
# Find where the parameter is accessed
grep -r "request.form.get('filename')" src/ # Python Flask
grep -r "req.body.filename" src/ # Node.js
grep -r "@RequestParam.*filename" src/ # Java Spring
grep -r "Request.Form['filename']" src/ # ASP.NET
grep -r "$_POST['filename']" src/ # PHP
Trace to Vulnerable Operation
Look for where the filename is used in:
- File creation: Creating files with user-controlled names
- File deletion: Deleting files based on user input
- File reading: Opening files with user-specified paths
- Path construction: Building file paths with user input
- Missing validation / indirection: User-controlled filenames used directly in file operations
Remediation
Core principle: Never let untrusted input choose file names, paths, or file operations; map external identifiers to server-controlled filenames and enforce canonical containment and safe file semantics.
→ For comprehensive remediation guidance, see Static CWE-73 Guidance
Language-Specific Guidance
The static guidance provides detailed remediation steps for many languages. If you need language-specific examples:
Verification and Follow-Up Testing
After applying the fix:
Reproduce the Vulnerability
# Use curl to test file control
curl -X POST "http://localhost:3000/save" \
-d "filename=../../etc/passwd&content=test"
curl -X POST "http://localhost:3000/export" \
-d "filename=/tmp/../../etc/shadow"
# Or use browser DevTools Network tab
Verify the Fix
- Confirm filenames are validated against allowlist patterns
- Verify path traversal sequences are rejected (
.., absolute paths) - Check files are created only in designated directories
- Ensure filenames are allowlist-validated and canonicalized; reject on mismatch (don’t ‘clean’ unsafe input)
- Test path normalization prevents bypasses
Test Edge Cases
# Path traversal
/save?filename=../../etc/passwd
/save?filename=....//....//etc/passwd
/save?filename=/etc/passwd
# Null byte injection (if applicable)
/save?filename=safe.txt%00.php
# Windows paths
/save?filename=C:\Windows\System32\config\sam
/save?filename=..\..\..\Windows\win.ini
# Overwrite critical files
/save?filename=.htaccess
/save?filename=web.config
# Or use browser DevTools Network tab to copy as cURL
Re-run DAST Scanner
Run your dynamic scanner again on the fixed endpoint to confirm remediation.