python.lang.security.audit.dangerous-testcapi-run-in-subinterp-audit.dangerous-testcapi-run-in-subinterp-audit

profile photo of semgrepsemgrep
Author
unknown
Download Count*

Found dynamic content in run_in_subinterp. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. Ensure no external data reaches here.

Run Locally

Run in CI

Defintion

rules:
  - id: dangerous-testcapi-run-in-subinterp-audit
    patterns:
      - pattern-either:
          - pattern: |
              _testcapi.run_in_subinterp($PAYLOAD, ...)
          - pattern: |
              test.support.run_in_subinterp($PAYLOAD, ...)
      - pattern-not: |
          _testcapi.run_in_subinterp("...", ...)
      - pattern-not: |
          test.support.run_in_subinterp("...", ...)
    message: Found dynamic content in `run_in_subinterp`. This is dangerous if
      external data can reach this function call because it allows a malicious
      actor to run arbitrary Python code. Ensure no external data reaches here.
    metadata:
      cwe:
        - "CWE-95: Improper Neutralization of Directives in Dynamically
          Evaluated Code ('Eval Injection')"
      owasp:
        - A03:2021 - Injection
      references:
        - https://semgrep.dev/docs/cheat-sheets/python-command-injection/
      category: security
      technology:
        - python
      confidence: LOW
      subcategory:
        - audit
      likelihood: LOW
      impact: HIGH
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Code Injection
    severity: WARNING
    languages:
      - python

Examples

dangerous-testcapi-run-in-subinterp-audit.py

import _testcapi
from test import support

def run_payload1(payload: str) -> None:
    # ruleid: dangerous-testcapi-run-in-subinterp-audit
    _testcapi.run_in_subinterp(payload)

def run_payload2(payload: str) -> None:
    # ruleid: dangerous-testcapi-run-in-subinterp-audit
    support.run_in_subinterp(payload)

def okTest(payload: str) -> None:
    # ok: dangerous-testcapi-run-in-subinterp-audit
    _testcapi.run_in_subinterp("print('Hello world')")