Back to Blog
high SEVERITY7 min read

How Path Traversal happens in Node.js tmp package and how to fix it

The tmp package version 0.0.33 contained a high-severity path traversal vulnerability (CVE-2026-44705) that allowed attackers to escape temporary directories through unsanitized prefix and postfix parameters. This reddit-app project was upgraded from tmp 0.0.33 to 0.2.7, which implements proper input sanitization to prevent directory traversal attacks and removes the deprecated os-tmpdir dependency.

O
By Orbis AppSec
Published August 29, 2026Reviewed August 29, 2026

Answer Summary

CVE-2026-44705 is a path traversal vulnerability (CWE-22) in the Node.js tmp package versions prior to 0.2.6. The vulnerability occurs when unsanitized prefix or postfix parameters contain directory traversal sequences like "../", allowing attackers to escape the temporary directory and write files to arbitrary locations. The fix is to upgrade tmp to version 0.2.7 or later, which sanitizes these parameters and prevents directory escape attacks.

Vulnerability at a Glance

cweCWE-22
fixUpgrade tmp package from 0.0.33 to 0.2.7 with proper input validation
riskArbitrary file write outside intended temporary directory
languageJavaScript (Node.js)
root causetmp 0.0.33 failed to sanitize prefix/postfix parameters containing "../" sequences
vulnerabilityPath Traversal via unsanitized prefix/postfix parameters

Introduction

In a reddit-app Node.js project, Trivy scanner flagged a high-severity path traversal vulnerability in the reddit-app/package-lock.json file. The culprit? The tmp package version 0.0.33, which contained CVE-2026-44705—a vulnerability that allows attackers to escape temporary directory boundaries through unsanitized prefix and postfix parameters. When an application using tmp accepts user-controlled input for temporary file naming, attackers could inject directory traversal sequences like ../../etc/ to write files anywhere on the filesystem, potentially compromising the entire system.

The vulnerability resided in how tmp 0.0.33 handled the optional prefix and postfix parameters when creating temporary files and directories. Without proper sanitization, these parameters could contain path traversal sequences that would be directly concatenated into the final filesystem path, bypassing the intended temporary directory isolation.

The Vulnerability Explained

The tmp package is widely used in Node.js applications to create temporary files and directories. In version 0.0.33, the package accepted prefix and postfix options that would be incorporated into the temporary file path. However, these parameters were not sanitized for directory traversal sequences.

Here's what the vulnerable dependency tree looked like in package-lock.json:

"node_modules/tmp": {
  "version": "0.0.33",
  "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
  "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
  "license": "MIT",
  "dependencies": {
    "os-tmpdir": "~1.0.2"
  },
  "engines": {
    "node": ">=0.6.0"
  }
}

The vulnerability manifests when application code uses tmp with user-influenced input. Consider this attack scenario:

const tmp = require('tmp'); // version 0.0.33

// Attacker controls the prefix through an HTTP parameter
const userPrefix = req.query.prefix; // Contains: "../../etc/cron.d/"

tmp.file({ prefix: userPrefix, postfix: '.sh' }, (err, path, fd) => {
  // Intended: /tmp/tmp-XYZ.sh
  // Actual: /etc/cron.d/tmp-XYZ.sh
  fs.writeFileSync(path, maliciousScript);
});

In this example, an attacker could:
1. Supply ../../etc/cron.d/ as the prefix parameter
2. The tmp library would create a file at /etc/cron.d/tmp-randomID.sh instead of in /tmp/
3. Write a malicious cron job that executes with elevated privileges
4. Achieve arbitrary code execution on the server

The real-world impact for the reddit-app application is severe. If any route handler or background job uses tmp with data derived from Reddit API responses, user comments, or configuration files, an attacker could:
- Overwrite application configuration files to change behavior
- Write to the web server's document root to serve malicious content
- Create files in system directories to escalate privileges
- Delete or corrupt critical application data

The Fix

The security team upgraded tmp from version 0.0.33 to 0.2.7, which includes comprehensive input sanitization. Here's what changed in package-lock.json:

Before (vulnerable):

"node_modules/tmp": {
  "version": "0.0.33",
  "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
  "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
  "license": "MIT",
  "dependencies": {
    "os-tmpdir": "~1.0.2"
  },
  "engines": {
    "node": ">=0.6.0"
  }
}

After (secure):

"node_modules/tmp": {
  "version": "0.2.7",
  "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz",
  "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==",
  "license": "MIT",
  "engines": {
    "node": ">=14.14"
  }
}

Notice several critical improvements:

  1. Version upgrade: From 0.0.33 to 0.2.7, which includes the CVE-2026-44705 fix
  2. Dependency removal: The deprecated os-tmpdir dependency is completely removed, as tmp 0.2.x uses Node.js's built-in os.tmpdir() method
  3. Modern Node.js requirement: The minimum Node.js version increased from 0.6.0 to 14.14, ensuring access to modern security features

