Add PR checks workflow#73
Conversation
📝 WalkthroughWalkthroughAdded a GitHub Actions workflow that triggers on pull requests to run automated checks including ESLint linting, Prettier format validation, Vitest tests, and project build. The workflow uses pnpm v10 and Node.js v20 with dependency caching, and a new ChangesPR Checks Workflow Setup
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Tamir198
left a comment
There was a problem hiding this comment.
One thing that I would check, I think that now every push to a pr triggers new workflow run, and the old ones keep running.
Read about concurrency to cancel old workflows on new commit, it should be something like this:
concurrency:
group: pr-checks-${{ github.event.pull_request.number }}
cancel-in-progress: true00edc64 to
1e1dd1c
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.github/workflows/pr-checks.yml (1)
21-24: ⚡ Quick winPin GitHub Actions to immutable commit SHAs.
Using version tags leaves the workflow exposed to upstream tag retargeting. Pinning to full SHAs hardens the CI supply chain.
Also applies to: 29-29
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/pr-checks.yml around lines 21 - 24, Replace the mutable action version tags with immutable commit SHAs for both uses entries shown (actions/checkout@v4 and pnpm/action-setup@v6.0.8) — locate the two occurrences (the checkout step and the Setup pnpm step, also the second occurrence referenced at 29-29) and pin each to the corresponding full commit SHA from their GitHub repositories so the workflow references a specific immutable commit instead of a floating tag.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/pr-checks.yml:
- Around line 35-47: The workflow step "Print environment info" currently
interpolates untrusted values (${ { github.head_ref }}, ${ { github.base_ref }},
${ { github.event.pull_request.number }}) directly into the run script; update
the job to set these three values in the job's env block (e.g., PR_HEAD_REF,
PR_BASE_REF, PR_NUMBER) and then reference them inside the "Print environment
info" step using shell variables ($PR_HEAD_REF, $PR_BASE_REF, $PR_NUMBER)
instead of direct GitHub expression interpolation to prevent script injection.
---
Nitpick comments:
In @.github/workflows/pr-checks.yml:
- Around line 21-24: Replace the mutable action version tags with immutable
commit SHAs for both uses entries shown (actions/checkout@v4 and
pnpm/action-setup@v6.0.8) — locate the two occurrences (the checkout step and
the Setup pnpm step, also the second occurrence referenced at 29-29) and pin
each to the corresponding full commit SHA from their GitHub repositories so the
workflow references a specific immutable commit instead of a floating tag.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ee6e6df8-c105-4e6b-add6-517e0af398d5
📒 Files selected for processing (2)
.github/workflows/pr-checks.ymlpackage.json
| - name: Print environment info | ||
| run: | | ||
| echo "::group::Environment" | ||
| echo "Node version:" | ||
| node --version | ||
| echo "pnpm version:" | ||
| pnpm --version | ||
| echo "Current branch:" | ||
| echo "${{ github.head_ref }}" | ||
| echo "Target branch:" | ||
| echo "${{ github.base_ref }}" | ||
| echo "PR number:" | ||
| echo "${{ github.event.pull_request.number }}" |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
GitHub Actions script injection pull_request context variables security risk
💡 Result:
Script injection in GitHub Actions occurs when untrusted user-controlled input—such as pull request titles, branch names, or issue bodies—is interpolated directly into workflow scripts [1][2]. When these values are used within ${{ }} expressions inside a run command, they are evaluated and substituted before the shell script executes, allowing an attacker to inject malicious commands that run on the GitHub Actions runner [1][3]. The security risk is significantly amplified when combined with the pull_request_target trigger [4][5]. Unlike the standard pull_request trigger, which runs in an isolated context without access to repository secrets, pull_request_target executes in the context of the base repository [4][6]. This grants the workflow access to repository secrets and elevated permissions, creating a critical Remote Code Execution (RCE) vector if the workflow processes untrusted content from a pull request [2][4][5]. To mitigate these risks, follow these security practices: 1. Use Environment Variables: Never interpolate ${{ }} expressions directly into run commands [3]. Instead, pass the untrusted input through an env block [7][3]. This ensures the input is treated as a variable rather than executable code [2][8]. Example of safe usage: - name: Example env: PR_TITLE: ${{ github.event.pull_request.title }} run: echo "$PR_TITLE" 2. Exercise Caution with pull_request_target: Use this trigger only when necessary [2][4]. If used, avoid checking out or executing code from the untrusted pull request head branch [4][5]. If you must process code from a PR, consider using a secondary, manually triggered workflow after a security review [4]. 3. Validate Inputs: Treat all context variables (e.g., github.event.pull_request.title, github.head_ref) as untrusted [1][2]. Implement strict validation, such as ensuring numeric fields contain only integers or using allowlists for expected string patterns [9][8]. 4. Principle of Least Privilege: Restrict GITHUB_TOKEN permissions to the minimum required for the task [8]. Avoid granting write access or secret access unless absolutely necessary [6][8]. 5. Use Automated Tools: Leverage security scanning tools like CodeQL, which includes queries designed to detect unsafe interpolation of untrusted input in GitHub Actions workflows [3][10]. You can also implement policy-as-code (e.g., using Open Policy Agent) to enforce these rules across your organization [11].
Citations:
- 1: https://docs.github.com/en/actions/concepts/security/script-injections
- 2: https://medium.com/@instatunnel/github-actions-script-injection-the-ci-cd-backdoor-3e8184eaef35
- 3: https://github.blog/2023-08-09-four-tips-to-keep-your-github-actions-workflows-secure
- 4: https://paulserban.eu/blog/post/pullrequest-vs-pullrequesttarget-the-github-actions-trigger-hiding-a-security-nightmare/
- 5: https://paulserban.eu/blog/post/why-is-pullrequesttarget-so-dangerous-a-security-explainer/
- 6: https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
- 7: Security: GitHub Actions script injection via untrusted PR contexts oxsecurity/megalinter#7657
- 8: https://openssf.org/blog/2024/08/12/mitigating-attack-vectors-in-github-workflows/
- 9: Validate numeric context variables in activation to prevent injection attacks github/gh-aw#16515
- 10: https://github.com/githubuniverseworkshops/workflow-script-injection
- 11: Add script injection prevention rule to GitHub Actions policy mlflow/mlflow#16545
🌐 Web query:
GitHub Actions security best practices environment variables pull_request event
💡 Result:
To secure GitHub Actions workflows triggered by pull requests, you must treat all user-controlled input as untrusted and isolate privileged operations [1][2][3]. Key Security Best Practices: 1. Use Intermediate Environment Variables for Untrusted Input Never use expression syntax (${{... }}) directly within shell scripts or command arguments, as this allows attackers to inject malicious commands [4][3][5]. Instead, map the untrusted input to an intermediate environment variable and reference that variable using standard shell syntax (e.g., "$VAR") [4][6][5]. Example of secure usage: - name: Check PR title env: TITLE: ${{ github.event.pull_request.title }} run: | # Use shell syntax, not ${{ env.TITLE }} if [[ "$TITLE" =~ ^octocat ]]; then echo "Valid title" fi 2. Understand Trigger Security Models - pull_request: This is the recommended trigger for most workflows [7][8]. It runs in a sandboxed environment using the code from the pull request's merge commit, has no access to repository secrets, and receives a read-only GITHUB_TOKEN [1][7][9]. - pull_request_target: This trigger runs in the context of the base repository and has access to secrets and a read/write GITHUB_TOKEN [7][8][10]. It is highly dangerous if used to execute untrusted code from a pull request [7][9]. Only use this trigger if absolutely necessary (e.g., for labeling or commenting) and ensure the workflow does not execute or process untrusted code from the PR head [7][10]. 3. Prevent Environment Variable Injection Attackers can inject malicious content into files like GITHUB_ENV, which can lead to the definition of dangerous environment variables (e.g., LD_PRELOAD) that affect subsequent steps [11][12]. Always validate or sanitize any data before writing it to GITHUB_ENV or GITHUB_PATH [2][11]. 4. General Hardening - Principle of Least Privilege: Explicitly set permissions for the GITHUB_TOKEN to read-only whenever possible [1][2][13]. - Use OIDC: Replace long-lived secrets with OpenID Connect (OIDC) for cloud provider authentication to minimize the impact of a potential credential leak [14][13][15]. - Code Scanning: Enable CodeQL to automatically detect potential workflow injection vulnerabilities in your repository [3].
Citations:
- 1: https://github.blog/2023-08-09-four-tips-to-keep-your-github-actions-workflows-secure
- 2: https://openssf.org/blog/2024/08/12/mitigating-attack-vectors-in-github-workflows/
- 3: https://github.blog/security/vulnerability-research/how-to-catch-github-actions-workflow-injections-before-attackers-do/
- 4: https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions
- 5: https://codeql.github.com/codeql-query-help/actions/actions-code-injection-critical/
- 6: https://dev.to/duriantaco/github-actions-security-and-gitlab-ci-security-static-analysis-for-cicd-g9h
- 7: https://paulserban.eu/blog/post/pullrequest-vs-pullrequesttarget-the-github-actions-trigger-hiding-a-security-nightmare/
- 8: https://runs-on.com/github-actions/pull-request-vs-pull-request-target/
- 9: https://paulserban.eu/blog/post/why-is-pullrequesttarget-so-dangerous-a-security-explainer/
- 10: https://stackoverflow.com/questions/74957218/what-is-the-difference-between-pull-request-and-pull-request-target-event-in-git
- 11: https://www.wiz.io/blog/github-actions-security-guide
- 12: https://securitylab.github.com/advisories/GHSL-2024-177_Litestar/
- 13: https://dev.to/sahil_kat/hardening-claude-code-in-github-actions-after-the-cvss-94-cve-3id5
- 14: https://www.aikido.dev/blog/checklist-github-actions
- 15: https://dev.to/neil_4e5a9c0f3c99/stop-putting-aws-access-keys-in-github-secrets-use-oidc-instead-5c13
🌐 Web query:
github.head_ref github.base_ref untrusted pull_request event injection
💡 Result:
In GitHub Actions, context variables such as github.head_ref and github.base_ref are considered untrusted input because they are controlled by the user who initiates the event (e.g., by creating a pull request or naming a branch) [1][2][3]. When these variables are directly interpolated into a run step using the ${{ }} syntax, they can be exploited to perform script injection attacks [1][4][3]. An attacker can craft a malicious branch name or pull request title containing shell metacharacters (such as quotes, semicolons, or command substitution syntax) to break out of the intended command string and execute arbitrary code on the runner [1][2][5]. This is particularly dangerous when the workflow runs on a privileged trigger like pull_request_target, which has access to repository secrets and write permissions [6][7][8]. To prevent these vulnerabilities, follow these security best practices: 1. Never directly interpolate untrusted context data into shell commands [3][9]. 2. Use intermediate environment variables to pass untrusted data into run steps [3][9]. When data is assigned to an environment variable, it is handled safely and does not interact with the shell script generation process [9]. 3. If you must use untrusted input in a script, treat it as a data argument rather than executable code [9]. 4. For privileged workflows, implement gating mechanisms such as requiring manual approval from a maintainer before running jobs on pull requests from forks [10][11]. 5. Minimize the permissions of the GITHUB_TOKEN and avoid using pull_request_target unless absolutely necessary [8][12]. Example of secure implementation: - name: Securely process branch name env: BRANCH_NAME: ${{ github.head_ref }} run: | # The variable is used safely here echo "Processing branch: $BRANCH_NAME"
Citations:
- 1: https://docs.github.com/en/actions/concepts/security/script-injections
- 2: https://securitylab.github.com/resources/github-actions-untrusted-input
- 3: https://orbisappsec.com/blog/critical-shell-injection-flaw-in-github-actions-how-to-secure-your-cicd-20260408
- 4: Security: GitHub Actions script injection via untrusted PR contexts oxsecurity/megalinter#7657
- 5: GHSA-8v8w-v8xg-79rf
- 6: https://synacktiv.com/en/publications/github-actions-exploitation-untrusted-input
- 7: GHSA-7x29-qqmq-v6qc
- 8: https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
- 9: https://docs.github.com/en/actions/reference/security/secure-use
- 10: https://paulserban.eu/blog/post/3-ways-to-secure-your-github-workflows-from-malicious-pull-requests/
- 11: https://www.aikido.dev/blog/checklist-github-actions
- 12: https://openssf.org/blog/2024/08/12/mitigating-attack-vectors-in-github-workflows/
🏁 Script executed:
head -20 .github/workflows/pr-checks.ymlRepository: ColmanDevClubORG/Sagol360Management
Length of output: 422
🏁 Script executed:
sed -n '35,47p' .github/workflows/pr-checks.ymlRepository: ColmanDevClubORG/Sagol360Management
Length of output: 511
Move PR context variables to env to prevent script injection.
Direct interpolation of ${{ github.head_ref }}, ${{ github.base_ref }}, and ${{ github.event.pull_request.number }} into the shell script allows potential script injection if these untrusted values contain shell metacharacters. Assign them to environment variables in the job env block and reference them as shell variables instead.
🔧 Suggested fix
- name: Print environment info
+ env:
+ HEAD_REF: ${{ github.head_ref }}
+ BASE_REF: ${{ github.base_ref }}
+ PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
echo "::group::Environment"
echo "Node version:"
node --version
echo "pnpm version:"
pnpm --version
echo "Current branch:"
- echo "${{ github.head_ref }}"
+ echo "$HEAD_REF"
echo "Target branch:"
- echo "${{ github.base_ref }}"
+ echo "$BASE_REF"
echo "PR number:"
- echo "${{ github.event.pull_request.number }}"
+ echo "$PR_NUMBER"
echo "::endgroup::"🧰 Tools
🪛 actionlint (1.7.12)
[error] 36-36: "github.head_ref" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details
(expression)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/pr-checks.yml around lines 35 - 47, The workflow step
"Print environment info" currently interpolates untrusted values (${ {
github.head_ref }}, ${ { github.base_ref }}, ${ {
github.event.pull_request.number }}) directly into the run script; update the
job to set these three values in the job's env block (e.g., PR_HEAD_REF,
PR_BASE_REF, PR_NUMBER) and then reference them inside the "Print environment
info" step using shell variables ($PR_HEAD_REF, $PR_BASE_REF, $PR_NUMBER)
instead of direct GitHub expression interpolation to prevent script injection.
Description
Please include a summary of the changes and the related issue.
Related Issue(s)
Fixes # (issue number)
Checklist:
Screenshots (if appropriate):
Summary by CodeRabbit