Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
update branach handling move action file to templates
  • Loading branch information
witmicko committed Dec 9, 2025
commit 27e6a8321b2db564983e3b9a0358c3d33d049852
3 changes: 3 additions & 0 deletions .github/templates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This directory contains templates for onboarding PRs that add the Security Code
## Templates

### `onboarding-pr-body-manual.md`

**Use for:** Manual PRs created by the security team

- More detailed with full language configuration examples
Expand All @@ -13,6 +14,7 @@ This directory contains templates for onboarding PRs that add the Security Code
- No auto-merge disclaimer

### `onboarding-pr-body-automated.md`

**Use for:** Automated PRs created by workflows

- Shorter, more concise
Expand All @@ -29,6 +31,7 @@ Both templates support variable substitution:
## Usage

**Manual PRs:**

```bash
# Copy and paste from onboarding-pr-body-manual.md
# Replace {{SECURITY_SCANNING_URL}} with actual URL
Expand Down
7 changes: 6 additions & 1 deletion .github/templates/onboarding-pr-body-automated.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
**This PR may be auto-merged in the future if not configured.**

If your team does not need the security scanner:

1. **Add a comment on this PR** explaining why your team is opting out
2. **Close this PR** to prevent auto-merge
3. **Add a `.github/no-security-scanner` file** to your repository to prevent future onboarding attempts
Copy link

Choose a reason for hiding this comment

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

Bug: Opt-out file documented but never checked in workflow

The PR body template instructs teams to add a .github/no-security-scanner file to "prevent future onboarding attempts", but the workflow never actually checks for this file before proceeding with onboarding. This means the documented opt-out mechanism doesn't work - repositories that have added the file will still receive onboarding PRs.

Additional Locations (1)

Fix in Cursor Fix in Web


If you need the scanner but want to customize it:

1. Complete the checklist below
2. Review and modify the workflow file as needed
3. Approve and merge this PR when ready
Expand All @@ -19,6 +21,7 @@ If no action is taken, this PR may be automatically merged after a grace period
## Required Action

Prior to merging this pull request, please ensure the following has been completed:

- [ ] The lines specifying `branches` correctly specify this repository's default branch (usually `main` or `master`).
- [ ] Any paths you would like to ignore have been added to the `paths-ignored` configuration option (see [setup](https://github.com/MetaMask/action-security-code-scanner/blob/main/README.md#setup))
- [ ] Language configuration has been reviewed - ignore falsely detected languages or add build commands for Java/Kotlin if needed (see Configuration section below)
Expand Down Expand Up @@ -84,10 +87,12 @@ The scanner auto-detects languages in your repository. If you need to customize
For more configuration options, please review the tool's [README](https://github.com/MetaMask/action-security-code-scanner/blob/main/README.md).

Optional secrets that can be configured:

- `SECURITY_SCAN_METRICS_TOKEN` - for metrics collection
- `APPSEC_BOT_SLACK_WEBHOOK` - for Slack notifications

For any additional questions, please reach out to `@app-sec` in Slack.

---
🤖 *This PR was automatically created by the MetaMask Security onboarding system*

🤖 _This PR was automatically created by the MetaMask Security onboarding system_
51 changes: 51 additions & 0 deletions .github/templates/security-code-scanner.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: MetaMask Security Code Scanner

on:
push:
branches:
- { DEFAULT_BRANCH }
pull_request:
branches:
- { DEFAULT_BRANCH }
workflow_call:
secrets:
SECURITY_SCAN_METRICS_TOKEN:
required: false
APPSEC_BOT_SLACK_WEBHOOK:
required: false
workflow_dispatch:

jobs:
security-scan:
uses: MetaMask/action-security-code-scanner/.github/workflows/security-scan.yml@v2
permissions:
actions: read
contents: read
security-events: write
with:
repo: ${{ github.repository }}
scanner-ref: 'v2'
paths-ignored: |
node_modules
**/node_modules/**
**/__snapshots__/**
__snapshots_linux__
**/__stories__/**
.storybook/
**/*.test.ts
**/*.test.tsx
**/*.test.js
**/*.test.jsx
**/*.spec.ts
**/*.spec.tsx
**/*.spec.js
**/*.spec.jsx
**/test*/**
**/e2e/**
**/tests/**
languages-config: |
[
]
secrets:
project-metrics-token: ${{ secrets.SECURITY_SCAN_METRICS_TOKEN }}
slack-webhook: ${{ secrets.APPSEC_BOT_SLACK_WEBHOOK }}
17 changes: 8 additions & 9 deletions .github/workflows/onboard-new-repo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,13 @@ jobs:
ORG="${{ github.event.client_payload.organization }}"
REPO_NAME="${{ github.event.client_payload.repository }}"
Copy link

Choose a reason for hiding this comment

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

Bug: Script injection via unsanitized repository_dispatch payload

The workflow directly interpolates github.event.client_payload.organization and github.event.client_payload.repository into shell commands using ${{ }} syntax. Since repository_dispatch payloads can be controlled by external actors (anyone with a token that has write access), a malicious payload containing shell metacharacters like backticks or $() would execute arbitrary commands during workflow runs. This is a documented GitHub Actions script injection vulnerability pattern. Values should be passed via environment variables rather than direct interpolation.

Fix in Cursor Fix in Web

REPO="$ORG/$REPO_NAME"
Copy link

Choose a reason for hiding this comment

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

Bug: Unsanitized repository_dispatch payload enables command injection

Values from github.event.client_payload.organization and github.event.client_payload.repository are used directly in shell commands via ${{ }} expression syntax. Since repository_dispatch events can be triggered by external webhooks with arbitrary payloads, a malicious actor could inject shell commands through these fields. The values are used in API calls, git operations, and file paths without any validation or sanitization.

Fix in Cursor Fix in Web

BASE_BRANCH="${{ github.event.client_payload.base_branch }}"
else
REPO="${{ inputs.organization }}/${{ inputs.repository }}"
Copy link

Choose a reason for hiding this comment

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

Bug: Shell command injection via unsanitized user inputs

The workflow directly interpolates user-controlled values from github.event.client_payload.organization, github.event.client_payload.repository, inputs.organization, and inputs.repository into shell commands using ${{ }} syntax. This is a known GitHub Actions security vulnerability allowing shell command injection. The repository_dispatch event's client_payload can be sent by anyone with repository access, and malicious values like foo; malicious_command would execute arbitrary commands. The safer approach is to pass these values through environment variables.

Fix in Cursor Fix in Web

BASE_BRANCH=""
fi

# If base_branch is not set, detect it from the repository
if [ -z "$BASE_BRANCH" ]; then
echo "Detecting default branch for $REPO..."
BASE_BRANCH=$(gh api "repos/$REPO" --jq '.default_branch')
fi
# Auto-detect default branch from the repository
echo "Detecting default branch for $REPO..."
BASE_BRANCH=$(gh api "repos/$REPO" --jq '.default_branch')

echo "repository=$REPO" >> "$GITHUB_OUTPUT"
echo "base_branch=$BASE_BRANCH" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -71,8 +67,11 @@ jobs:
# Create .github/workflows directory if it doesn't exist
mkdir -p .github/workflows

# Copy the security scanner workflow template
cp ../scanner-repo/examples/security-code-scanner.yml .github/workflows/security-code-scanner.yml
# Copy the security scanner workflow template and replace placeholders
BASE_BRANCH="${{ steps.target.outputs.base_branch }}"
sed "s/{ DEFAULT_BRANCH }/$BASE_BRANCH/g" \
../scanner-repo/.github/templates/security-code-scanner.yml \
> .github/workflows/security-code-scanner.yml
Copy link

Choose a reason for hiding this comment

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

Bug: sed fails when branch name contains forward slashes

The sed command uses / as a delimiter when substituting { DEFAULT_BRANCH } with $BASE_BRANCH. If the default branch name contains a forward slash (e.g., release/main or feature/default), the substitution will fail because the / in the branch name will be interpreted as a sed delimiter. Using a different delimiter like | or # would handle this edge case.

Fix in Cursor Fix in Web

Copy link

Choose a reason for hiding this comment

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

Bug: Sed command breaks on branch names containing slashes

The sed command uses / as the delimiter when replacing { DEFAULT_BRANCH } with $BASE_BRANCH. If the default branch name contains a / character (e.g., release/main or develop/stable), the sed substitution will fail or produce incorrect output because the / in the branch name will be interpreted as a delimiter boundary.

Fix in Cursor Fix in Web


git add .github/workflows/security-code-scanner.yml
git commit -m "chore: add MetaMask Security Code Scanner workflow
Expand Down
4 changes: 2 additions & 2 deletions examples/security-code-scanner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ jobs:
paths-ignored: |
node_modules
**/node_modules/**
**/__snapshots__/
**/__snapshots__/**
__snapshots_linux__
**/__stories__/
**/__stories__/**
.storybook/
**/*.test.ts
**/*.test.tsx
Expand Down
Loading