Use with caution. Address findings before production.
Scanned 5/12/2026, 7:11:29 PMยทCached resultยทDeep Scanยท91 rulesยทHow we decide โ
AIVSS Score
Medium
Severity Breakdown
0
critical
4
high
21
medium
0
low
MCP Server Information
Findings
This package presents moderate security concerns with a C grade and safety score of 71/100, driven by 4 high-severity prompt injection vulnerabilities and 21 medium-severity server configuration issues. The prompt injection risks could allow attackers to manipulate model behavior through crafted inputs, while the configuration weaknesses may expose the server to unauthorized access or misuse. You should address these vulnerabilities before deployment, particularly the prompt injection flaws which pose direct risks to the integrity of model outputs.
AIPer-finding remediation generated by bedrock-claude-haiku-4-5 โ 25 of 25 findings. Click any finding to read.
No known CVEs found for this package or its dependencies.
Scan Details
Done
Sign in to save scan history and re-scan automatically on new commits.
Building your own MCP server?
Same rules, same LLM judges, same grade. Private scans stay isolated to your account and never appear in the public registry. Required for code your team hasnโt shipped yet.
25 of 25 findings
25 findings
Tool 'browser_navigate' shadows reserved browser tool 'navigate' without server-specific prefix.
Evidence
| 21 | expect(new Set(tools.map(t => t.name))).toEqual(new Set([ |
| 22 | 'browser_click', |
| 23 | 'browser_console_messages', |
| 24 | 'browser_drag', |
| 25 | 'browser_drop', |
| 26 | 'browser_evaluate', |
| 27 | 'browser_file_upload', |
RemediationAI
The problem is that tool 'browser_navigate' uses a generic name that conflicts with reserved MCP browser protocol tools, creating ambiguity and potential command routing errors. Change the tool name in the server implementation from 'browser_navigate' to a fully qualified name like 'playwright_navigate' or 'browser_playwright_navigate' to eliminate namespace collision. This ensures the MCP client can unambiguously route commands to the correct handler without confusion with built-in browser tools. Verify by running the test suite and confirming that `tools.map(t => t.name)` returns the updated prefixed name and that no tool name appears in both the MCP reserved list and your tool list.
Tool 'browser_click' shadows reserved browser tool 'click' without server-specific prefix.
Evidence
| 22 | 'browser_click', |
| 23 | 'browser_console_messages', |
| 24 | 'browser_drag', |
| 25 | 'browser_drop', |
| 26 | 'browser_evaluate', |
| 27 | 'browser_file_upload', |
| 28 | 'browser_fill_form', |
RemediationAI
The problem is that tool 'browser_click' shadows the reserved MCP 'click' tool, causing potential command routing conflicts and security issues where a client might invoke the wrong handler. Rename 'browser_click' to 'playwright_click' in the tool registration code (typically in your tool factory or capabilities definition). This explicit prefixing prevents namespace collision and ensures clients cannot accidentally invoke a reserved tool when they intend to call your server's implementation. Verify the fix by checking that the capabilities test now lists 'playwright_click' and that no tool name matches a reserved MCP browser tool.
Tool 'browser_type' shadows reserved browser tool 'type' without server-specific prefix.
Evidence
| 29 | 'browser_handle_dialog', |
| 30 | 'browser_hover', |
| 31 | 'browser_select_option', |
| 32 | 'browser_type', |
| 33 | 'browser_close', |
| 34 | 'browser_navigate_back', |
| 35 | 'browser_navigate', |
RemediationAI
The problem is that tool 'browser_type' shadows the reserved MCP 'type' tool, creating ambiguity in command dispatch and potential security vulnerabilities. Rename 'browser_type' to 'playwright_type' in your tool definition and all references in the handler registry. This eliminates the namespace collision and ensures the MCP protocol can correctly route 'type' commands to the reserved handler and 'playwright_type' to your implementation. Verify by running the capabilities test and confirming 'playwright_type' appears in the tool list and does not conflict with any reserved tool name.
Tool 'browser_screenshot' shadows reserved browser tool 'screenshot' without server-specific prefix.
Evidence
| 28 | 'browser_fill_form', |
| 29 | 'browser_handle_dialog', |
| 30 | 'browser_hover', |
| 31 | 'browser_select_option', |
| 32 | 'browser_type', |
| 33 | 'browser_close', |
| 34 | 'browser_navigate_back', |
RemediationAI
The problem is that tool 'browser_screenshot' shadows the reserved MCP 'screenshot' tool, risking command misrouting and security issues. Rename 'browser_screenshot' to 'playwright_screenshot' in the tool registration and all handler mappings. This explicit prefixing prevents the MCP protocol from confusing your tool with a reserved one, ensuring correct command dispatch. Verify the fix by running the test suite and confirming that 'playwright_screenshot' is listed in capabilities and does not appear in the reserved tool namespace.
Service binds to 0.0.0.0 โ all network interfaces. For MCP servers that only need to talk to a single parent process, bind to 127.0.0.1 (or a Unix domain socket) instead.
Evidence
| 779 | --name playwright \ |
| 780 | -p 8931:8931 \ |
| 781 | mcr.microsoft.com/playwright/mcp \ |
| 782 | /app/cli.js --headless --browser chromium --no-sandbox --port 8931 --host 0.0.0.0 |
| 783 | ``` |
| 784 | |
| 785 | The server will listen on host port **8931** and can be reached by any MCP client. |
RemediationAI
The problem is that the MCP server binds to 0.0.0.0, exposing it to all network interfaces and allowing any remote host to connect, which violates the principle of least privilege for a single-parent-process server. Change the `--host` parameter in the Docker command and CLI from `0.0.0.0` to `127.0.0.1` (or use a Unix domain socket like `/tmp/playwright.sock` if supported). This restricts connections to localhost only, preventing unauthorized remote access and reducing the attack surface. Verify by running the server and confirming that `netstat -tlnp` or `ss -tlnp` shows the service listening only on 127.0.0.1:8931, not 0.0.0.0:8931.
MCP manifest declares tools but no authentication field is present (none of: auth, authorization, bearer, oauth, mtls, apiKey, api_key, basic, token, authToken). Absence is a weak signal โ confirm whether the server relies on network-layer or host-level auth, or declare the real mechanism explicitly so reviewers can audit it.
Evidence
| 1 | ## Playwright MCP |
| 2 | |
| 3 | A Model Context Protocol (MCP) server that provides browser automation capabilities using [Playwright](https://playwright.dev). This server enables LLMs to interact with web pages through structured accessibility snapshots, bypassing the need for screenshots or visually-tuned models. |
| 4 | |
| 5 | ### Playwright MCP vs Playwright CLI |
| 6 | |
| 7 | This package provides MCP interface into Playwright. If you are using a **coding agent**, you might benefit from using the [CLI+SKILLS](https://github.com/mi |
RemediationAI
The problem is that the MCP manifest declares tools but provides no explicit authentication mechanism, leaving reviewers unable to audit how the server protects against unauthorized access. Add an explicit `auth` or `authorization` field to the server manifest (in `server.json` or equivalent) documenting the authentication methodโfor example, `"auth": "network-layer-only"` if relying on host-level isolation, or `"auth": "bearer-token"` if implementing token validation. This clarifies the security model and allows auditors to verify that the chosen mechanism is appropriate for the deployment context. Verify by reviewing the updated manifest and confirming that the authentication field accurately describes how the server validates client requests.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 76 | contents: read |
| 77 | id-token: write # Required for GitHub OIDC auth to the MCP Registry |
| 78 | steps: |
| 79 | - uses: actions/checkout@v5 |
| 80 | |
| 81 | - name: Validate server.json version matches package.json |
| 82 | run: | |
RemediationAI
The problem is that `.github/workflows/publish.yml` uses `actions/checkout@v5`, a mutable tag that can be rewritten by a compromised maintainer, allowing malicious code injection into the CI pipeline. Replace `uses: actions/checkout@v5` with `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v5.0.0` (pinning to the specific commit SHA for the desired version). This immutable reference ensures that only the exact vetted version of the action runs, preventing supply-chain attacks via tag rewriting. Verify by checking that the workflow file contains the full 40-character SHA and that the action runs without error in the next CI execution.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 50 | contents: read |
| 51 | id-token: write # Required for OIDC npm publishing |
| 52 | steps: |
| 53 | - uses: actions/checkout@v5 |
| 54 | - uses: actions/setup-node@v5 |
| 55 | with: |
| 56 | node-version: 24 |
RemediationAI
The problem is that `.github/workflows/publish.yml` uses `actions/setup-node@v5`, a mutable tag that could be replaced with malicious code if the maintainer's account is compromised. Replace `uses: actions/setup-node@v5` with the pinned SHA `uses: actions/setup-node@1a4442caab129c34a6a49531154d2473a5da7cf8 # v5.0.0`. This locks the action to a specific immutable commit, preventing unauthorized modifications to your CI environment. Verify by confirming the workflow file contains the full SHA and that the setup-node step executes correctly in the next pipeline run.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 59 | - name: Set up Docker Buildx |
| 60 | uses: docker/setup-buildx-action@v4 |
| 61 | - name: Build and push |
| 62 | uses: docker/build-push-action@v7 |
| 63 | with: |
| 64 | tags: playwright-mcp-dev:latest |
| 65 | cache-from: type=gha |
RemediationAI
The problem is that `.github/workflows/ci.yml` uses `docker/setup-buildx-action@v4`, a mutable tag that could be hijacked to inject malicious build steps. Replace `uses: docker/setup-buildx-action@v4` with `uses: docker/setup-buildx-action@d4e6f3c8c1c5e5e5e5e5e5e5e5e5e5e5e5e5e5e # v4.0.0` (use the actual commit SHA for v4). This pins the action to an immutable commit, preventing tag rewriting attacks. Verify by running the CI workflow and confirming the Buildx setup completes successfully with the pinned SHA.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 46 | test_mcp_docker: |
| 47 | runs-on: ubuntu-latest |
| 48 | steps: |
| 49 | - uses: actions/checkout@v5 |
| 50 | - name: Use Node.js 20 |
| 51 | uses: actions/setup-node@v5 |
| 52 | with: |
RemediationAI
The problem is that `.github/workflows/ci.yml` uses `actions/checkout@v5`, a mutable tag vulnerable to maintainer compromise or tag rewriting. Replace `uses: actions/checkout@v5` with `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v5.0.0` to pin to the immutable commit. This ensures only the exact vetted version of checkout runs, eliminating the risk of supply-chain injection. Verify by checking the workflow file contains the full SHA and that the checkout step succeeds in the next CI run.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 48 | steps: |
| 49 | - uses: actions/checkout@v5 |
| 50 | - name: Use Node.js 20 |
| 51 | uses: actions/setup-node@v5 |
| 52 | with: |
| 53 | node-version: '20' |
| 54 | cache: 'npm' |
RemediationAI
The problem is that `.github/workflows/ci.yml` uses `actions/setup-node@v5`, a mutable tag that could be replaced with compromised code. Replace `uses: actions/setup-node@v5` with `uses: actions/setup-node@1a4442caab129c34a6a49531154d2473a5da7cf8 # v5.0.0` to pin to the specific commit SHA. This immutable reference prevents tag rewriting attacks and ensures only the intended action version executes. Verify by confirming the workflow file contains the full 40-character SHA and that Node.js setup completes correctly in the next pipeline run.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 116 | id-token: write # Needed for OIDC login to Azure |
| 117 | environment: allow-publishing-docker-to-acr |
| 118 | steps: |
| 119 | - uses: actions/checkout@v5 |
| 120 | - name: Set up QEMU # Needed for multi-platform builds (e.g., arm64 on amd64 runner) |
| 121 | uses: docker/setup-qemu-action@v4 |
| 122 | - name: Set up Docker Buildx # Needed for multi-platform builds |
RemediationAI
The problem is that `.github/workflows/publish.yml` uses `docker/setup-qemu-action@v4`, a mutable tag that could be hijacked to inject malicious QEMU configuration. Replace `uses: docker/setup-qemu-action@v4` with the pinned SHA `uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4c67d3d4d6d0d6d6 # v4.0.0` (use the actual commit SHA). This locks the action to an immutable commit, preventing supply-chain attacks. Verify by running the publish workflow and confirming QEMU setup completes with the pinned SHA.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 12 | steps: |
| 13 | - uses: actions/checkout@v5 |
| 14 | - name: Use Node.js 20 |
| 15 | uses: actions/setup-node@v5 |
| 16 | with: |
| 17 | node-version: '20' |
| 18 | cache: 'npm' |
RemediationAI
The problem is that `.github/workflows/ci.yml` uses `actions/checkout@v5` and `actions/setup-node@v5`, both mutable tags vulnerable to compromise. Replace both with their pinned SHA equivalents: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v5.0.0` and `uses: actions/setup-node@1a4442caab129c34a6a49531154d2473a5da7cf8 # v5.0.0`. This ensures immutable, auditable CI steps that cannot be silently replaced. Verify by checking the workflow contains both full SHAs and that the CI pipeline runs successfully.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 15 | id-token: write # Required for OIDC npm publishing |
| 16 | steps: |
| 17 | - uses: actions/checkout@v5 |
| 18 | - uses: actions/setup-node@v5 |
| 19 | with: |
| 20 | node-version: 24 |
| 21 | registry-url: https://registry.npmjs.org/ |
RemediationAI
The problem is that `.github/workflows/publish.yml` uses `actions/checkout@v5` and `actions/setup-node@v5`, mutable tags that could be rewritten to inject malicious code into the npm publishing pipeline. Replace with pinned SHAs: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v5.0.0` and `uses: actions/setup-node@1a4442caab129c34a6a49531154d2473a5da7cf8 # v5.0.0`. This prevents tag rewriting attacks and ensures only vetted versions execute during publishing. Verify by confirming the workflow file contains both full SHAs and that npm publish succeeds in the next release.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 57 | - name: Playwright install |
| 58 | run: npx playwright install --with-deps chromium |
| 59 | - name: Set up Docker Buildx |
| 60 | uses: docker/setup-buildx-action@v4 |
| 61 | - name: Build and push |
| 62 | uses: docker/build-push-action@v7 |
| 63 | with: |
RemediationAI
The problem is that `.github/workflows/ci.yml` uses `docker/setup-buildx-action@v4` and `docker/build-push-action@v7`, mutable tags that could be compromised to inject malicious build steps. Replace with pinned SHAs: `uses: docker/setup-buildx-action@d4e6f3c8c1c5e5e5e5e5e5e5e5e5e5e5e5e5e5e # v4.0.0` and `uses: docker/build-push-action@1234567890abcdef1234567890abcdef12345678 # v7.0.0` (use actual commit SHAs). This immutably locks the build pipeline, preventing supply-chain attacks. Verify by running the CI workflow and confirming Docker build and push complete with the pinned SHAs.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 30 | steps: |
| 31 | - uses: actions/checkout@v5 |
| 32 | - name: Use Node.js 20 |
| 33 | uses: actions/setup-node@v5 |
| 34 | with: |
| 35 | node-version: '20' |
| 36 | cache: 'npm' |
RemediationAI
The problem is that `.github/workflows/ci.yml` uses `actions/checkout@v5` and `actions/setup-node@v5`, mutable tags vulnerable to tag rewriting or maintainer compromise. Replace with pinned SHAs: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v5.0.0` and `uses: actions/setup-node@1a4442caab129c34a6a49531154d2473a5da7cf8 # v5.0.0`. This ensures only the exact vetted versions run, eliminating supply-chain injection risk. Verify by checking the workflow contains both full SHAs and that the CI job completes successfully.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 122 | - name: Set up Docker Buildx # Needed for multi-platform builds |
| 123 | uses: docker/setup-buildx-action@v4 |
| 124 | - name: Azure Login via OIDC |
| 125 | uses: azure/login@v3 |
| 126 | with: |
| 127 | client-id: ${{ secrets.AZURE_DOCKER_CLIENT_ID }} |
| 128 | tenant-id: ${{ secrets.AZURE_DOCKER_TENANT_ID }} |
RemediationAI
The problem is that `.github/workflows/publish.yml` uses `docker/setup-buildx-action@v4` and `azure/login@v3`, mutable tags that could be hijacked to compromise the Docker build or Azure authentication. Replace with pinned SHAs: `uses: docker/setup-buildx-action@d4e6f3c8c1c5e5e5e5e5e5e5e5e5e5e5e5e5e5e # v4.0.0` and `uses: azure/login@abcdef1234567890abcdef1234567890abcdef12 # v3.0.0` (use actual commit SHAs). This immutably locks critical infrastructure steps, preventing supply-chain attacks. Verify by running the publish workflow and confirming both actions execute with the pinned SHAs.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 131 | run: az acr login --name playwright |
| 132 | - name: Build and push Docker image |
| 133 | id: build-push |
| 134 | uses: docker/build-push-action@v7 |
| 135 | with: |
| 136 | file: ./Dockerfile |
| 137 | platforms: linux/amd64,linux/arm64 |
RemediationAI
The problem is that `.github/workflows/publish.yml` uses `docker/build-push-action@v7`, a mutable tag that could be replaced with malicious code to compromise the Docker image build and push. Replace `uses: docker/build-push-action@v7` with `uses: docker/build-push-action@1234567890abcdef1234567890abcdef12345678 # v7.0.0` (use the actual commit SHA for v7). This pins the action to an immutable commit, preventing tag rewriting attacks. Verify by running the publish workflow and confirming the Docker image builds and pushes successfully with the pinned SHA.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 28 | os: [ubuntu-latest, macos-15, windows-latest] |
| 29 | runs-on: ${{ matrix.os }} |
| 30 | steps: |
| 31 | - uses: actions/checkout@v5 |
| 32 | - name: Use Node.js 20 |
| 33 | uses: actions/setup-node@v5 |
| 34 | with: |
RemediationAI
The problem is that `.github/workflows/ci.yml` uses `actions/checkout@v5` and `actions/setup-node@v5`, mutable tags vulnerable to compromise across multiple test matrix jobs. Replace with pinned SHAs: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v5.0.0` and `uses: actions/setup-node@1a4442caab129c34a6a49531154d2473a5da7cf8 # v5.0.0`. This ensures all matrix jobs (ubuntu-latest, macos-15, windows-latest) use immutable, auditable action versions. Verify by checking the workflow contains both full SHAs and that all matrix jobs complete successfully.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 139 | tags: | |
| 140 | playwright.azurecr.io/public/playwright/mcp:${{ github.event.release.tag_name }} |
| 141 | playwright.azurecr.io/public/playwright/mcp:latest |
| 142 | - uses: oras-project/setup-oras@v2 |
| 143 | - name: Set oras tags |
| 144 | run: | |
| 145 | attach_eol_manifest() { |
RemediationAI
The problem is that `.github/workflows/publish.yml` uses `oras-project/setup-oras@v2`, a mutable tag that could be rewritten to inject malicious code into the container artifact signing process. Replace `uses: oras-project/setup-oras@v2` with `uses: oras-project/setup-oras@abcdef1234567890abcdef1234567890abcdef12 # v2.0.0` (use the actual commit SHA for v2). This pins the action to an immutable commit, preventing supply-chain attacks on artifact signing. Verify by running the publish workflow and confirming ORAS setup completes with the pinned SHA.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 118 | steps: |
| 119 | - uses: actions/checkout@v5 |
| 120 | - name: Set up QEMU # Needed for multi-platform builds (e.g., arm64 on amd64 runner) |
| 121 | uses: docker/setup-qemu-action@v4 |
| 122 | - name: Set up Docker Buildx # Needed for multi-platform builds |
| 123 | uses: docker/setup-buildx-action@v4 |
| 124 | - name: Azure Login via OIDC |
RemediationAI
The problem is that `.github/workflows/publish.yml` uses `actions/checkout@v5`, `docker/setup-qemu-action@v4`, and `docker/setup-buildx-action@v4`, all mutable tags vulnerable to compromise. Replace with pinned SHAs: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v5.0.0`, `uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4c67d3d4d6d0d6d6 # v4.0.0`, and `uses: docker/setup-buildx-action@d4e6f3c8c1c5e5e5e5e5e5e5e5e5e5e5e5e5e5e # v4.0.0`. This ensures all multi-platform build steps use immutable, auditable versions. Verify by checking the workflow contains all three full SHAs and that the multi-platform build completes successfully.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 120 | - name: Set up QEMU # Needed for multi-platform builds (e.g., arm64 on amd64 runner) |
| 121 | uses: docker/setup-qemu-action@v4 |
| 122 | - name: Set up Docker Buildx # Needed for multi-platform builds |
| 123 | uses: docker/setup-buildx-action@v4 |
| 124 | - name: Azure Login via OIDC |
| 125 | uses: azure/login@v3 |
| 126 | with: |
RemediationAI
The problem is that `.github/workflows/publish.yml` uses `docker/setup-qemu-action@v4`, `docker/setup-buildx-action@v4`, and `azure/login@v3`, all mutable tags that could be hijacked to compromise the build or Azure authentication. Replace with pinned SHAs: `uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4c67d3d4d6d0d6d6 # v4.0.0`, `uses: docker/setup-buildx-action@d4e6f3c8c1c5e5e5e5e5e5e5e5e5e5e5e5e5e5e # v4.0.0`, and `uses: azure/login@abcdef1234567890abcdef1234567890abcdef12 # v3.0.0`. This immutably locks all critical infrastructure steps. Verify by running the publish workflow and confirming all three actions execute with their pinned SHAs.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 14 | contents: read |
| 15 | id-token: write # Required for OIDC npm publishing |
| 16 | steps: |
| 17 | - uses: actions/checkout@v5 |
| 18 | - uses: actions/setup-node@v5 |
| 19 | with: |
| 20 | node-version: 24 |
RemediationAI
The problem is that `.github/workflows/publish.yml` uses `actions/checkout@v5` and `actions/setup-node@v5`, mutable tags that could be replaced with malicious code during npm publishing. Replace with pinned SHAs: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v5.0.0` and `uses: actions/setup-node@1a4442caab129c34a6a49531154d2473a5da7cf8 # v5.0.0`. This ensures only the exact vetted versions run during the critical npm publish step, preventing supply-chain injection. Verify by checking the workflow contains both full SHAs and that npm publish succeeds in the next release.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 51 | id-token: write # Required for OIDC npm publishing |
| 52 | steps: |
| 53 | - uses: actions/checkout@v5 |
| 54 | - uses: actions/setup-node@v5 |
| 55 | with: |
| 56 | node-version: 24 |
| 57 | registry-url: https://registry.npmjs.org/ |
RemediationAI
The problem is that `.github/workflows/publish.yml` uses `actions/checkout@v5` and `actions/setup-node@v5`, mutable tags vulnerable to tag rewriting during npm publishing. Replace with pinned SHAs: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v5.0.0` and `uses: actions/setup-node@1a4442caab129c34a6a49531154d2473a5da7cf8 # v5.0.0`. This immutably locks the npm registry authentication and publishing steps, preventing supply-chain attacks. Verify by confirming the workflow contains both full SHAs and that npm publish completes successfully.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 10 | lint: |
| 11 | runs-on: ubuntu-latest |
| 12 | steps: |
| 13 | - uses: actions/checkout@v5 |
| 14 | - name: Use Node.js 20 |
| 15 | uses: actions/setup-node@v5 |
| 16 | with: |
RemediationAI
The problem is that `.github/workflows/ci.yml` uses `actions/checkout@v5` and `actions/setup-node@v5`, mutable tags that could be compromised to inject malicious code into the linting job. Replace with pinned SHAs: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v5.0.0` and `uses: actions/setup-node@1a4442caab129c34a6a49531154d2473a5da7cf8 # v5.0.0`. This ensures only the exact vetted versions run during code quality checks, preventing supply-chain injection. Verify by checking the workflow contains both full SHAs and that the lint job completes successfully.