javascript.aws-lambda.security.pg-sqli.pg-sqli

profile photo of semgrepsemgrep
Author
unknown
Download Count*

Detected SQL statement that is tainted by $EVENT object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: connection.query('SELECT $1 from table', [userinput])

Run Locally

Run in CI

Defintion

rules:
  - id: pg-sqli
    message: "Detected SQL statement that is tainted by `$EVENT` object. This could
      lead to SQL injection if the variable is user-controlled and not properly
      sanitized. In order to prevent SQL injection, use parameterized queries or
      prepared statements instead. You can use parameterized statements like so:
      `connection.query('SELECT $1 from table', [userinput])`"
    metadata:
      references:
        - https://node-postgres.com/features/queries
      category: security
      owasp:
        - A01:2017 - Injection
        - A03:2021 - Injection
      cwe:
        - "CWE-89: Improper Neutralization of Special Elements used in an SQL
          Command ('SQL Injection')"
      technology:
        - aws-lambda
        - postgres
        - pg
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - vuln
      likelihood: MEDIUM
      impact: HIGH
      confidence: MEDIUM
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - SQL Injection
    languages:
      - javascript
      - typescript
    severity: WARNING
    mode: taint
    pattern-sources:
      - patterns:
          - pattern-either:
              - pattern-inside: |
                  exports.handler = function ($EVENT, ...) {
                    ...
                  }
              - pattern-inside: |
                  function $FUNC ($EVENT, ...) {...}
                  ...
                  exports.handler = $FUNC
              - pattern-inside: |
                  $FUNC = function ($EVENT, ...) {...}
                  ...
                  exports.handler = $FUNC
          - pattern: $EVENT
    pattern-sinks:
      - patterns:
          - focus-metavariable: $QUERY
          - pattern-either:
              - pattern: $DB.query($QUERY, ...)
          - pattern-either:
              - pattern-inside: |
                  require('pg')
                  ...
              - pattern-inside: |
                  import 'pg'
                  ...

Examples

pg-sqli.js

let response;

const prettyPrint = (ob) => JSON.stringify(ob, null, 2).replace('\'','');
const timestamp = () => new Date();

const toBase64 = (msg) => Buffer.from(msg).toString('base64');

const { Client } = require('pg');
exports.handler = async function (event, context) {
  console.log("the event");
  console.log(event);

  const client = new Client({
    user: "test",
    host: "db",
    database: "nockslots",
    password: "test",
    port: 5432,
  });

  console.log("connecting to db...");

  await client.connect();

  records = [];
  event.Records.forEach((record) => {
    const { body } = record;
    console.log(body);
    records.push(toBase64(body));
  });

  const query = `INSERT INTO public.messages (body, encoded_message) VALUES ('${prettyPrint(event)}', '${records[0]}');`;

  console.log('the query:');
  console.log(query);

  try {
    console.log("Trying the query...");
    // ruleid: pg-sqli
    await client.query(query)
    // ok: pg-sqli
    await client.query('INSERT INTO messages (body, message) VALUES ($1, $2);', [prettyPrint(event), records[0]])
    await client.end();
  } catch (error) {
    console.log('Could not add row to postgres, soz');
    console.log(error);
  }

  return { key: JSON.stringify(records) };
};