javascript.express.security.express-data-exfiltration.express-data-exfiltration

profile photo of semgrepsemgrep
Author
445
Download Count*

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.

Run Locally

Run in CI

Defintion

rules:
  - id: express-data-exfiltration
    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:
      owasp:
        - A08:2021 - Software and Data Integrity Failures
      cwe:
        - "CWE-915: Improperly Controlled Modification of Dynamically-Determined
          Object Attributes"
      references:
        - https://en.wikipedia.org/wiki/Mass_assignment_vulnerability
        - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html
      category: security
      technology:
        - express
      subcategory:
        - audit
      likelihood: LOW
      impact: MEDIUM
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Mass Assignment
    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
      - 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-sinks:
      - pattern: Object.assign(...)

Examples

express-data-exfiltration.js

const express = require('express')
const app = express()
const port = 3000

function testController1(req, res) {
    try {
        const defaultData = {foo: true}
        // ruleid: express-data-exfiltration
        let data = Object.assign(defaultData, req.query)
        doSmthWith(data)
    } catch (err) {
        this.log.error(err);
    }
    res.end('ok')
};
app.get('/test1', testController1)

let testController2 = function (req, res) {
    const defaultData = {foo: {bar: true}}
    // ruleid: express-data-exfiltration
    let data = Object.assign(defaultData, {foo: req.query})
    doSmthWith(data)
    return res.send({ok: true})

}
app.get('/test2', testController2)

var testController3 = null;
testController3 = function (req, res) {
    const defaultData = {foo: true}
    let newData = req.body
    // ruleid: express-data-exfiltration
    let data = Object.assign(defaultData, newData)
    doSmthWith(data)
    return res.send({ok: true})
}
app.get('/test3', testController3)

app.get('/ok-test', (req, res) => {
    const defaultData = {foo: req.body.foo}
    let newData = {bar: '123'}
    // ruleid: express-data-exfiltration
    let data = Object.assign(defaultData, newData)
    doSmthWith(data)
    return res.send(func())
})

let okController = function (req, res) {
    const defaultData = {foo: {bar: true}}
    // ok: express-data-exfiltration
    let data = Object.assign(defaultData, {foo: getFoo()})
    doSmthWith(data)
    return res.send({ok: true})
}
app.get('/ok-test2', okController)

app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))