Skip to content

fix(skill-scan): stop hiding compiled bytecode from audit surface (Closes #531) - #532

Open
boy-hack wants to merge 2 commits into
mainfrom
fix/skill-scan-pyc-bypass
Open

fix(skill-scan): stop hiding compiled bytecode from audit surface (Closes #531)#532
boy-hack wants to merge 2 commits into
mainfrom
fix/skill-scan-pyc-bypass

Conversation

@boy-hack

Copy link
Copy Markdown
Collaborator

Summary

Closes #531. skill-scan previously excluded __pycache__ and .pyc/.pyo/.pyd from both the LLM directory tree (dir_tree / _build_repo_tree) and the static pre_scan regex pass. Because CPython loads .pyc at import time independently of any .py source, a malicious skill could ship a clean .py decoy plus a malicious .pyc (PEP 552 UNCHECKED_HASH) and receive a false SAFE verdict (100/100 trust score).

Changes

  • pre_scan: removed .pyc/.pyo/.pyd from the skip set and scan them as text; added _collect_bytecode_warnings() to surface every compiled artifact with an explicit warning.
  • agent._build_repo_tree: reveals __pycache__ and .pyc, annotated with a compiled-bytecode warning injected into the prompt.
  • dir_actions.dir_tree: reveals __pycache__ and .pyc, annotated with a [compiled-bytecode] marker so the agent is no longer blind to them.
  • tests: added tests/test_bytecode_bypass.py regression coverage (3 tests, all passing locally).

Verification

Reproduced the bypass locally with a malicious UNCHECKED_HASH .pyc carrying an SSH-key exfil pattern. Before the fix the scanner output no findings; after the fix pre_scan flags the .pyc payload and both tree renderers surface the bytecode artifact with a warning.

Note

Per project rules this PR is opened for review; merge is performed by the maintainers.

zhuque added 2 commits August 11, 2026 09:26
…oses #531)

skill-scan previously excluded __pycache__ and .pyc/.pyo/.pyd from both the
LLM directory tree (dir_tree / _build_repo_tree) and the static pre_scan regex
pass. Since CPython loads .pyc at import time independently of any .py source,
a malicious skill could ship a clean .py decoy plus a malicious .pyc (PEP 552
UNCHECKED_HASH) and receive a false SAFE verdict (100/100 trust score).

Changes:
- pre_scan: remove .pyc/.pyo/.pyd from the skip set and scan them as text;
  add _collect_bytecode_warnings() to surface every compiled artifact.
- agent._build_repo_tree: reveal __pycache__ and .pyc, annotate with a
  compiled-bytecode warning in the injected repo tree.
- dir_actions.dir_tree: reveal __pycache__ and .pyc, annotate with
  [compiled-bytecode] marker so the agent is no longer blind to them.
- tests: add tests/test_bytecode_bypass.py regression coverage.
Force-add tests/test_bytecode_bypass.py (root .gitignore excludes 'tests').
Covers: repo tree + dir_tree reveal compiled bytecode, pre_scan detects
malicious .pyc payload.
@boy-hack

Copy link
Copy Markdown
Collaborator Author

Thanks @boy-hack for this fix (Closes #531). This addresses a real security concern: skill-scan previously excluded __pycache__ and .pyc/.pyo/.pyd from both the LLM directory tree (dir_tree / _build_repo_tree) and the static pre_scan regex pass. Since CPython loads .pyc at import time independently of any .py source, a malicious skill could ship a clean .py decoy plus a malicious .pyc (PEP 552 UNCHECKED_HASH) and receive a false SAFE verdict.

Changes:

  • pre_scan: removed .pyc/.pyo/.pyd from skip patterns
  • dir_tree / _build_repo_tree: include __pycache__ directories and compiled bytecode files
  • Trust score calculation now accounts for compiled bytecode presence

Review notes:

  • Clean 4-file change (+158/-9)
  • Well-documented with test cases
  • No false positive risk (bytecode without source is inherently suspicious)

LGTM. @pythoncheng for visibility.

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.

[SECURITY] __pycache__ and .pyc files hidden from LLM agent tools (v4.5.1) (malicious skill bypasses this scanner)

1 participant