-
-
Notifications
You must be signed in to change notification settings - Fork 91
feat: Audit secrets outside an environment #637
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
base: main
Are you sure you want to change the base?
Conversation
Hey @aldur, thanks for taking a stab at this! I'll do a high-level review later today or tomorrow. |
Thanks for the comments! I have addressed them, added a snapshot and had to modify I have also some |
You should run |
Done, thank you! |
Thanks @aldur, this is looking really good! One thing I'm realizing, based on the changes to the other tests: this might be slightly too conservative as a default audit, at least for now, since a lot of people have relatively simple CI/CD setups with 1-2 workflows where an environment wouldn't provide much isolation. Given that, I'm thinking that it might make sense to mark this as a "pedantic" audit for now, i.e. by calling |
1048e11
to
0132617
Compare
Done! Sorry it took me some time to get back to this :) |
No problem at all! I'll do another review tonight. |
|
||
audit_meta!( | ||
SecretsOutsideEnvironment, | ||
"secrets-outside-environment", |
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'm trying to make new audit names a bit shorter, so some ideas here:
secret-outside-env
secret-without-env
secret-missing-env
secret-no-env
(shortest, but maybe not easy to understand)
Curious if you have any other naming thoughts as well 🙂
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.
Picked number 2 and fixed in 96c90ac
.
step: &crate::models::Step<'w>, | ||
findings: &mut Vec<crate::finding::Finding<'w>>, | ||
) -> anyhow::Result<()> { | ||
if s.contains("secrets") { |
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 think we need to exclude secrets.github_token
here, since that's a "latent" secret that's present regardless of any environment.
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.
Yep that makes sense! Fixed it in b5dab62
.
working_directory: _, | ||
} => match env { | ||
LoE::Expr(e) => { | ||
Self::check_secrets_access(e.as_bare(), step, &mut findings)?; |
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 think this check needs to be a little more discerning: e
needs to be parsed into an Expr
, which then needs to be walked recursively to visit each Expr::Context
and match that on the secrets
namespace.
Without that, we'll end up with (admittedly goofy) false positives like:
with:
yolo: ${{ 'secrets' }}
Writing the AST walker is currently a bit annoying/manual; if you want to wait until I add a Visitor
API that might make your life a bit easier (I plan on doing that pretty soon) 🙂
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 like that! It will also increase the audit confidence. I am ok with waiting for the Visitor
API, just give me a ping once ready and I'll put it to work :)
eenv = with; | ||
} | ||
StepBody::Run { | ||
run: _, |
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.
Note: I'm okay with skipping run:
blocks for an MVP here, but we will need to extract expressions from those and scan for secrets as well at some point.
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.
Makes sense! I naively thought that wouldn't be required, would this be an example?
- name: Clean install dependencies and build
run: |
npm ci
PASSWORD=${{ secrets.password }} npm run build
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.
Yep, exactly 🙂
Hi there! Any news on the |
Hey @aldur, sorry for the delay! The (P.S. Sorry for the huge conflict set here -- with any luck most of it can probably be discarded and the snapshot tests can be re-done on top of just the audit changes.) |
I'm done with the expression API refactoring, but I wasn't able to reach a Given that, I think we can move forward without blocking on any larger visitor API changes here; the existing APIs should work well enough. Sorry for such a delay on my end. |
Would close #184.
Early draft, mainly to gather feedback (as this scratch an itch I have :)). Specifically, doing string matching in the
with
/env
section might not be robust enough and/or might lead to false positives.Sorry about the noise in the imports, that is what
rustfmt
has suggested for me. That can be reverted if it doesn't match the project style.