Files
zeekay bc4ddf332b chore: rebase the tree onto upstream master fa1a9a60
Mechanically re-derived: bin/debrand runs over a fresh import of
posthog/posthog@fa1a9a60d4 (2026-08-06).
The pipeline (.hanzo/workflows), the Dockerfiles and bin/docker*
entrypoints, compose files, LLM.md and the squashed initial migration
are restored from the shipped tree, same as the previous import.

The prune's import-closure guard kept 21 products the new core now
imports; dropping them is a refactor now, recorded rather than forced.
2026-08-06 01:25:36 -07:00

34 lines
1.5 KiB
YAML

rules:
- id: orm-field-injection
languages: [python]
severity: ERROR
message: |
ORM field injection risk: a variable is interpolated into a dict key
passed to .filter()/.exclude()/Q(). If the variable is user-controlled,
an attacker can use Django's __ notation to traverse FK relationships
and exfiltrate sensitive fields (e.g. user__password, team__api_token).
Fix: validate the variable against an allowlist of permitted field names
before using it in the ORM lookup. Anchoring the path on a JSONField is not
enough on its own: Django still resolves the last segment as a lookup, so a
path like detail__<var> or detail__key__<var> lets the caller pick the
operation (e.g. regex, which runs an attacker-supplied Postgres regular
expression over every row). Validate every segment, including the last.
Suppress with: # nosemgrep: orm-field-injection <reason>
patterns:
- pattern-either:
- pattern: '$QS.filter(**{f"...{$VAR}...": ...})'
- pattern: '$QS.exclude(**{f"...{$VAR}...": ...})'
- pattern: 'Q(**{f"...{$VAR}...": ...})'
metadata:
category: security
subcategory: [vuln]
cwe: 'CWE-943: Improper Neutralization of Special Elements in Data Query Logic'
confidence: MEDIUM
paths:
exclude:
- '**/test/**'
- '**/tests/**'
- '**/.semgrep/**'