javascript.express.security.audit.express-third-party-object-deserialization.express-third-party-object-deserialization

Author
unknown
Download Count*
License
The following function call $SER.$FUNC accepts user controlled data which can result in Remote Code Execution (RCE) through Object Deserialization. It is recommended to use secure data processing alternatives such as JSON.parse() and Buffer.from().
Run Locally
Run in CI
Defintion
rules:
- id: express-third-party-object-deserialization
message: The following function call $SER.$FUNC accepts user controlled data
which can result in Remote Code Execution (RCE) through Object
Deserialization. It is recommended to use secure data processing
alternatives such as JSON.parse() and Buffer.from().
metadata:
interfile: true
technology:
- express
category: security
cwe:
- "CWE-502: Deserialization of Untrusted Data"
references:
- https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
source_rule_url:
- https://github.com/ajinabraham/njsscan/blob/75bfbeb9c8d72999e4d527dfa2548f7f0f3cc48a/njsscan/rules/semantic_grep/eval/eval_deserialize.yaml
owasp:
- A08:2017 - Insecure Deserialization
- A08:2021 - Software and Data Integrity Failures
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- vuln
likelihood: HIGH
impact: HIGH
confidence: HIGH
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
languages:
- javascript
- typescript
severity: WARNING
mode: taint
pattern-sources:
- patterns:
- pattern-either:
- pattern-inside: function ... ($REQ, $RES) {...}
- pattern-inside: function ... ($REQ, $RES, $NEXT) {...}
- patterns:
- pattern-either:
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...})
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})
- metavariable-regex:
metavariable: $METHOD
regex: ^(get|post|put|head|delete|options)$
- pattern-either:
- pattern: $REQ.query
- pattern: $REQ.body
- pattern: $REQ.params
- pattern: $REQ.cookies
- pattern: $REQ.headers
- pattern: $REQ.files.$ANYTHING.data.toString('utf8')
- pattern: $REQ.files.$ANYTHING['data'].toString('utf8')
- patterns:
- pattern-either:
- pattern-inside: |
({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>
{...}
- pattern-inside: |
({ $REQ }: Request,$RES: Response) => {...}
- focus-metavariable: $REQ
- pattern-either:
- pattern: params
- pattern: query
- pattern: cookies
- pattern: headers
- pattern: body
- pattern: files.$ANYTHING.data.toString('utf8')
- pattern: files.$ANYTHING['data'].toString('utf8')
pattern-sinks:
- pattern-either:
- patterns:
- pattern-either:
- pattern-inside: |
$SER = require('$IMPORT')
...
- pattern-inside: |
import $SER from '$IMPORT'
...
- pattern-inside: |
import * as $SER from '$IMPORT'
...
- metavariable-regex:
metavariable: $IMPORT
regex: ^(node-serialize|serialize-to-js)$
- pattern: $SER.$FUNC(...)
- metavariable-regex:
metavariable: $FUNC
regex: ^(unserialize|deserialize)$
Examples
express-third-party-object-deserialization.ts
var node_serialize = require("node-serialize")
var serialize_to_js = require('serialize-to-js');
module.exports.value = function (req,res){
// ruleid: express-third-party-object-deserialization
node_serialize.unserialize(req.files.products.data.toString('utf8'))
// ok: express-third-party-object-deserialization
fake.unserialize(req.files)
}
module.exports.value1 = function (req,res){
var str = new Buffer(req.cookies.profile, 'base64').toString();
// ruleid: express-third-party-object-deserialization
serialize_to_js.deserialize(str)
// ok: express-third-party-object-deserialization
foo.deserialize(str)
}
Short Link: https://sg.run/8W5j