Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
groups:
dev-dependencies:
dependency-type: development
20 changes: 20 additions & 0 deletions .github/workflows/dependabot-auto-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: dependabot-auto-merge
on: pull_request

permissions:
contents: write
pull-requests: write

jobs:
auto-merge:
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify current GitHub Actions best practice for bot verification

rg -n "github\.actor.*dependabot" --glob '*.yml' --glob '*.yaml' -C 3

Repository: azerothcore/Keira3

Length of output: 44


🏁 Script executed:

cat .github/workflows/dependabot-auto-merge.yml

Repository: azerothcore/Keira3

Length of output: 606


🌐 Web query:

GitHub Actions github.actor spoofing security vulnerability dependabot

💡 Result:

The use of github.actor to identify and trust bots like Dependabot in GitHub Actions is considered a security vulnerability, often referred to as a Confused Deputy attack [1][2][3]. The vulnerability exists because github.actor (and github.triggering_actor) represents the user who triggered the specific event for the workflow run, not the immutable author of the pull request [1][4][5]. Attackers can exploit this by triggering bot-related commands (such as @dependabot recreate) or by other means to force a workflow to run with github.actor set to dependabot[bot], even if the underlying code changes in the pull request were submitted by an untrusted user [1][3]. If a workflow uses this condition to grant privileged access—such as auto-merging a pull request—it can lead to the execution of malicious code with the repository's secrets or write permissions [6][2][5]. To secure workflows against this vulnerability, developers should: 1. Never rely solely on github.actor or github.triggering_actor for security-sensitive trust decisions [4][2]. 2. Use immutable, event-specific metadata to verify the source of the change, such as github.event.pull_request.user.login, which confirms the actual author of the pull request [4][3]. 3. For workflows that must interact with bots, implement multi-layered validation, such as checking both the actor and the pull request author, or ensuring the pull request originates from a trusted source branch [3][7]. 4. Consider using specialized tools and security scanners (e.g., zizmor, poutine) that detect spoofable bot-check patterns in your YAML configurations [8][4][2][7]. Relying on github.actor is dangerous because it is mutable and context-dependent, whereas checking the pull request author directly from the event payload provides a more reliable security boundary [1][4].

Citations:


🌐 Web query:

GitHub Actions github.event.pull_request.user secure bot verification

💡 Result:

There is no built-in, automated "secure bot verification" feature for the github.event.pull_request.user context in GitHub Actions. Because data from the github context—including user information—is user-controlled input [1][2], relying on it for security-critical decisions (like auto-merging or granting elevated permissions) is inherently dangerous without secondary validation [3][4]. To securely verify if a pull request author is a trusted bot or user, you must implement defensive programming practices: 1. Never Trust Context Directly: Treat all github.event data as potentially untrusted [1][3]. An attacker can manipulate pull request metadata (e.g., titles, descriptions) to attempt injection attacks [1][4]. 2. Use API-Based Verification: Instead of relying on the context variable alone, use the GitHub REST API within your workflow to verify the actor's identity and permissions [5]. For example, you can use the github.rest.repos.getCollaboratorPermissionLevel endpoint to confirm if the user has specific repository permissions (like maintainer or admin) rather than trusting a simple username check [5]. 3. Verify Bot Identity: If you need to identify a specific bot (e.g., dependabot[bot]), verify its identity explicitly. While you can check the user.type field in the payload (which may show as 'Bot' [5]), this should be combined with other checks, such as verifying the email or specific login name, to prevent spoofing. 4. Use Gated Triggers: For privileged operations, avoid running workflows automatically on pull requests from forks [3]. Utilize the pull_request trigger for unprivileged tasks (like running tests) and a secondary, more secure, or gated mechanism (such as workflow_run triggered by a successful test or a manual approval label) for privileged operations [6][7]. 5. Prevent Injection: If you must use github.event.pull_request.user in scripts, always pass the value through an environment variable instead of interpolating it directly into a run command [1][3][4]. This prevents shell command injection [1][4]. Example of secure pattern: Instead of if: github.event.pull_request.user.login == 'trusted-bot', use an action or script step that queries the GitHub API to confirm the actor's authorization and intent, ensuring that the logic is evaluated against the current state of the repository's access controls [5].

Citations:


Strengthen bot actor verification to prevent spoofing.

The github.actor context can be spoofed by users who name themselves dependabot[bot]. A malicious user could create an account with that name or trigger bot-related commands to force this workflow to run as dependabot[bot], enabling auto-merge of their own pull requests and bypassing review requirements.