The fix was enforced through an npm override in package.json:

"overrides": {
  "tmp": "0.2.7"
}

This override ensures that even if other dependencies in the project require older versions of tmp, npm will force the use of the secure 0.2.7 version throughout the entire dependency tree.

How this specific change solves the problem:

The tmp 0.2.7 version implements strict validation of prefix and postfix parameters:
- Path traversal sequences (../, ..\\) are detected and rejected
- Absolute paths are not permitted in prefix/postfix
- Only safe filename characters are allowed
- The temporary directory boundary is enforced at the library level

This means that even if application code passes unsanitized user input to tmp, the library itself will prevent directory escape attempts. The attack scenario shown earlier would now fail safely:

const tmp = require('tmp'); // version 0.2.7

const userPrefix = req.query.prefix; // Contains: "../../etc/cron.d/"

tmp.file({ prefix: userPrefix, postfix: '.sh' }, (err, path, fd) => {
  // tmp 0.2.7 sanitizes the prefix, stripping traversal sequences
  // Result: /tmp/.._.._etc_cron.d_tmp-XYZ.sh (safe)
  // Or throws an error, depending on configuration
});

Prevention & Best Practices

To avoid path traversal vulnerabilities in Node.js applications:

1. Keep Dependencies Updated

Regularly audit and update npm packages, especially security-critical libraries like tmp. Use tools like npm audit or npm outdated to identify vulnerable dependencies:

npm audit
npm audit fix

2. Validate File Path Components

Never pass user input directly as file path components without validation:

// BAD: Direct use of user input
tmp.file({ prefix: req.query.prefix });

// GOOD: Validate against allowlist
const ALLOWED_PREFIXES = ['user-upload', 'cache', 'session'];
const prefix = ALLOWED_PREFIXES.includes(req.query.type) 
  ? req.query.type 
  : 'default';
tmp.file({ prefix });

3. Use Path Normalization

Always normalize and validate paths before file operations:

const path = require('path');

function isSafePath(userPath, baseDir) {
  const normalized = path.normalize(userPath);
  const resolved = path.resolve(baseDir, normalized);
  return resolved.startsWith(path.resolve(baseDir));
}

4. Implement Defense in Depth

Even with library fixes, implement application-level controls:
- Use chroot jails or containers to limit filesystem access
- Run Node.js processes with minimal file system permissions
- Log all file creation operations for audit trails
- Implement rate limiting on file creation endpoints

5. Static Analysis Integration

Integrate security scanners into your CI/CD pipeline:
- Trivy: Scans package-lock.json for known CVEs (as used here)
- Snyk: Monitors dependencies and suggests fixes
- npm audit: Built-in vulnerability scanner
- Semgrep: Detects insecure code patterns

OWASP and CWE References

This vulnerability maps to:
- CWE-22: Improper Limitation of a Pathname to a Restricted Directory
- OWASP Top 10 2021: A01:2021 – Broken Access Control

The OWASP Path Traversal prevention cheat sheet recommends:
- Input validation with allowlists
- Path canonicalization before validation
- Sandboxing file operations
- Principle of least privilege for file system access

Key Takeaways

  • tmp 0.0.33's unsanitized prefix/postfix parameters allowed directory traversal through ../ sequences, enabling arbitrary file writes outside temporary directories
  • The os-tmpdir dependency was completely removed in tmp 0.2.x, reducing the attack surface and eliminating a deprecated dependency
  • npm overrides in package.json ensure consistent security across the entire dependency tree, even when transitive dependencies require older versions
  • Trivy scanner successfully detected CVE-2026-44705 in package-lock.json before the vulnerability could be exploited in production
  • Upgrading from Node.js 0.6.0 to 14.14 minimum requirement ensures access to modern security features and better filesystem isolation primitives

How Orbis AppSec Detected This

  • Source: The vulnerability exists in the tmp package's handling of prefix and postfix parameters, which can be influenced by user input through HTTP requests, API responses, or configuration files
  • Sink: The unsafe path construction in tmp 0.0.33's file() and dir() methods at the point where prefix/postfix are concatenated into filesystem paths without sanitization
  • Missing control: Input validation and path traversal sequence filtering for the prefix and postfix parameters before filesystem path construction
  • CWE: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
  • Fix: Upgraded tmp from 0.0.33 to 0.2.7, which implements comprehensive input sanitization and removes the deprecated os-tmpdir dependency

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

CVE-2026-44705 demonstrates how even widely-used utility libraries can contain critical security flaws that persist across years and thousands of dependent projects. The path traversal vulnerability in tmp 0.0.33 could have allowed attackers to write files anywhere on the filesystem, leading to complete system compromise. By upgrading to tmp 0.2.7 and using npm overrides to enforce this version across the dependency tree, the reddit-app project eliminated this attack vector.

