You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _posts/2024-12-13-python-packaging-security.md
+25-14Lines changed: 25 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,9 +17,6 @@ last_modified: 2024-12-13
17
17
---
18
18
19
19
20
-
21
-
22
-
23
20
## Is your PyPI publication workflow secure?
24
21
25
22
The recent Python package breach [involving Ultralytics](https://blog.yossarian.net/2024/12/06/zizmor-ultralytics-injection) has spotlighted the importance of securing your Python package PyPI publishing workflows. The Ultralytics breach was a supply chain attack where malicious actors exploited a GitHub workflow to inject harmful code into a Python package, enabling them to hijack users’ machines for Bitcoin mining. What this means in English:
@@ -49,19 +46,19 @@ The Ultralytics breach is a wake-up call for all maintainers: secure your workfl
49
46
### 🔐 Secure your workflows 🔐
50
47
- 🚫 Avoid risky events like `pull_request_target` and adopt release-based workflows.
51
48
- ♻️ Don’t cache dependencies in your publish workflows to prevent tampering.
52
-
- If you reference branches that others may use in a pull request, clean or sanitize branch names in your workflow.
49
+
- If you reference branches in a pull request, clean or sanitize branch names in your workflow.
53
50
54
-
### **Lock down GitHub repo access**
51
+
### Lock down GitHub repo access
55
52
- 🔒 Restrict repository access to essential maintainers only.
56
53
- ✅ Add automated checks to ensure releases are authorized and secure.
57
54
58
-
### **Strengthen PyPI security**
55
+
### Strengthen PyPI security
59
56
- 🔑 Set up Trusted Publisher for tokenless authentication with PyPI.
60
57
- 📱 Enable 2FA for your PyPI account and store recovery codes securely.
61
58
62
-
Taking these steps will significantly reduce risks to your packages, contributors, and the broader Python ecosystem. Don’t wait—start securing your workflows today.
59
+
These steps will significantly reduce risks to your packages, contributors, and the broader Python ecosystem. Don’t wait—start securing your workflows today.
63
60
64
-
### **What Happened in the Ultralytics Breach?**
61
+
### What happened in the Ultralytics breach?
65
62
66
63
The Ultralytics incident was a **supply chain attack**—a type of attack where sneaky coders compromise the tools or processes used to create or distribute software. In this case, the bad actors/hackers wanted to use the user's machines to mine Bitcoin. This was a hack with the goal of using other people's compute for illegal profit!
67
64
@@ -93,7 +90,7 @@ For this post, we will use [this workflow that pyOpenSci has setup](https://gith
93
90
Below, are actionable steps you can take to enhance security when publishing Python packages to PyPI using GitHub actions.
94
91
95
92
96
-
## **1. Avoid `pull_request_target` and consider release-based workflows**
93
+
## 1. Avoid `pull_request_target` and consider release-based workflows
97
94
98
95
The [`pull_request_target`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target) event in GitHub Actions that Ultralytics used, allows workflows to run with elevated permissions on the base branch, even when triggered by changes from a fork. Thus, when used as a trigger to push a release to PyPI, your workflow becomes vulnerable.
99
96
@@ -214,12 +211,12 @@ You can see how to set up GitHub Actions securely in our own [PyPI publishing Gi
214
211
**Note:** Trusted Publisher workflows are currently only available for GitHub. Support for GitLab may be coming in the future—stay tuned!
215
212
{: .notice }
216
213
217
-
## **5. Create a Dedicated Environment for Publish Actions**
214
+
## 5. Create a dedicated environment for publish actions
218
215
219
216
Use isolated environments in combination with Trusted Publisher in your GitHub workflow to publish to PyPI.
220
-
Isolated environments ensure that your publishing process remains secure even if other parts of your CI pipeline are compromised.
217
+
Isolated environments ensure your publishing process remains secure even if other parts of your CI pipeline are compromised.
221
218
222
-
If you look at the pyometra workflow, notice that we have an [environment called `pypi`](https://github.com/pyOpenSci/pyosMeta/blob/main/.github/workflows/publish-pypi.yml#L57) that is used for trusted publishing. By setting this up, we have created a direct pipeline between this action and PyPI via the pypi environment and the trusted publisher setup which refers to the workflow file's name.
219
+
If you look at the pyometra workflow, notice that we have an [environment called `pypi`](https://github.com/pyOpenSci/pyosMeta/blob/main/.github/workflows/publish-pypi.yml#L57) that is used for trusted publishing. By setting this up, we have created a direct pipeline between this action and PyPI via the PyPI environment and the trusted publisher setup, which refers to the workflow file's name.
223
220
224
221
```yaml
225
222
publish:
@@ -307,7 +304,7 @@ The good news here is that if you use a release-based workflow as discussed earl
307
304
308
305
Restricting publish workflows to tagged releases significantly reduces the risk of such attacks.
309
306
310
-
### Delete Old Tokens
307
+
### Delete old tokens
311
308
312
309
If you are using a trusted publisher workflow but have previously created PyPI API tokens for your package to use in GitHub Actions, it’s time to clean house:
313
310
@@ -326,8 +323,22 @@ Important: Store recovery codes securely (e.g., a password manager).
326
323
* Be careful about who can gain direct write access to your project's repository. Only a specific, trusted subset of maintainers should be able to trigger a publish-to-PyPI workflow. Most contributors and maintainers don’t need direct write access to your repository; limiting access reduces security risks.
327
324
328
325
329
-
## **Learn More**
326
+
## Learn More
330
327
331
328
pyOpenSci follows best practices for PyPI publishing using our custom GitHub Actions workflow. Check out our tutorial on Python packaging here:
If you are on LinkedIn, you should [subscribe to our newsletter, too](https://www.linkedin.com/newsletters/7179551305344933888/?displayConfirmation=true).
0 commit comments