Join our Newsletter — 33% off our NHI Course

sitecustomize.py (Python Startup Hook)

sitecustomize.py is a Python startup hook that Python imports automatically when the interpreter starts, if it is present on the import path. Attackers can place malicious code there to gain persistence or influence every Python session. Defenders should restrict writable paths, inspect import locations, and watch for unexpected code in startup files.

What sitecustomize.py actually does

Python imports sitecustomize.py automatically during interpreter startup when it is present on the import path, which makes it a global hook that can alter behaviour before application code runs. That same convenience gives defenders and attackers a high-leverage point for environment-wide influence.

Because the hook runs early and invisibly, small changes can affect every Python session on a host, in a virtual environment, or inside tooling that embeds Python. That makes the file less like a normal module and more like a startup control surface.

Why the startup hook is security-sensitive

The main security concern is trust placement: if an attacker can write to a location that Python searches at startup, they can execute code without changing the application itself. A malicious hook can seed persistence, alter imports, suppress logging, or pivot into any Python-based workflow that loads the interpreter.

For defenders, the key issue is not just whether sitecustomize.py exists, but where it lives and who can modify the directory that contains it. Writable import paths, shared package directories, and overly broad environment settings can turn an ordinary startup convenience into a system-wide execution path.

How attackers abuse startup-time execution

Attackers favour startup hook because they are reliable and low-noise. Once planted, the code can run before user logic, scheduled jobs, web services, notebooks, or automation scripts have a chance to validate their own runtime state.

That pattern is a classic persistence technique, and it overlaps with broader startup-file abuse such as login scripts, shell profiles, and autostart entries. The underlying idea is the same: place code in a location that the platform trusts and executes automatically. Persistence Techniques Guide is a useful reference for understanding how startup abuse fits into the wider persistence landscape.

In Python environments, the impact can extend beyond the current user if the interpreter is used by shared services, CI jobs, or administrative tooling. That is why seemingly small path and permission mistakes can become durable footholds.

Defensive controls and review points

The practical defence is to treat interpreter startup paths as privileged infrastructure. Inspect where Python is loading startup hooks from, keep writable directories out of the import path where possible, and avoid relying on locations that ordinary users or build processes can modify.

Reviewing package and import locations is equally important because a malicious hook can be disguised as a normal environment file or arrive through an unexpected dependency path. PyPI secrets exposure 2023 and the Ultralytics PyPI compromise 2024 both show how Python ecosystems can be abused when trust and publish paths are not tightly controlled.

After discovering a malicious startup hook, defenders should review the host for related persistence, unexpected imports, altered environment variables, and any Python processes that may have executed while the hook was present. In practice, the file is both a compromise vector and a clue.

Risk and Threat Considerations

Startup hooks create a high-value persistence opportunity because they execute early, automatically, and often before application-specific controls or monitoring are active. If the containing directory is writable by a less-trusted user or process, the attacker can gain repeatable code execution across sessions and services that rely on Python.

Failure mechanism: A writable import path or tampered startup location lets malicious code run whenever the interpreter starts, which can hijack automation, modify runtime behaviour, and survive normal application reinstalls.

Impact: The compromise can expose credentials, session material, API keys, or operational data handled by Python programs, and it can create persistence that is hard to notice because the malicious logic lives outside the main application.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

MITRE ATT&CK addresses the attack and risk surface, while NIST SP 800-53 Rev 5 and CIS Controls v8 set the governance and control requirements practitioners need to meet.

Framework Control / Reference Relevance
MITRE ATT&CK T1547.001 — Registry Run Keys / Startup Folder Covers persistence by automatic startup execution, which is the core abuse pattern here.
Recommendation — Map suspicious startup-file execution to persistence techniques and hunt for follow-on activity.
NIST SP 800-53 Rev 5 CM-7 — Least Functionality Reducing unnecessary startup-path exposure supports limiting what code can run at interpreter start.
SI-4 — System Monitoring Unexpected startup code requires monitoring for anomalous execution during interpreter launch.
AC-6 — Least Privilege Write access to startup locations should be limited to only trusted administrators and processes.
Recommendation — Restrict startup paths and remove unneeded execution locations from Python environments. Monitor interpreter startup and alert on unexpected imports or startup-file execution. Limit write permissions on Python import locations to trusted administrative principals.
CIS Controls v8 CIS-4 — Secure Configuration of Enterprise Assets and Software Secure baselines should prevent unsafe writable paths and uncontrolled startup behaviour.
Recommendation — Harden Python host configurations to keep startup locations controlled and immutable.

Practitioner Guidance

Why practitioners should care: sitecustomize.py is one of those mechanisms that is easy to overlook during development but difficult to ignore during incident response. If your Python estate includes shared servers, automation, or developer workstations, startup hooks deserve the same scrutiny you would give any other autostart mechanism.

What to watch for: Unexpected files on import paths, newly writable package directories, startup behaviour changes, or Python processes that begin importing from unusual locations are all signals that the hook may be being abused. The safest assumption is that any unauthorised startup file is already a potential persistence point.