However, simply checking github.event.pull_request.user is insufficient, as that metadata is also user-controlled and can be manipulated. Secure alternatives include:

  • Using the GitHub REST API to verify the actor's actual repository permissions
  • Switching to a workflow_run trigger on a successful build from the default branch instead of checking conditions on pull_request
  • Combining checks with gated mechanisms (e.g., requiring explicit labels or approvals) rather than relying on actor/user metadata alone
🧰 Tools
🪛 zizmor (1.25.2)

[error] 11-11: spoofable bot actor check (bot-conditions): actor context may be spoofable

(bot-conditions)

🤖 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/dependabot-auto-merge.yml at line 11, The condition
checking `if: github.actor == 'dependabot[bot]'` is vulnerable to spoofing since
users can create accounts with that name. Replace this actor-based verification
with a more secure approach: either switch the workflow trigger from
`pull_request` to `workflow_run` that only activates on successful builds from
the default branch (which is not under user control), or implement verification
using the GitHub REST API to confirm the actual permissions of the actor, or add
additional gated mechanisms like requiring specific labels or approvals that
cannot be set by users with suspicious actor names. Any of these approaches will
prevent malicious actors from triggering auto-merge of their own pull requests.

Source: Linters/SAST tools

steps:
- name: Fetch metadata
id: meta
uses: dependabot/fetch-metadata@v2

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the latest commit SHA for dependabot/fetch-metadata@v2

gh api repos/dependabot/fetch-metadata/git/refs/tags/v2 --jq '.object.sha' || \
gh api repos/dependabot/fetch-metadata/commits?sha=v2 --jq '.[0].sha'

Repository: azerothcore/Keira3

Length of output: 103


🏁 Script executed:

# Locate and read the dependabot workflow file
fd -type f dependabot-auto-merge.yml

Repository: azerothcore/Keira3

Length of output: 233


🏁 Script executed:

# Check the actual content of the workflow around line 15
if [ -f .github/workflows/dependabot-auto-merge.yml ]; then
  sed -n '10,20p' .github/workflows/dependabot-auto-merge.yml
fi

Repository: azerothcore/Keira3

Length of output: 485


Pin action to a specific SHA for supply chain security.

The action reference uses a mutable tag (@v2) instead of an immutable SHA. If the tag is moved to a malicious commit, this workflow would execute untrusted code with write permissions. Pin to SHA 21025c705c08248db411dc16f3619e6b5f9ea21a:

uses: dependabot/fetch-metadata@21025c705c08248db411dc16f3619e6b5f9ea21a
🧰 Tools
🪛 zizmor (1.25.2)

[error] 15-15: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 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/dependabot-auto-merge.yml at line 15, The
dependabot/fetch-metadata action reference uses a mutable tag (`@v2`) which poses
a supply chain security risk since the tag could be moved to a malicious commit.
Replace the mutable tag with the immutable SHA hash to ensure the workflow
always executes the trusted version. Update the action reference from `@v2` to
`@21025c705c08248db411dc16f3619e6b5f9ea21a` for the dependabot/fetch-metadata
action.

Source: Linters/SAST tools

- name: Enable auto-merge
if: steps.meta.outputs.update-type != 'version-update:semver-major'
run: gh pr merge --auto --squash "${{ github.event.pull_request.html_url }}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use environment variable instead of inline template expansion.

While github.event.pull_request.html_url is controlled by GitHub and should be safe, following the security best practice of avoiding template expansion in shell commands reduces risk and improves code safety.

🛡️ Proposed fix to use environment variable
      - name: Enable auto-merge
        if: steps.meta.outputs.update-type != 'version-update:semver-major'
-       run: gh pr merge --auto --squash "${{ github.event.pull_request.html_url }}"
+       run: gh pr merge --auto --squash "$PR_URL"
        env:
+         PR_URL: ${{ github.event.pull_request.html_url }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
run: gh pr merge --auto --squash "${{ github.event.pull_request.html_url }}"
- name: Enable auto-merge
if: steps.meta.outputs.update-type != 'version-update:semver-major'
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
🧰 Tools
🪛 zizmor (1.25.2)

[error] 18-18: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 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/dependabot-auto-merge.yml at line 18, The gh pr merge
command is directly using template expansion with ${{
github.event.pull_request.html_url }} in the shell command. To follow security
best practices and avoid template expansion in shell commands, add an env
section to the step and define an environment variable (e.g., PR_URL) that
captures the github.event.pull_request.html_url value using template syntax,
then update the run command to reference this environment variable using
standard shell syntax (e.g., $PR_URL) instead of inline template expansion.

Source: Linters/SAST tools

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Loading