Skip to content

Conversation

JustFiesta
Copy link
Owner

Based on multistage. As minimal as I could get them before maintenance overhead - used distroless for node and alpine for python.

…oless) - min 196MB without alpine musl overhead

The entrypoint is set as node in distroless so only CMD was provided
Copy link

github-actions bot commented Aug 20, 2025

🔍 Vulnerabilities of currencyservice:ci-63d000cba219e5173a0e69a8f583f135ef0687ac

📦 Image Reference currencyservice:ci-63d000cba219e5173a0e69a8f583f135ef0687ac
digestsha256:2f1a8a21790f370609285f64d802a4e6c8fadd9958abf72f2315515c16fc6334
vulnerabilitiescritical: 0 high: 1 medium: 0 low: 2
platformlinux/amd64
size67 MB
packages327
📦 Base Image gcr.io/distroless/static:nonroot
digestsha256:1b4dbd7d38a0fd4bbaf5216a21a615d07b56747a96d3c650689cbb7fdc412b49
vulnerabilitiescritical: 0 high: 0 medium: 0 low: 0
critical: 0 high: 1 medium: 0 low: 0 taffydb 2.6.2 (npm)

pkg:npm/[email protected]

high 7.5: CVE--2019--10790 Improper Input Validation

Affected range<=2.7.3
Fixed versionNot Fixed
CVSS Score7.5
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
EPSS Score0.449%
EPSS Percentile63rd percentile
Description

TaffyDB allows attackers to forge adding additional properties into user-input processed by taffy which can allow access to any data items in the DB. Taffy sets an internal index for each data item in its DB. However, it is found that the internal index can be forged by adding additional properties into user-input. If index is found in the query, TaffyDB will ignore other query conditions and directly return the indexed data item. Moreover, the internal index is in an easily-guessable format (e.g., T000002R000001). As such, attackers can use this vulnerability to access any data items in the DB. Note: taffy and its successor package taffydb are not maintained.

critical: 0 high: 0 medium: 0 low: 1 brace-expansion 1.1.11 (npm)

pkg:npm/[email protected]

low 1.3: CVE--2025--5889 Uncontrolled Resource Consumption

Affected range>=1.0.0
<=1.1.11
Fixed version1.1.12
CVSS Score1.3
CVSS VectorCVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
EPSS Score0.022%
EPSS Percentile4th percentile
Description

A vulnerability was found in juliangruber brace-expansion up to 1.1.11/2.0.1/3.0.0/4.0.0. It has been rated as problematic. Affected by this issue is the function expand of the file index.js. The manipulation leads to inefficient regular expression complexity. The attack may be launched remotely. The complexity of an attack is rather high. The exploitation is known to be difficult. The exploit has been disclosed to the public and may be used. Upgrading to version 1.1.12, 2.0.2, 3.0.1 and 4.0.1 is able to address this issue. The name of the patch is a5b98a4f30d7813266b221435e1eaaf25a1b0ac5. It is recommended to upgrade the affected component.

critical: 0 high: 0 medium: 0 low: 1 tmp 0.2.1 (npm)

pkg:npm/[email protected]

low 2.5: CVE--2025--54798 Improper Link Resolution Before File Access ('Link Following')

Affected range<=0.2.3
Fixed version0.2.4
CVSS Score2.5
CVSS VectorCVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
EPSS Score0.017%
EPSS Percentile2nd percentile
Description

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: raszi/node-tmp#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 [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': '/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

@JustFiesta JustFiesta merged commit ba089dc into main Aug 20, 2025
8 checks passed
@JustFiesta JustFiesta deleted the currency_and_emailservice_dockerfiles branch August 20, 2025 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant