Skip to content
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: even more precision for bash steps in github-env #208

Merged
merged 5 commits into from
Nov 28, 2024

Conversation

ubiratansoares
Copy link
Contributor

@ubiratansoares ubiratansoares commented Nov 26, 2024

A follow-up for #197

Here we leverage tree-sitter-bash rather than regexes to match usages of $GITHUB_ENV within a Bash script body.

I took a simple approach, getting the full expansion for a file_redirect or pipeline and matching inner contents. Perhaps I'm missing some corner cases, but at least we have a starting point to iterate over 🙂

I also added some additional test cases (comments) and prepared the implementation to match against other types of shells in upcoming PRs.

@ubiratansoares ubiratansoares mentioned this pull request Nov 26, 2024
3 tasks
Comment on lines 16 to 17
let bash = tree_sitter_bash::LANGUAGE;
let mut parser = Parser::new();
Copy link
Owner

Choose a reason for hiding this comment

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

Nit: creating the parser with each evaluation is probably slower than necessary; we could probably reuse parser by making it a property of GitHubEnv that gets loaded when the audit itself is loaded with GitHubEnv::new 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done here, along with other changes!

if let StepBody::Run { run, .. } = &step.deref().body {
if Self::uses_github_environment(run) {
if let StepBody::Run { run, shell, .. } = &step.deref().body {
let interpreter = shell.clone().unwrap_or("bash".into());
Copy link
Owner

Choose a reason for hiding this comment

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

This is unfortunately not guaranteed to be the right default, since Windows runners default to pwsh. I think what we need to do is look at the surrounding NormalJob::runs_on and maybe add some kind of RunsOn::default_shell() helper. I'll look into that a bit.

(Nonblocker, since this is still improving on the precision of the current approach 🙂)

Copy link
Owner

Choose a reason for hiding this comment

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

Actually, it's a bit more annoying than even that: we need to determine the step's shell via the following precedence:

  1. defaults.run.shell
  2. jobs.<job_id>.defaults.run.shell
  3. jobs.<job_id>.steps[*].shell
  4. If none of the above are set, use the default shell implied by the runner from runs-on (which might be indeterminate in the self-hosted runner case)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@woodruffw I totally missed pwsh on Windows as the default, I never used Windows runners and I though that bash was the default (via WLS). Another day, another learning I guess 🙂

Copy link
Owner

Choose a reason for hiding this comment

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

I forget about too 🙂 -- the changes in #213 should enable this, but I'll rebase off of your work so that it's not a blocker here.

@@ -72,7 +111,7 @@ mod tests {
use crate::audit::github_env::GitHubEnv;

#[test]
fn test_shell_patterns() {
fn test_exploitable_bash_patterns() {
Copy link
Owner

Choose a reason for hiding this comment

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

I think we can fold these two test functions into one, with (case, expected: bool) as the parametrization 🙂

@ubiratansoares
Copy link
Contributor Author

@woodruffw I lack the energy to work on anything else today, I'll resume the work on this PR tomorrow, addressing all your suggestions, and perhaps making the most of #213 🙂

Meanwhile, thanks again for the great review (as usual), it's a pleasure contributing to and learning from this project ❤️

@woodruffw
Copy link
Owner

Thank you too! And there's no rush or urgency at all, it's all supposed to be open source fun 🙂

@ubiratansoares ubiratansoares marked this pull request as ready for review November 28, 2024 07:12
@woodruffw woodruffw added the enhancement New feature or request label Nov 28, 2024
Signed-off-by: William Woodruff <[email protected]>
Copy link
Owner

@woodruffw woodruffw left a comment

Choose a reason for hiding this comment

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

LGTM, thanks a ton @ubiratansoares!

@woodruffw woodruffw enabled auto-merge (squash) November 28, 2024 22:23
@woodruffw woodruffw merged commit a0e1723 into woodruffw:main Nov 28, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants