-
-
Notifications
You must be signed in to change notification settings - Fork 32
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
feat: initial cache-poisoning audit #294
Conversation
259018b
to
a67519e
Compare
Thanks @ubiratansoares! I'll try and do an initial pass on this today or tomorrow. |
|
||
let trigger = &step.workflow().on; | ||
|
||
if !self.trigger_used_when_publishing_artifacts(trigger) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good for now, thanks!
Thinking out loud: another future proxy we could use for "is this a publishing workflow" is whether or not the workflow contains any well-known publishing actions, e.g. gh-action-pypi-publish
.
Not something to do with this iteration, but worth thinking about 🙂
a67519e
to
accbdbd
Compare
@woodruffw Addressed your suggestions, let me know whether I missed something! Docs to follow 🙂 |
Thanks! I think that's everything -- just undraft and give me a ping when you're ready for a final review! |
@woodruffw Added some docs here, let me know what you think :) Some follow-ups from this PR, so we can keep its size manageable for the review:
|
Added this additional commit to highlight another (potential) follow-up : should we evaluate |
src/models.rs
Outdated
pub(crate) fn as_template(&self) -> String { | ||
format!("{}/{}", self.owner, self.repo) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created this new method as a helper, since I need to get a template from what we have in well-know list, essentially due the asymmetrical nature of RepositoryUses::matches
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't love that we have to re-build the slug here, but that's my fault for building a bad abstraction here 😅 -- I'll try and clean this up as part of the final review.
Thanks! I'll give this a final pass tomorrow, but this is looking great to me! Let's track the follow-ups in #294 (comment) with a new issue 🙂 |
Signed-off-by: William Woodruff <william@yossarian.net>
Allow `RepositoryUses::matches` to take `impl TryInto<RepositoryUses>` instead, which has an auto-derived infallible impl for `RepositoryUses` itself. Signed-off-by: William Woodruff <william@yossarian.net>
GHA doesn't know the difference between `true` and `'true'`, so neither should we. Signed-off-by: William Woodruff <william@yossarian.net>
|
Signed-off-by: William Woodruff <william@yossarian.net>
Signed-off-by: William Woodruff <william@yossarian.net>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, great work @ubiratansoares!
A first iteration on #261
There is a lot to unpack in this PR already, so I added several inline comments, and I'll go for docs as soon as we are good with the overal design 🙂
First consideration : for now, I'm matching as triggers for this audit only
release
andpush
(with tags filters).I'm aware that more scenarios exist : I myself use another pattern (on top of
workflow_dispatch
), happy to get input and iterate, or eventually tackle them as a follow-up. I miss a check for the default branch of the repo, but since it requires querying the Github API, I've skipped it for now.Second consideration: because of the multitude of caching-aware Actions that exist (and how they behave), and because we should aim to consume a static API at some point in the future, I've modelled a
CacheAwareAction
struct, which is the very core of this PR.In general, I tried to capture with this data holder:
actions/setup-go
)actions/cache
)actions/setup-node
)There is a static list of
CacheAwareAction
, covering all Actions provided by Github and a few others. Happy to add as many as we want to have 🔥Third consideration: I defined a strategy for this audit on top of a chat I had with Adnan, focusing on the unzip part of cache-poisoning attacks. This means I'm not considering
actions/cache/save
in the Actions we inspect for.Most of the Actions I've listed bring both saving/restoring out-of-the-box, but some of them define a
lookup-only
input (as peractions/cache
andactions/cache/restore
do), that only queries the Github API for cache entries but do not download any caches. Maybe this is incomplete/insufficient, and I'd love to get inputs here!Last but not least : I added several examples of vulnerable Workflows and snapshot test all of them.
Most likely I missed other things, but hopefully this PR sesa a place to get started 🙂