Skip to content

Improve security of handling pyc files#623

Merged
danieldk merged 2 commits into
mainfrom
pycache-security
Jun 6, 2026
Merged

Improve security of handling pyc files#623
danieldk merged 2 commits into
mainfrom
pycache-security

Conversation

@danieldk

@danieldk danieldk commented Jun 5, 2026

Copy link
Copy Markdown
Member

We cannot consider pyc files in digest, because they are generated by the interpreter and are not static. However, a blanket ignore of pyc files in hashing can allow an attacker to smuggle in a malicious pyc file. Tighten up security in the following way:

  • Never download .pyc files or __pycache__ directories. This ensures that we are only downloading files that are covered by the digest.
  • When hashing files, exclude __pycache__, since these are locally generated.
  • When hashing files, do not exclude pyc files, since the Python interpreter does not generate them outside __pycache__. The first mitigation should cover this case, but let's include them in hashing to be extra paranoid.

We cannot consider pyc files in digest, because they are generated by
the interpreter and are not static. However, a blanket ignore of pyc
files in hashing can allow an attacker to smuggle in a malicious pyc
file. Tighten up security in the following way:

- Never download `.pyc` files or `__pycache__` directories. This
  ensures that we are only downloading files that are covered by the
  digest.
- When hashing files, exclude `__pycache__`, since these are locally
  generated.
- When hashing files, do not exclude `pyc` files, since the Python
  interpreter does not generate them outside `__pycache__`. The first
  mitigation should cover this case, but let's include them in hashing
  to be extra paranoid.
@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

sayakpaul
sayakpaul previously approved these changes Jun 5, 2026
fs::write(pycache_dir.join("mod.cpython-311.pyc"), b"bytecode")?;
// A .pyc outside __pycache__/ must be included — it was not generated
// locally by Python and should be covered by the digest.
fs::write(dir.path().join("payload.pyc"), b"smuggled")?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"smuggled" 🤪

Since we now do not download .pyc/__pycache__, also do not include them
in lockfile calculations.
@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

Coverage report — kernels/

Measured on: Python 3.10 / Torch 2.12.0.
Other CI configurations are not included in this number.
Hardware-gated code paths (ROCm/XPU/NPU/Darwin/Windows) are excluded or unreachable on the Linux+CUDA runner.

Total coverage: 83.3% — threshold: 80% — ✅

Per-file breakdown
Name Stmts Miss Cover Missing
src/kernels/__init__.py 10 0 100%
src/kernels/_system.py 6 1 83% 10
src/kernels/_versions.py 63 7 89% 46, 49, 52-53, 56-57, 100
src/kernels/backends.py 194 55 72% 40, 44, 48-51, 68, 90, 108, 117, 121, 125-127, 148, 170, 181, 188-191, 201, 205-225, 233, 256-276
src/kernels/compat.py 8 1 88% 5
src/kernels/deps.py 54 4 93% 58-59, 95, 98
src/kernels/layer/__init__.py 6 0 100%
src/kernels/layer/_interval_tree.py 103 4 96% 23, 52, 147, 150
src/kernels/layer/device.py 48 14 71% 42, 47-49, 91, 96-98, 101, 149, 152, 155-157
src/kernels/layer/func.py 93 7 92% 72, 100, 154, 257, 263, 272, 290
src/kernels/layer/globals.py 5 0 100%
src/kernels/layer/kernelize.py 73 8 89% 255, 273, 281-282, 288, 292, 308-310
src/kernels/layer/layer.py 174 15 91% 166, 209, 215, 228, 320-321, 333, 342, 350, 361, 390, 394, 407, 460, 490
src/kernels/layer/mode.py 14 0 100%
src/kernels/layer/repos.py 130 34 74% 27, 33, 36-41, 61-62, 68, 71-74, 88, 92, 101-102, 108, 111-114, 121-122, 128, 131-134, 141-142, 148, 151-154, 235
src/kernels/lockfile.py 71 46 35% 37-101, 105-128
src/kernels/status.py 49 2 96% 23, 81
src/kernels/utils.py 300 60 80% 59, 71-75, 81-82, 211, 215, 218, 280, 288, 327-328, 366, 397, 402, 437, 618-623, 653, 656, 658, 664, 677-678, 699-711, 715-722, 730, 734-744, 748-755, 793, 797, 816, 818
src/kernels/variants.py 262 19 93% 56, 87, 108, 138, 247-248, 289, 291, 371-378, 384-390, 421-427, 439-445, 534-536
TOTAL 1663 277 83%

Updated by the Test kernels workflow on commit 543fe803866fc03dcc2ee1d5cb8f953a749d50ef.

@danieldk danieldk merged commit 0b3c8f4 into main Jun 6, 2026
54 checks passed
@danieldk danieldk deleted the pycache-security branch June 6, 2026 14:08
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.

3 participants