Skip to content

security: update actions for artifact handling only by id #3648

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 5, 2025

Conversation

GrantBirki
Copy link
Contributor

This pull request updates the publish.yml workflow to explicitly use artifact-ids instead of the name input option when handling artifacts. This is important because artifacts produced by GitHub Actions can be completely overwritten by other workflow runs if they use the same name. To avoid potential TOCTOU issues/vulnerabilities where an artifact might be replaced between upload and download, the new artifact-ids input allows you to download artifacts by their specific ID rather than by name.

In the context of this repo, this is especially important as the SLSA L3 badge is present on this project, but in order to be truly at SLSA L3, you cannot use name for artifacts as it could be replaced between the build and release... stages of this workflow. This means that another workflow could potentially change the artifact being used by this publish.yml job and release a malicious package to pypi.org.


The pull request where I originally implemented this feature in actions/download-artifact does a pretty good job at summarizing why this is important in the context of security in general: actions/download-artifact#401

@GrantBirki
Copy link
Contributor Author

If your change does not deserve a changelog entry, apply the Skip Changelog GitHub label to your pull request

I do not have the ability to add labels to this PR, but I do not think this change needs a changelog entry so this label should be added.

@pquentin pquentin added the Skip Changelog Pull requests that don't require a changelog entry label Aug 5, 2025
Copy link
Member

@pquentin pquentin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, thank you!

@@ -47,7 +48,8 @@ jobs:
cd dist && echo "hashes=$(sha256sum * | base64 -w0)" >> $GITHUB_OUTPUT

- name: "Upload dists"
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@4.6.2 # immutable release
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please stick to the existing scheme? There may be an argument to switch back to version numbers, but I'd rather do this separately, for all actions, and make sure that the format will be recognized by dependabot.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pquentin done! ✅

Copy link
Member

@pquentin pquentin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! LGTM.

We can address ci.yml later since it's not part of the publishing build and does not impact SLSA levels.

@pquentin pquentin enabled auto-merge (squash) August 5, 2025 16:52
@pquentin pquentin merged commit fd84166 into urllib3:main Aug 5, 2025
36 checks passed
@pquentin
Copy link
Member

pquentin commented Aug 5, 2025

@GrantBirki This didn't work: https://github.com/urllib3/urllib3/actions/runs/16756161327/job/47439256407

Here's what a working run looks like: https://github.com/urllib3/urllib3/actions/runs/16593313383/job/46934035410

with:
name: "dist"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess removing this line led to the job failure

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the logs I can see: Starting download of artifact to: /home/runner/work/urllib3/urllib3/dist/dist (ref) and in the working logs, it looks like this:

Starting download of artifact to: /home/runner/work/urllib3/urllib3/dist

ref

So it appears that there is some sort of double nested dist/dist action going on when not referencing by name 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep that is exactly what is going on! When using a single artifact by name, it resolves the path slightly differently:

https://github.com/actions/download-artifact/blob/448e3f862ab3ef47aa50ff917776823c9946035b/src/download-artifact.ts#L177-L179

So I think the easy fix here would just be to adjust the path used for the artifacts in other steps. I'll open a PR to fix this now.

@GrantBirki
Copy link
Contributor Author

@illia-v @pquentin I have created a follow-up PR that should address the issue with the nested artifact path here: #3650

@illia-v
Copy link
Member

illia-v commented Aug 5, 2025

@GrantBirki thanks for this security hardening and the quick fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Skip Changelog Pull requests that don't require a changelog entry
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants