python.lang.security.audit.dangerous-annotations-usage.dangerous-annotations-usage

profile photo of semgrepsemgrep
Author
1,829
Download Count*

Annotations passed to typing.get_type_hints are evaluated in globals and locals namespaces. Make sure that no arbitrary value can be written as the annotation and passed to typing.get_type_hints function.

Run Locally

Run in CI

Defintion

rules:
  - id: dangerous-annotations-usage
    patterns:
      - pattern: |
          $C.__annotations__[$NAME] = $X
      - pattern-not: |
          $C.__annotations__[$NAME] = "..."
      - pattern-not: |
          $C.__annotations__[$NAME] = typing.$Y
      - metavariable-regex:
          metavariable: $X
          regex: (?!(int|float|complex|list|tuple|range|str|bytes|bytearray|memoryview|set|frozenset|dict))
    message: Annotations passed to `typing.get_type_hints` are evaluated in
      `globals` and `locals` namespaces. Make sure that no arbitrary value can
      be written as the annotation and passed to `typing.get_type_hints`
      function.
    severity: INFO
    metadata:
      cwe:
        - "CWE-95: Improper Neutralization of Directives in Dynamically
          Evaluated Code ('Eval Injection')"
      owasp:
        - A03:2021 - Injection
      category: security
      references:
        - https://docs.python.org/3/library/typing.html#typing.get_type_hints
      technology:
        - python
      subcategory:
        - audit
      likelihood: LOW
      impact: LOW
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Code Injection
    languages:
      - python

Examples

dangerous-annotations-usage.py

from typing import List, Set, Dict, Tuple, Optional, get_type_hints

class C:
    member: int = 0

def smth(payload):
  # ruleid: dangerous-annotations-usage
  C.__annotations__["member"] = payload
  get_type_hints(C)

def ok1():
  # ok: dangerous-annotations-usage
  C.__annotations__["member"] = int
  get_type_hints(C)

def ok2():
  # ok: dangerous-annotations-usage
  C.__annotations__["member"] = List
  get_type_hints(C)