python.aws-lambda.security.dynamodb-filter-injection.dynamodb-filter-injection

profile photo of semgrepsemgrep
Author
unknown
Download Count*

Detected DynamoDB query filter that is tainted by $EVENT object. This could lead to NoSQL injection if the variable is user-controlled and not properly sanitized. Explicitly assign query params instead of passing data from $EVENT directly to DynamoDB client.

Run Locally

Run in CI

Defintion

rules:
  - id: dynamodb-filter-injection
    mode: taint
    metadata:
      cwe:
        - "CWE-943: Improper Neutralization of Special Elements in Data Query
          Logic"
      owasp:
        - A01:2017 - Injection
      category: security
      technology:
        - python
        - boto3
        - aws-lambda
        - dynamodb
      references:
        - https://medium.com/appsecengineer/dynamodb-injection-1db99c2454ac
      subcategory:
        - vuln
      impact: MEDIUM
      likelihood: MEDIUM
      confidence: MEDIUM
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Improper Validation
    message: Detected DynamoDB query filter that is tainted by `$EVENT` object. This
      could lead to NoSQL injection if the variable is user-controlled and not
      properly sanitized. Explicitly assign query params instead of passing data
      from `$EVENT` directly to DynamoDB client.
    pattern-sources:
      - patterns:
          - pattern: event
          - pattern-inside: |
              def $HANDLER(event, context):
                ...
    pattern-sanitizers:
      - patterns:
          - pattern: |
              {...}
    pattern-sinks:
      - patterns:
          - focus-metavariable: $SINK
          - pattern-either:
              - pattern: $TABLE.scan(..., ScanFilter = $SINK, ...)
              - pattern: $TABLE.query(..., QueryFilter = $SINK, ...)
          - pattern-either:
              - patterns:
                  - pattern-inside: |
                      $TABLE = $DB.Table(...)
                      ...
                  - pattern-inside: |
                      $DB = boto3.resource('dynamodb', ...)
                      ...
              - pattern-inside: |
                  $TABLE = boto3.client('dynamodb', ...)
                  ...
    severity: ERROR
    languages:
      - python

Examples

dynamodb-filter-injection.py

import boto3

def handler(event, context):
  dynamodb = boto3.resource('dynamodb')
  dynamodb_table = dynamodb.Table('Name')
  dynamodb_table.query(
    Select = 'ALL_ATTRIBUTES',
    # ruleid: dynamodb-filter-injection
    QueryFilter = event.body.filter
  )

  dynamodb_table.scan(
    Select = 'ALL_ATTRIBUTES', 
    # ok: dynamodb-filter-injection
    ScanFilter = {'first_name': event.body.name}
  )

def new_handler(event, context):
  client = boto3.client('dynamodb')

  client.scan(
    Select = 'ALL_ATTRIBUTES', 
    # ruleid: dynamodb-filter-injection
    ScanFilter = event.body.filter
  )

  client.query(
    Select = 'ALL_ATTRIBUTES', 
    # ok: dynamodb-filter-injection
    QueryFilter = {'first_name': event.body.name}
  )