mirror of
https://github.com/hanzoai/insights.git
synced 2026-11-03 00:52:32 +00:00
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.
34 lines
1.5 KiB
YAML
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/**'
|