javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection

profile photo of semgrepsemgrep
Author
unknown
Download Count*

Detected a sequelize statement that is tainted by user-input. This could lead to SQL injection if the variable is user-controlled and is not properly sanitized. In order to prevent SQL injection, it is recommended to use parameterized queries or prepared statements.

Run Locally

Run in CI

Defintion

rules:
  - id: express-sequelize-injection
    message: Detected a sequelize statement that is tainted by user-input. This
      could lead to SQL injection if the variable is user-controlled and is not
      properly sanitized. In order to prevent SQL injection, it is recommended
      to use parameterized queries or prepared statements.
    options:
      interfile: true
    metadata:
      interfile: true
      references:
        - https://sequelize.org/docs/v6/core-concepts/raw-queries/#replacements
      category: security
      technology:
        - express
      cwe:
        - "CWE-89: Improper Neutralization of Special Elements used in an SQL
          Command ('SQL Injection')"
      owasp:
        - A01:2017 - Injection
        - A03:2021 - Injection
      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]
      vulnerability_class:
        - SQL Injection
    languages:
      - javascript
      - typescript
    severity: ERROR
    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: sequelize.query($QUERY,...)
                  - pattern: $DB.sequelize.query($QUERY,...)
              - focus-metavariable: $QUERY
    pattern-sanitizers:
      - pattern-either:
          - pattern: parseInt(...)
          - pattern: $FUNC. ... .hash(...)

Examples

sequelize-injection-express.ts

import m = require('../m/index')
import { Request, Response, NextFunction } from 'express'

module.exports = function search () {
  return (req: Request, res: Response, next: NextFunction) => {
    let criteria = req.query.foo
    // ok: express-sequelize-injection
    m.sequelize.query(
      'SELECT * FROM projects WHERE status = ?',
      {
        replacements: [req.body.foo],
        type: QueryTypes.SELECT
      }
    )
    // ok: express-sequelize-injection
    m.sequelize.query(
      'SELECT * FROM projects WHERE status = ?',
      {
        replacements: [req.body.foo],
        type: QueryTypes.SELECT
      }
    )
    let obj =  {
        replacements: [req.body.foo],
        type: QueryTypes.SELECT
      }
    // ok: express-sequelize-injection
    let projects = 'projects'
      sequelize.query(
        `SELECT * FROM ${projects} WHERE status = ?`,
        obj
      )
    // ruleid: express-sequelize-injection
    m.sequelize.query(`SELECT * FROM Foo WHERE ((criteria LIKE '%${criteria}%))`) 
    // ruleid: express-sequelize-injection
    sequelize.query(`SELECT * FROM Foo WHERE ((criteria LIKE '%${obj.replacements[0]}%))`) 
  }
}