The key lesson: dependency security requires continuous monitoring and rapid response. Automated tools like Trivy can detect these vulnerabilities, but the real security improvement comes from acting on those findings—upgrading vulnerable packages, testing the changes, and deploying fixes quickly. Make dependency auditing a regular part of your development workflow, not a once-a-year security review.

References

Frequently Asked Questions

What is path traversal in the tmp package?

Path traversal in tmp occurs when unsanitized prefix or postfix parameters containing "../" sequences allow attackers to escape the temporary directory boundaries and create files in arbitrary filesystem locations, potentially overwriting critical system files or application data.

How do you prevent path traversal in Node.js temporary file operations?

Use tmp version 0.2.6 or later which sanitizes prefix and postfix parameters, avoid accepting user input directly as file path components, validate all path inputs against an allowlist, and use path.normalize() and path.resolve() to detect traversal attempts before passing paths to file operations.

What CWE is path traversal?

Path traversal is classified as CWE-22 (Improper Limitation of a Pathname to a Restricted Directory), also known as "directory traversal." It occurs when an application uses external input to construct a pathname without properly neutralizing special elements that can resolve to locations outside the intended directory.

Is input validation enough to prevent path traversal in tmp?

While input validation helps, upgrading to tmp 0.2.7 is essential because the vulnerability exists in the library's core logic. The newer version implements comprehensive sanitization internally, removing the burden from application developers and ensuring consistent protection across all usage patterns.

Can static analysis detect path traversal vulnerabilities?

Yes, static analysis tools like Trivy, Snyk, and Semgrep can detect known path traversal vulnerabilities by scanning dependency manifests for vulnerable package versions. In this case, Trivy identified CVE-2026-44705 by analyzing package-lock.json and flagging tmp 0.0.33 as vulnerable.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #24

Related Articles

medium

How Path Traversal and Filename Injection Happens in Python File Handling and How to Fix It

A medium-severity path traversal vulnerability in `PainterNode/painter_node.py` allowed attackers to reference files outside the intended directory by exploiting a broken `isFileName()` validation function. The original logic used incorrect boolean operators, meaning the filename guard never actually blocked malicious inputs like `../../../etc/passwd` or paths containing backslashes. The fix rewrites the condition with proper logic and adds explicit checks for path separator characters and direc

critical

How Archive Path Traversal Happens in Node.js and How to Fix It

CVE-2026-53486 is a critical path traversal vulnerability in the Decompress library, where crafted archive entries can write files and symbolic links outside the intended extraction directory. This vulnerability was transitively introduced through `@vitest/browser` and related packages pinned at version 4.1.5, and was resolved by upgrading to 4.1.6 and 5.0.0-beta.3. Left unpatched, an attacker who controls an archive file processed by any downstream consumer of this dependency chain could overwr

high

How Path Traversal happens in Python Flask apps and how to fix it

A path traversal vulnerability in `WAVE2SCORE/app.py` allowed attackers to supply a crafted file path that escaped the application's intended working directory, potentially enabling access to arbitrary files on the server. The fix resolves the absolute path and validates it against the expected `WORK_DIR` boundary before any processing occurs. This kind of boundary check is a critical safeguard in any application that processes user-supplied file paths.

high

How Arbitrary File Read happens in Python LangSmith SDK and how to fix it

A high-severity arbitrary server-side file read vulnerability (GHSA-f4xh-w4cj-qxq8) was discovered in LangSmith SDK's `TracingMiddleware`, affecting versions prior to 0.8.18. An attacker able to influence tracing requests could potentially read arbitrary files from the server's filesystem. Upgrading from version 0.8.15 to 0.8.18 in `poetry.lock` and `pyproject.toml` closes the attack surface entirely.

critical

How Command Injection happens in Python PopClip Extensions and how to fix it

A critical command injection vulnerability was discovered in `contrib/Klipz.popclipext/Klipz.py`, where user-controlled clipboard content was concatenated directly into shell commands executed via `osascript`. The fix replaces unsafe string concatenation with `subprocess` and proper argument lists, and replaces the unsafe `pickle` serialization with `json` to eliminate a secondary deserialization risk. Together, these changes close two distinct attack surfaces in a single file.

high

How insecure-use-string-copy-fn happens in C and how to fix it

A high-severity vulnerability was identified in `plugin/bin/install.c` where `strcpy()` and `strncpy()` were used to handle path strings without proper bounds checking or guaranteed null-termination. The fix replaces `strcpy()` with direct character assignment and `strncpy()` with `snprintf()`, eliminating both buffer overflow and missing null-terminator risks in the plugin installation workflow.