lote.guide
esc
  • npm lifecycle scriptsscripts field in package.jsonNode.js
  • setup.py arbitrary code executionsetup.py in source distributions (sdist)Python
  • NODE_OPTIONS preload injectionNODE_OPTIONS environment variable, CLI flags, or .env files loaded via --env-fileNode.js
  • .pth file import execution*.pth files on sys.path (commonly site-packages)Python
  • binding.gyp / node-gyp native compilationbinding.gyp file in the package rootNode.js
  • Corepack (packageManager field)"packageManager" field in package.json, COREPACK_HOME cache directoryNode.js
  • .npmrc registry manipulation.npmrc file (project, user, or global)Node.js
  • overrides / resolutions dependency swapoverrides (npm) or resolutions (Yarn) field in package.jsonNode.js
  • pnpm hooks (pnpmfile.cjs).pnpmfile.cjs in the project rootNode.js
  • .yarnrc.yml plugins and registry.yarnrc.yml in the project rootNode.js
  • pyproject.toml build backendspyproject.toml [build-system] tablePython
  • sitecustomize / usercustomize auto-importsitecustomize.py / usercustomize.py on sys.path (usually site-packages)Python
  • .node native addon loading.node files in node_modules/ (typically under build/Release/ or prebuilds/)Node.js
  • Yarn Plug'n'Play (.pnp.cjs).pnp.cjs in the project rootNode.js
  • __init__.py execution on import__init__.py in any package directory on sys.pathPython
  • .pyc bytecode cache poisoning.pyc files in __pycache__/ directories alongside source modulesPython
  • PYTHONPATH / PYTHONHOME module shadowingPYTHONPATH / PYTHONHOME environment variablesPython
  • npx / npm exec remote executionnpx, npm exec, npm create / npm init (initializer flows)Node.js
  • conftest.py auto-loading (pytest)conftest.py files in any directory pytest traversesPython
  • NODE_PATH environment variableNODE_PATH environment variableNode.js
  • "imports" field (subpath imports)imports field in package.jsonNode.js
  • require.extensions / Module._extensionsrequire.extensions / Module._extensions in any loaded moduleNode.js
  • .egg files and EGG-INFO scripts.egg files in site-packages (registered via easy-install.pth)Python
  • Zip imports (zipimport).zip / .pyz files on sys.path, or passed directly to the interpreterPython
  • PYTHONSTARTUP environment variablePYTHONSTARTUP environment variablePython
  • node_modules/.hooks/ directorynode_modules/.hooks/ directoryNode.js
Python
Interpreter startup/File on disk

.pth file import execution

During site initialization at interpreter startup

Lives in
*.pth files on sys.path (commonly site-packages)
Attacker needs
Filesystem write access, Supply-chain foothold
Lifecycle
Install
Startup
your code
Module load
Runtime
REPL

Runs while the interpreter boots, before your entrypoint.

How it runs

A .pth file in a site-packages directory can do more than list paths. Any line that starts with import gets executed during site setup. Your code doesn't have to import anything, and there's no opt-in.

echo 'import sys; print("You are hacked")' \
  > /opt/homebrew/lib/python3.13/site-packages/demo.pth
python   # prints before your own code runs

The sneaky part is that .pth files look mundane. They are supposed to hold path entries, so nobody audits them. A stealthier variant hides import lines among legitimate path entries in easy-install.pth. Search for the .pth extension and the first results are PyTorch model files, which helps the disguise.

The LiteLLM attack in 2026 used this exact technique. A compromised version dropped a .pth into site-packages that executed on every Python startup, with no user interaction required.

In the wild

LiteLLM 2026, a compromised package dropped a .pth that ran on every startup

Defend

Audit .pth files in site-packages; launch with python -S where feasible; install from hash-pinned wheels instead of sdists; monitor site-packages for writes.