javascript.lang.security.audit.detect-non-literal-fs-filename.detect-non-literal-fs-filename
semgrep
Author
745
Download Count*
License
Detected that function argument $ARG
has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are validated.
Run Locally
Run in CI
Defintion
rules:
- id: detect-non-literal-fs-filename
message: Detected that function argument `$ARG` has entered the fs module. An
attacker could potentially control the location of this file, to include
going backwards in the directory with '../'. To address this, ensure that
user-controlled variables in file paths are validated.
metadata:
cwe:
- "CWE-22: Improper Limitation of a Pathname to a Restricted Directory
('Path Traversal')"
references:
- https://owasp.org/www-community/attacks/Path_Traversal
owasp:
- A05:2017 - Broken Access Control
- A01:2021 - Broken Access Control
source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-non-literal-fs-filename.js
category: security
technology:
- typescript
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- vuln
likelihood: HIGH
impact: MEDIUM
confidence: LOW
vulnerability_class:
- Path Traversal
languages:
- typescript
- javascript
severity: WARNING
mode: taint
pattern-sources:
- patterns:
- pattern-inside: function ... (..., $ARG,...) {...}
- focus-metavariable: $ARG
pattern-sinks:
- patterns:
- pattern-either:
- pattern-inside: |
$FS = require('fs')
...
- pattern-inside: |
$FS = require('fs/promises')
...
- pattern-inside: |
import * as $FS from 'fs'
...
- pattern-inside: |
import $FS from 'fs'
...
- pattern-inside: |
import * as $FS from 'fs/promises'
...
- pattern-inside: |
import $FS from 'fs/promises'
...
- pattern-not: $FS. ... .$METHOD("...", ...)
- pattern-either:
- pattern: $FS. ... .access($FILE,...)
- pattern: $FS. ... .appendFile($FILE,...)
- pattern: $FS. ... .chmod($FILE,...)
- pattern: $FS. ... .chown($FILE,...)
- pattern: $FS. ... .close($FILE,...)
- pattern: $FS. ... .copyFile($FILE,...)
- pattern: $FS. ... .copyFile($SMTH, $FILE,...)
- pattern: $FS. ... .cp($FILE, ...)
- pattern: $FS. ... .cp($SMTH, $FILE, ...)
- pattern: $FS. ... .createReadStream($FILE,...)
- pattern: $FS. ... .createWriteStream($FILE,...)
- pattern: $FS. ... .exists($FILE, ...)
- pattern: $FS. ... .fchmod($FILE, ...)
- pattern: $FS. ... .fchown($FILE, ...)
- pattern: $FS. ... .fdatasync($FILE, ...)
- pattern: $FS. ... .fstat($FILE, ...)
- pattern: $FS. ... .fsync($FILE, ...)
- pattern: $FS. ... .ftruncate($FILE, ...)
- pattern: $FS. ... .futimes($FILE, ...)
- pattern: $FS. ... .lchmod($FILE, ...)
- pattern: $FS. ... .lchown($FILE, ...)
- pattern: $FS. ... .lutimes($FILE, ...)
- pattern: $FS. ... .link($FILE, ...)
- pattern: $FS. ... .link($SMTH, $FILE, ...)
- pattern: $FS. ... .lstat($FILE, ...)
- pattern: $FS. ... .mkdir($FILE, ...)
- pattern: $FS. ... .mkdtemp($FILE, ...)
- pattern: $FS. ... .open($FILE, ...)
- pattern: $FS. ... .opendir($FILE, ...)
- pattern: $FS. ... .read($FILE, ...)
- pattern: $FS. ... .read($FILE, ...)
- pattern: $FS. ... .readdir($FILE, ...)
- pattern: $FS. ... .readFile($FILE, ...)
- pattern: $FS. ... .readlink($FILE, ...)
- pattern: $FS. ... .readv($FILE, ...)
- pattern: $FS. ... .realpath($FILE, ...)
- pattern: $FS. ... .realpath.native($FILE, ...)
- pattern: $FS. ... .rename($FILE, ...)
- pattern: $FS. ... .rename($SMTH, $FILE, ...)
- pattern: $FS. ... .rmdir($FILE, ...)
- pattern: $FS. ... .rm($FILE, ...)
- pattern: $FS. ... .stat($FILE, ...)
- pattern: $FS. ... .symlink($SMTH, $FILE, ...)
- pattern: $FS. ... .symlink($FILE, ...)
- pattern: $FS. ... .truncate($FILE, ...)
- pattern: $FS. ... .unlink($FILE, ...)
- pattern: $FS. ... .unwatchFile($FILE, ...)
- pattern: $FS. ... .utimes($FILE, ...)
- pattern: $FS. ... .watch($FILE, ...)
- pattern: $FS. ... .watchFile($FILE, ...)
- pattern: $FS. ... .write($FILE, ...)
- pattern: $FS. ... .writeFile($FILE, ...)
- pattern: $FS. ... .writev($FILE, ...)
- pattern: $FS. ... .accessSync($FILE, ...)
- pattern: $FS. ... .appendFileSync($FILE, ...)
- pattern: $FS. ... .chmodSync($FILE, ...)
- pattern: $FS. ... .chownSync($FILE, ...)
- pattern: $FS. ... .closeSync($FILE, ...)
- pattern: $FS. ... .copyFileSync($FILE, ...)
- pattern: $FS. ... .copyFileSync($SMTH, $FILE, ...)
- pattern: $FS. ... .cpSync($FILE, ...)
- pattern: $FS. ... .cpSync($SMTH, $FILE, ...)
- pattern: $FS. ... .existsSync($FILE, ...)
- pattern: $FS. ... .fchmodSync($FILE, ...)
- pattern: $FS. ... .fchownSync($FILE, ...)
- pattern: $FS. ... .fdatasyncSync($FILE, ...)
- pattern: $FS. ... .fstatSync($FILE, ...)
- pattern: $FS. ... .fsyncSync($FILE, ...)
- pattern: $FS. ... .ftruncateSync($FILE, ...)
- pattern: $FS. ... .futimesSync($FILE, ...)
- pattern: $FS. ... .lchmodSync($FILE, ...)
- pattern: $FS. ... .lchownSync($FILE, ...)
- pattern: $FS. ... .lutimesSync($FILE, ...)
- pattern: $FS. ... .linkSync($FILE, ...)
- pattern: $FS. ... .linkSync($SMTH, $FILE, ...)
- pattern: $FS. ... .lstatSync($FILE, ...)
- pattern: $FS. ... .mkdirSync($FILE, ...)
- pattern: $FS. ... .mkdtempSync($FILE, ...)
- pattern: $FS. ... .opendirSync($FILE, ...)
- pattern: $FS. ... .openSync($FILE, ...)
- pattern: $FS. ... .readdirSync($FILE, ...)
- pattern: $FS. ... .readFileSync($FILE, ...)
- pattern: $FS. ... .readlinkSync($FILE, ...)
- pattern: $FS. ... .readSync($FILE, ...)
- pattern: $FS. ... .readSync($FILE, ...)
- pattern: $FS. ... .readvSync($FILE, ...)
- pattern: $FS. ... .realpathync($FILE, ...)
- pattern: $FS. ... .realpathSync.native($FILE, ...)
- pattern: $FS. ... .renameSync($FILE, ...)
- pattern: $FS. ... .renameSync($SMTH, $FILE, ...)
- pattern: $FS. ... .rmdirSync($FILE, ...)
- pattern: $FS. ... .rmSync($FILE, ...)
- pattern: $FS. ... .statSync($FILE, ...)
- pattern: $FS. ... .symlinkSync($FILE, ...)
- pattern: $FS. ... .symlinkSync($SMTH, $FILE, ...)
- pattern: $FS. ... .truncateSync($FILE, ...)
- pattern: $FS. ... .unlinkSync($FILE, ...)
- pattern: $FS. ... .utimesSync($FILE, ...)
- pattern: $FS. ... .writeFileSync($FILE, ...)
- pattern: $FS. ... .writeSync($FILE, ...)
- pattern: $FS. ... .writevSync($FILE, ...)
- focus-metavariable: $FILE
- patterns:
- pattern-either:
- pattern-inside: |
import 'fs'
...
- pattern-inside: |
import 'fs/promises'
...
- pattern-not: $METHOD("...", ...)
- pattern-either:
- pattern: access($FILE,...)
- pattern: appendFile($FILE,...)
- pattern: chmod($FILE,...)
- pattern: chown($FILE,...)
- pattern: close($FILE,...)
- pattern: copyFile($FILE,...)
- pattern: copyFile($SMTH, $FILE,...)
- pattern: cp($FILE, ...)
- pattern: cp($SMTH, $FILE, ...)
- pattern: createReadStream($FILE,...)
- pattern: createWriteStream($FILE,...)
- pattern: exists($FILE, ...)
- pattern: fchmod($FILE, ...)
- pattern: fchown($FILE, ...)
- pattern: fdatasync($FILE, ...)
- pattern: fstat($FILE, ...)
- pattern: fsync($FILE, ...)
- pattern: ftruncate($FILE, ...)
- pattern: futimes($FILE, ...)
- pattern: lchmod($FILE, ...)
- pattern: lchown($FILE, ...)
- pattern: lutimes($FILE, ...)
- pattern: link($FILE, ...)
- pattern: link($SMTH, $FILE, ...)
- pattern: lstat($FILE, ...)
- pattern: mkdir($FILE, ...)
- pattern: mkdtemp($FILE, ...)
- pattern: open($FILE, ...)
- pattern: opendir($FILE, ...)
- pattern: read($FILE, ...)
- pattern: read($FILE, ...)
- pattern: readdir($FILE, ...)
- pattern: readFile($FILE, ...)
- pattern: readlink($FILE, ...)
- pattern: readv($FILE, ...)
- pattern: realpath($FILE, ...)
- pattern: realpath.native($FILE, ...)
- pattern: rename($FILE, ...)
- pattern: rename($SMTH, $FILE, ...)
- pattern: rmdir($FILE, ...)
- pattern: rm($FILE, ...)
- pattern: stat($FILE, ...)
- pattern: symlink($SMTH, $FILE, ...)
- pattern: symlink($FILE, ...)
- pattern: truncate($FILE, ...)
- pattern: unlink($FILE, ...)
- pattern: unwatchFile($FILE, ...)
- pattern: utimes($FILE, ...)
- pattern: watch($FILE, ...)
- pattern: watchFile($FILE, ...)
- pattern: write($FILE, ...)
- pattern: writeFile($FILE, ...)
- pattern: writev($FILE, ...)
- pattern: accessSync($FILE, ...)
- pattern: appendFileSync($FILE, ...)
- pattern: chmodSync($FILE, ...)
- pattern: chownSync($FILE, ...)
- pattern: closeSync($FILE, ...)
- pattern: copyFileSync($FILE, ...)
- pattern: copyFileSync($SMTH, $FILE, ...)
- pattern: cpSync($FILE, ...)
- pattern: cpSync($SMTH, $FILE, ...)
- pattern: existsSync($FILE, ...)
- pattern: fchmodSync($FILE, ...)
- pattern: fchownSync($FILE, ...)
- pattern: fdatasyncSync($FILE, ...)
- pattern: fstatSync($FILE, ...)
- pattern: fsyncSync($FILE, ...)
- pattern: ftruncateSync($FILE, ...)
- pattern: futimesSync($FILE, ...)
- pattern: lchmodSync($FILE, ...)
- pattern: lchownSync($FILE, ...)
- pattern: lutimesSync($FILE, ...)
- pattern: linkSync($FILE, ...)
- pattern: linkSync($SMTH, $FILE, ...)
- pattern: lstatSync($FILE, ...)
- pattern: mkdirSync($FILE, ...)
- pattern: mkdtempSync($FILE, ...)
- pattern: opendirSync($FILE, ...)
- pattern: openSync($FILE, ...)
- pattern: readdirSync($FILE, ...)
- pattern: readFileSync($FILE, ...)
- pattern: readlinkSync($FILE, ...)
- pattern: readSync($FILE, ...)
- pattern: readSync($FILE, ...)
- pattern: readvSync($FILE, ...)
- pattern: realpathync($FILE, ...)
- pattern: realpathSync.native($FILE, ...)
- pattern: renameSync($FILE, ...)
- pattern: renameSync($SMTH, $FILE, ...)
- pattern: rmdirSync($FILE, ...)
- pattern: rmSync($FILE, ...)
- pattern: statSync($FILE, ...)
- pattern: symlinkSync($FILE, ...)
- pattern: symlinkSync($SMTH, $FILE, ...)
- pattern: truncateSync($FILE, ...)
- pattern: unlinkSync($FILE, ...)
- pattern: utimesSync($FILE, ...)
- pattern: writeFileSync($FILE, ...)
- pattern: writeSync($FILE, ...)
- pattern: writevSync($FILE, ...)
- focus-metavariable: $FILE
Examples
detect-non-literal-fs-filename.js
const {readFile} = require('fs/promises')
const fs = require('fs')
function test1(fileName) {
// ruleid:detect-non-literal-fs-filename
readFile(fileName)
.then((resolve, reject) => {
foobar()
})
}
async function test2(fileName) {
// ruleid:detect-non-literal-fs-filename
const data = await fs.promises.mkdir(fileName, {})
foobar(data)
}
function test3(fileName) {
const data = new Uint8Array(Buffer.from('Hello Node.js'));
// ruleid:detect-non-literal-fs-filename
fs.writeFile(fileName, data, (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
}
function okTest1(data) {
const data = new Uint8Array(Buffer.from('Hello Node.js'));
// ok:detect-non-literal-fs-filename
fs.writeFile('message.txt', data, (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
}
async function okTest2() {
let filehandle;
try {
// ok:detect-non-literal-fs-filename
filehandle = await fs.promises.open('thefile.txt', 'r');
} finally {
if (filehandle !== undefined)
await filehandle.close();
}
}
async function okTest3() {
let filehandle;
try {
// ok:detect-non-literal-fs-filename
filehandle = await this.open();
} finally {
if (filehandle !== undefined)
await filehandle.close();
}
}
detect-non-literal-fs-filename.ts
import * as fs from 'fs/promises';
import {readFile} from 'fs';
function test1(fileName) {
// ruleid:detect-non-literal-fs-filename
readFile(fileName)
.then((resolve, reject) => {
foobar()
})
}
async function test2(fileName) {
// ruleid:detect-non-literal-fs-filename
const data = await fs.promises.mkdir(fileName, {})
foobar(data)
}
function test3(fileName) {
const data = new Uint8Array(Buffer.from('Hello Node.js'));
// ruleid:detect-non-literal-fs-filename
fs.writeFile(fileName, data, (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
}
function okTest1(data) {
const data = new Uint8Array(Buffer.from('Hello Node.js'));
// ok:detect-non-literal-fs-filename
fs.writeFile('message.txt', data, (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
}
async function okTest2() {
let filehandle;
try {
// ok:detect-non-literal-fs-filename
filehandle = await fs.promises.open('thefile.txt', 'r');
} finally {
if (filehandle !== undefined)
await filehandle.close();
}
}
async function okTest3() {
let filehandle;
try {
// ok:detect-non-literal-fs-filename
filehandle = await this.open();
} finally {
if (filehandle !== undefined)
await filehandle.close();
}
}
Short Link: https://sg.run/8RNQ