PyPI's package filtering and popularity signals don't seem sufficient anymore. A recent supply-chain incident involving a popular machine-learning ecosystem package showed that even widely used community projects can briefly distribute code that exposes secrets such as environment variables or cloud credentials. Dependency scanners also tend to be limited, outdated, or focused mainly on known CVEs rather than new malicious behavior. Short of manually reviewing every direct and transitive dependency—or avoiding third-party packages entirely—what practical steps do you use? Do you rely on pinned versions, delayed updates, isolated environments, sandboxes, static analysis, minimal dependencies, or something else?
5 Answers
Use layers rather than expecting one scanner to solve this. Build from a locked dependency file in a reproducible environment, review changes before upgrading, scan for known vulnerabilities and suspicious files, and run untrusted code with limited filesystem, network, and credential access. Keep secrets out of the process whenever possible. Sandboxing limits the damage if a package is compromised, but it does not prove the package is safe.
There is no fully autonomous solution. Automated static analysis, AI-assisted review, lockfiles, delayed updates, and sandboxing can reduce risk, but each has blind spots and produces false positives. For a small package that is easy to understand, reviewing or replacing it may be reasonable; for large frameworks, you have to combine trust, auditing, controlled upgrades, and least-privilege execution rather than reading every line yourself.
For higher-risk projects, evaluate the library’s security policy, release process, contributor diversity, build and publication controls, and response history. Reproducible builds and an internal package mirror or allowlist can prevent unexpected packages from entering production. Development-only tools may deserve less scrutiny than runtime dependencies, but they still should not have unnecessary access to credentials or production systems.
Popularity alone is not a security guarantee. Also, the incident being discussed involved Lightning, a third-party high-level wrapper in the PyTorch ecosystem, rather than PyTorch itself. The broader lesson still stands: every package, including transitive dependencies and installation hooks, can expand your attack surface. For small utilities, reimplementing the functionality with the standard library may be safer and simpler than adding another dependency.
The practical baseline is to minimize dependencies, prefer mature projects with active maintainers and a history of handling security issues, pin direct and transitive versions, and avoid automatic upgrades. Waiting several days or weeks before adopting a new release gives the community time to catch obvious supply-chain attacks. It is not perfect, but it prevents a large portion of opportunistic incidents.
That delay mainly protects you from malicious releases that are discovered quickly. It cannot eliminate zero-days, so it needs to be combined with isolation and monitoring.

Dependency scanners are still useful, but many only compare package names and versions with vulnerability databases. They usually will not detect a brand-new malicious payload, typosquatting, or dangerous install-time behavior.