Image

"Michael Kennedy's Thoughts on Technology": Python Supply Chain Security Made Easy

Maybe you’ve heard that hackers have been trying to take advantage of open source software to inject code into your machine, and worst case scenario, even the consumers of your libraries or your applications machines. In this quick post, I’ll show you how to integratePython’s “Official” package scanning technologydirectly into your continuous integration and your project’s unit tests. While pip-audit is maintained in part byTrail of Bitswith support from Google, it’s part of thePyPA organization.

Why this matters

Here are 5 recent, high-danger PyPI security issues supply chain attacks where “pip install” can turn into “pip install a backdoor.” Afterwards, we talk about how to scan for and prevent these from making it to your users.

Compromised popular package release (ultralytics), malicious update pushed to PyPI

What happened:A malicious version (8.3.41) of the widely-usedultralyticspackage was published to PyPI, containing code that downloaded the XMRig coinminer. Follow-on versions also carried the malicious downloader, and the writeup attributes the initial compromise to a GitHub Actions script injection, plus later abuse consistent with a stolen PyPI API token. Source:ReversingLabs

Campaign of fake packages stealing cloud access tokens, 14,100+ downloads before removal

What happened:Researchers reported multiple bogus PyPI libraries (including “time-related utilities”) designed to exfiltrate cloud access tokens, with the campaign exceeding 14,100 downloads before takedown. If those tokens are real, this can turn into cloud account takeover. Source:The Hacker News

Typosquatting and name-confusion targetingcolorama, with remote control and data theft payloads

What happened:A campaign uploaded lookalike package names to PyPI to catch developers intending to installcolorama, with payloads described as enabling persistent remote access/remote control plus harvesting and exfiltration of sensitive data. High danger mainly becausecoloramais popular and typos happen. Source:Checkmarx

PyPI credential-phishing led to real account compromise and malicious releases of a legit project (num2words)

What happened:PyPI reported an email phishing campaign using a lookalike domain; 4 accounts were successfully phished, attacker-generated API tokens were revoked, and malicious releases ofnum2wordswere uploaded then removed. This is the “steal maintainer creds, ship malware via trusted package name” playbook. Source:Python Package Index Blog

SilentSync RAT delivered via malicious PyPI packages (sisaws,secmeasure)

What happened:Zscaler documented malicious packages (including typosquatting) that deliver a Python-based remote access trojan (RAT) with command execution, file exfiltration, screen capture, and browser data theft (credentials, cookies, etc.). Source:Zscaler

Integrating pip-audit

Those are definitely scary situations. I’m sure you’ve heard about typo squatting and how annoying that can be. Caution will save you there. Where caution will not save you is when a legitimate package has its supply chain taken over. A lot of times this could look like a package that you use depends on another package whose maintainer was phished. And now everything that uses that library is carrying that vulnerability forward.

Enterpip-audit.

pip-auditis great because you can just run it on the command line. It will check against PyPA’s official list of vulnerabilities and tell you if anything in your virtual environment or requirements files is known to be malicious.

You could even set up a GitHub Action to do so, and I wouldn’t recommend against that at all. But it’s also valuable to make this check happen on developers’ machines. It’s a simple two-step process to do so:

  1. Add pip-audit to your project’s development dependencies or install it globally withuv tool install pip-audit.
  2. Create a unit test that simply shells out to execute pip-audit and fails the test if an issue is found.

Part one’s easy. Part two takes a little bit more work. That’s okay, because I got it for you. Just download the file here and drop it in your pytest test directory:

test_pypi_security_audit.py

Here’s a small segment to give you a sense of what’s involved.

That’s it! When anything runs your unit test, whether that’s continuous integration, a git hook, or just a developer testing their code, you’ll also run a pip-audit audit of your project.

Image

Let others find out

Now, pip-audit tests if a malicious package has been installed, In which case, for that poor developer or machine, it may be too late. If it’s CI, who cares? But one other feature you can combine with this that is really nice isuv’s ability to put a delay on upgrading your dependencies.

Many developers, myself included, will typically run some kind of command that will pin your versions. Periodically we also run a command that looks for newer libraries and updates pinned versions so we’re using the latest code. So this way you upgrade in a stair-step manner at the time you’re intending to change versions.

This works great. However, what if the malicious version of a package is released five minutes before before you run this command. You’re getting it installed. But pretty soon, the community is going to find out that something is afoot, report it, and it will be yanked from PyPI. Here bad timing got you hacked.

While it’s not a guaranteed solution, certainly Defense In Depth would tell us maybe wait a few days to install a package. But you don’t want to review packages manually one by one, do you? For example, forTalk Python Training, we have over 200 packages for that website. It would be an immense hassle to verify the dates of each one and manually pick the versions.

No need! We can just add a simple delay to our uv command:

In particular, notice–exclude-newer “1 week”. The exact duration isn’t the important thing. It’s about putting a little bit of a delay for issues to be reported into your workflow. You canread about the full feature here. This way, we only incorporate packages that have survived in the public on PyPI for at least one week.

Hope this helps. Stay safe out there.

https://mkennedy.codes/posts/python-supply-chain-security-made-easy/