Downloads · 30 days
0
Uttam69/tfjs-path-traversal-poc
tfjs-path-traversal-poc is a machine learning model from Uttam69. Use it for the machine learning task on the model card, and read the license before you ship it in a product.
Vulnerability: Loading a TensorFlow.js model.json with @tensorflow/tfjs-node reads files outside the model directory because weightsManifest[].paths are joined to the model directory and read with no path-traversal gu…
Downloads · 30 days
0
Access
Public
Updated Jul 19, 2026
Repo size
—
Likes
0
Public
Click a slice to open those files.
.md3 KB · 45%
From the Hugging Face model README
Vulnerability: Loading a TensorFlow.js model.json with @tensorflow/tfjs-node reads files
outside the model directory because weightsManifest[].paths are joined to the model directory
and read with no path-traversal guard. A malicious model.json with ../ in a weight path
performs arbitrary local file read at model-load time. ModelScan does not scan .json, so the
malicious model file is never inspected.
Benign PoC:
model/model.jsonreads../SECRET.txt(a marker that ships in this repo, one level above the model's own folder). This proves the loader escapes the model directory. To read a real sensitive file, set the manifest path to e.g.../../../../../../etc/passwd— only against files you are authorized to read.
@tensorflow/tfjs-node — tf.loadLayersModel('file://.../model.json') / tf.loadGraphModel(...) /
tf.io.fileSystem(...).load().tfjs-node/src/io/file_system.ts → NodeFileSystem.loadWeights:
join(dirName, path) then readFile(...) with no normalization / no .. rejection / no base-dir check.tfjs-poc/
model/model.json # weightsManifest paths = ["../SECRET.txt"] (escapes model/)
SECRET.txt # marker "TFJS_LEAK_PROOF1" (16 bytes), sits OUTSIDE model/
reproduce.js # loads model/model.json, prints the bytes read
npm install --ignore-scripts @tensorflow/tfjs-node
node reproduce.js
Expected output:
bytes read from ../SECRET.txt (outside model/): "TFJS_LEAK_PROOF1"
CONFIRMED: arbitrary file read via path traversal at model load
(--ignore-scripts skips the native backend build, which is not needed — the file-read sink is in
the pure-JS dist/io/file_system.js. On Linux the prebuilt native binary installs cleanly without it.)
modelscan -p model/model.json -r json # -> {"total_scanned": 0, "issues": []}
tfjs-core/src/io/weights_loader.ts, fetchUrl = filePathPrefix + filepath, unvalidated).Resolve each manifest path and reject any that escapes the model directory:
const base = path.resolve(dirName);
const full = path.resolve(base, p);
if (full !== base && !full.startsWith(base + path.sep)) throw new Error('weight path outside model dir');
No prior huntr/NVD/GHSA report for tfjs model-load traversal. GitHub issue #8628 is a different
bug — path traversal in the tfjs converter (write_weights.py, file write during
conversion), not this load-time read in tfjs-node.