Skip to content

Harden maven-workflow-run.yml (pin actions, validate commit_sha, scope token+secrets) — APS security-ai-review - #22

Closed
Rohannagariya1 wants to merge 1 commit into
browserstack:mainfrom
Rohannagariya1:security/aps-gha-hardening-maven-workflow
Closed

Harden maven-workflow-run.yml (pin actions, validate commit_sha, scope token+secrets) — APS security-ai-review#22
Rohannagariya1 wants to merge 1 commit into
browserstack:mainfrom
Rohannagariya1:security/aps-gha-hardening-maven-workflow

Conversation

@Rohannagariya1

@Rohannagariya1 Rohannagariya1 commented Aug 12, 2026

Copy link
Copy Markdown

What & why

Hardens .github/workflows/maven-workflow-run.yml against the GitHub-Actions findings raised by BrowserStack's security-ai-review scan (umbrella APPSEC-409). This is CI/workflow-only — no change to any runtime code, the SDK, or the sample tests, so it cannot affect BrowserStack session behaviour.

Jira: APS-19434 (chain C-001) and the component/chain tickets it closes — see below.

Changes

  1. Pin actions to commit SHAs (was mutable @v3 tags):
    • actions/checkouta37ce91… (v3.7.0)
    • actions/setup-javae9fbacd… (v3.14.2)
    • (actions/github-script was already SHA-pinned.)
  2. Scope the default GITHUB_TOKEN: added a top-level permissions: block (contents: read, checks: write). Previously no block was declared, so the token defaulted to write-all. checks: write is retained because the two github-script steps call checks.create.
  3. Validate commit_sha: new validate-input gate job (permissions: {}) that rejects anything not matching ^[0-9a-f]{40}$ before any checkout/build runs. The value is read from the environment and matched with a bash regex — never interpolated into a shell command — so the check itself is injection-safe. comment-run gates on it via needs:. (Single pre-job instead of an in-job step so the 3×3 matrix doesn't spin up 9 runners for a bad input.)
  4. Move BrowserStack secrets to step level: BROWSERSTACK_USERNAME / BROWSERSTACK_ACCESS_KEY moved from the job-level env: (visible to every step) to step-level env: on the three mvn steps only.
  5. persist-credentials: false on checkout so the token isn't left in .git/config for later steps.

Honest scoping (what this does and does not fix)

  • commit_sha (F-003 / C-001): there is no ${{ … }}run: expression-injection sink in this workflow (the input only reaches checkout's ref: and github-script's env:/process.env, which is the safe pattern). The real exposure is checkout of an unvalidated arbitrary ref; the regex gate constrains that to a real 40-hex SHA. It does not remove the inherent risk that a workflow_dispatch actor (who already needs repo write) can point it at a valid SHA of a malicious commit whose Maven plugins then execute on the runner — that is intrinsic to a "build an arbitrary commit" workflow. Reviewers who want to close that residual should gate this workflow behind a GitHub Environment with required reviewers (a repo setting, intentionally not done here to avoid changing the sample's UX).
  • Check-status spoofing / branch-protection (F-004 / C-004): checks: write is required by the workflow, so a writer can still create a check run for an arbitrary SHA. Dropping contents to read is the correct in-scope mitigation; the complete control is a repo setting — this workflow's check must not be configured as a required status check in branch protection.
  • SDK version = LATEST (F-002 / C-002): handled separately as By-DesignLATEST is BrowserStack's documented, recommended way to declare browserstack-java-sdk, and this sample exists to demonstrate that pattern. Those two tickets are being closed Won't-Do with that rationale rather than pinned here.

Testing

CI-config change; workflow_dispatch can only be exercised after merge. Verified by: (a) yaml.safe_load parses clean, both jobs present, top-level permissions applied; (b) both pinned SHAs independently resolved to their v3.7.0 / v3.14.2 tags via the GitHub API; (c) the regex gate reviewed for injection-safety (env-read + bash [[ =~ ]], rejects multiline). No behavioural change to the Maven test steps themselves.

Tickets closed by this PR

APS-19434 (C-001), APS-19433 (C-003), APS-19441 (C-004), APS-19439 (F-003), APS-19446 (F-004), APS-19440 (F-001), APS-19438 (F-005). APS-19444 (F-002) & APS-19442 (C-002) closed separately as By-Design.

Pin actions to commit SHAs, validate commit_sha (40-hex gate job),
scope GITHUB_TOKEN (contents:read, checks:write), move BrowserStack
secrets to step-level env, persist-credentials:false on checkout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Rohannagariya1
Rohannagariya1 requested a review from a team as a code owner August 12, 2026 11:56
@Rohannagariya1

Copy link
Copy Markdown
Author

Closing — out of scope. java-selenium-browserstack is a customer sample/demo repo (*-browserstack), which is excluded from BrowserStack's security-ai-review remediation process. This PR was raised in error; the associated APS tickets are being closed as Won't-Do (excluded). Apologies for the noise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant