Created
August 31, 2021 11:38
-
-
Save inkz/f9a1d321aa306826d1de6207b5affb45 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
rules: | |
- id: insecure-object-assign | |
mode: taint | |
message: | | |
Depending on the context, user control data in `Object.assign` can cause web response to include data that it should not have or can lead to a mass assignment vulnerability. | |
metadata: | |
cwe: "CWE-601: URL Redirection to Untrusted Site ('Open Redirect')" | |
owasp: 'A1: Injection' | |
references: | |
- https://nodesecroadmap.fyi/chapter-1/threat-EXF.html | |
- https://en.wikipedia.org/wiki/Mass_assignment_vulnerability | |
category: security | |
languages: | |
- javascript | |
- typescript | |
severity: WARNING | |
pattern-sources: | |
- patterns: | |
- pattern: JSON.parse(...) | |
- pattern-not: JSON.parse("...",...) | |
pattern-sinks: | |
- pattern: Object.assign(...) | |
- id: node-mssql-sqli | |
languages: | |
- js | |
- typescript | |
message: > | |
Detected string concatenation with a non-literal variable in a | |
node-postgres JS SQL statement. This could lead to SQL injection if the variable is user-controlled | |
and not properly sanitized. In order to prevent SQL injection, | |
used parameterized queries or prepared statements instead. | |
You can use parameterized statements like so: | |
`$REQ.query('SELECT $1 from table', [userinput])` | |
metadata: | |
category: security | |
license: Commons Clause License Condition v1.0[LGPL-2.1-only] | |
references: | |
- https://node-postgres.com/features/queries | |
patterns: | |
- pattern-inside: | | |
require('mssql') | |
... | |
- pattern-inside: | | |
$REQ = $POOL.request(...) | |
... | |
- pattern-either: | |
- patterns: | |
- pattern-either: | |
- pattern: | | |
$REQ.query($QUERY,...) | |
- pattern: | | |
$REQ.query($QUERY, ...).$INTFUNC(...) | |
- pattern-either: | |
- pattern-inside: | | |
$QUERY = $X + $Y | |
... | |
- pattern-inside: | | |
$QUERY += $X | |
... | |
- pattern-inside: | | |
$QUERY = $X.concat($Y) | |
... | |
- pattern-inside: | | |
$QUERY = `...${...}...` | |
... | |
- pattern-not-inside: | | |
$QUERY += "..." | |
... | |
- pattern-not-inside: | | |
$QUERY = "..." + "..." | |
... | |
- pattern-not-inside: | | |
$QUERY = $X.concat("...") | |
... | |
- pattern: $REQ.query($X + $Y, ...) | |
- pattern: $REQ.query($X.concat($Y), ...) | |
- pattern: $REQ.query(`...${...}...`, ...) | |
- pattern-not: $REQ.query("..." + "...", ...) | |
- pattern-not: $REQ.query($X.concat("..."), ...) | |
severity: WARNING | |
- id: code-string-concat | |
message: >- | |
User controlled data in eval() or similar functions may result in Code Injection | |
languages: | |
- javascript | |
- typescript | |
severity: WARNING | |
metadata: | |
owasp: 'A1: Injection' | |
cwe: "CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')" | |
category: security | |
technology: | |
- node.js | |
pattern-either: | |
- patterns: | |
- pattern-either: | |
- patterns: | |
- pattern: $STRING + $EXPR | |
- pattern-not: $STRING + "..." | |
- patterns: | |
- pattern: $EXPR + $STRING | |
- pattern-not: '"..." + $STRING' | |
- patterns: | |
- pattern: '[..., $STRING, ...].join(...)' | |
- patterns: | |
- pattern: $VAR += $STRING | |
- metavariable-regex: | |
metavariable: $STRING | |
regex: .*(function|Function|eval|\([^\(\)]*\)\s*=>).* | |
- patterns: | |
- pattern-inside: | | |
`...${...}...` | |
- pattern-regex: function|Function|eval|\([^\(\)]*\)\s*=> | |
- id: lazy-load-module | |
patterns: | |
- pattern: require(...) | |
- pattern-inside: | | |
function $NAME(...) { | |
... | |
} | |
message: | | |
Lazy loading can complicate code bundling if care is not taken, also `require`s are run synchronously by Node.js. | |
If they are called from within a function, it may block other requests from being handled at a more critical time. | |
The best practice is to `require` modules at the beginning of each file, before and outside of any functions. | |
languages: [js, ts] | |
severity: WARNING | |
metadata: | |
category: best-practice | |
references: | |
- https://nodesecroadmap.fyi/chapter-2/dynamism.html | |
- https://github.com/goldbergyoni/nodebestpractices#-38-require-modules-first-not-inside-functions | |
- id: express-data-exfiltration | |
mode: taint | |
message: | | |
Depending on the context, user control data in `Object.assign` can cause web response to include data that it should not have or can lead to a mass assignment vulnerability. | |
metadata: | |
cwe: 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' | |
references: | |
- https://nodesecroadmap.fyi/chapter-1/threat-EXF.html | |
- https://en.wikipedia.org/wiki/Mass_assignment_vulnerability | |
category: security | |
technology: | |
- express | |
languages: | |
- javascript | |
- typescript | |
severity: WARNING | |
pattern-sources: | |
- patterns: | |
- pattern-either: | |
- pattern-inside: function ... ($REQ, $RES) {...} | |
- pattern-inside: function ... ($REQ, $RES, $NEXT) {...} | |
- pattern-inside: $APP.get(..., function $FUNC($REQ, $RES) {...}) | |
- pattern-inside: $APP.post(..., function $FUNC($REQ, $RES) {...}) | |
- pattern-inside: $APP.put(..., function $FUNC($REQ, $RES) {...}) | |
- pattern-inside: $APP.head(..., function $FUNC($REQ, $RES) {...}) | |
- pattern-inside: $APP.delete(..., function $FUNC($REQ, $RES) {...}) | |
- pattern-inside: $APP.options(..., function $FUNC($REQ, $RES) {...}) | |
- pattern-either: | |
- pattern: $REQ | |
- pattern: $REQ.$QUERY | |
- pattern: $REQ.$BODY.$PARAM | |
pattern-sinks: | |
- pattern: Object.assign(...) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment