contrib.nodejsscan.path_traversal.generic_path_traversal

Author
99
Download Count*
License
Untrusted user input in readFile()/readFileSync() can endup in Directory Traversal Attacks.
Run Locally
Run in CI
Defintion
rules:
- id: generic_path_traversal
patterns:
- pattern-either:
- pattern-inside: |
require('http');
...
- pattern-inside: |
require('express');
...
- pattern-inside: |
require('koa');
...
- pattern-inside: |
require('electron');
...
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: |
$X.createReadStream(..., <... $REQ.$QUERY.$VAR ...>, ...)
- pattern: |
$X.createReadStream(..., <... $REQ.$QUERY ...>, ...)
- pattern: |
$X.readFile(..., <... $REQ.$QUERY.$VAR ...>, ...)
- pattern: |
$X.readFile(..., <... $REQ.$QUERY ...>, ...)
- pattern: |
$X.readFileSync(..., <... $REQ.$QUERY.$VAR ...>, ...)
- pattern: |
$X.readFileSync(..., <... $REQ.$QUERY ...>, ...)
- pattern: |
$X.readFileAsync(..., <... $REQ.$QUERY.$VAR ...>, ...)
- pattern: |
$X.readFileAsync(..., <... $REQ.$QUERY ...>, ...)
- pattern: |
$INP = <... $REQ.$QUERY.$VAR ...>;
...
$X.createReadStream(..., <... $INP ...>, ...);
- pattern: |
$INP = <... $REQ.$QUERY ...>;
...
$X.createReadStream(..., <... $INP ...>, ...);
- pattern: |
$INP = <... $REQ.$QUERY.$VAR ...>;
...
$X.readFile(..., <... $INP ...>, ...);
- pattern: |
$INP = <... $REQ.$QUERY ...>;
...
$X.readFile(..., <... $INP ...>, ...);
- pattern: |
$INP = <... $REQ.$QUERY.$VAR ...>;
...
$X.readFileSync(..., <... $INP ...>, ...);
- pattern: |
$INP = <... $REQ.$QUERY ...>;
...
$X.readFileSync(..., <... $INP ...>, ...);
- pattern: |
$INP = <... $REQ.$QUERY.$VAR ...>;
...
$X.readFileAsync(..., <... $INP ...>, ...);
- pattern: |
$INP = <... $REQ.$QUERY ...>;
...
$X.readFileAsync(..., <... $INP ...>, ...);
- pattern: |
$Y = $REQ.$QUERY.$VAR;
...
$INP = <... $Y ...>;
...
$X.createReadStream(..., <... $INP ...>, ...);
- pattern: |
$Y = $REQ.$QUERY;
...
$INP = <... $Y ...>;
...
$X.createReadStream(..., <... $INP ...>, ...);
- pattern: |
$Y = $REQ.$QUERY.$VAR;
...
$INP = <... $Y ...>;
...
$X.readFile(..., <... $INP ...>, ...);
- pattern: |
$Y = $REQ.$QUERY;
...
$INP = <... $Y ...>;
...
$X.readFile(..., <... $INP ...>, ...);
- pattern: |
$Y = $REQ.$QUERY.$VAR;
...
$INP = <... $Y ...>;
...
$X.readFileSync(..., <... $INP ...>, ...);
- pattern: |
$Y = $REQ.$QUERY;
...
$INP = <... $Y ...>;
...
$X.readFileSync(..., <... $INP ...>, ...);
- pattern: |
$Y = $REQ.$QUERY.$VAR;
...
$INP = <... $Y ...>;
...
$X.readFileAsync(..., <... $INP ...>, ...);
- pattern: |
$Y = $REQ.$QUERY;
...
$INP = <... $Y ...>;
...
$X.readFileAsync(..., <... $INP ...>, ...);
message: Untrusted user input in readFile()/readFileSync() can endup in
Directory Traversal Attacks.
languages:
- javascript
severity: ERROR
metadata:
owasp: A05:2017 - Broken Access Control
cwe: "CWE-23: Relative Path Traversal"
category: security
technology:
- node.js
- express
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
Examples
path_traversal.js
var http = require('http'),
fileSystem = require('fs'),
path = require('path');
var config = require('../config');
var Promise = require('bluebird');
Promise.promisifyAll(fileSystem);
var express = require('express');
var app = express();
app.get('/', function (req, res) {
// ruleid:generic_path_traversal
var filePath = path.join(__dirname, '/' + req.query.load);
var readStream = fileSystem.createReadStream(filePath);
// ruleid:generic_path_traversal
fileSystem.readFile(req.query.foo);
// ruleid:generic_path_traversal
console.log(fileSystem.readFileSync(req.query.nar, 'utf8'));
// ruleid:generic_path_traversal
var foo = req.query.y;
fileSystem.readFile(foo);
fileSystem.readFile(foo + "bar");
readStream.pipe(res);
});
app.get('/foo', function (req, res) {
// ruleid:generic_path_traversal
var date = req.query.date;
var fileName = config.dirName + '/' + date;
var downloadFileName = 'log_' + fileName + '.txt';
fs.readFileAsync(fileName)
.then(function (data) {
res.download(fileName, downloadFileName);
})
})
app.listen(8888);
// do not match
fileSystem.readFile(ddd);
Short Link: https://sg.run/5QlK