Skip to content
Closed
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
5 changes: 5 additions & 0 deletions .github/workflows/swift-sdk-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ on:
- 'packages/rs-*/**'
- '.github/workflows/swift-sdk-build.yml'

permissions:
contents: read
pull-requests: write
issues: write
Comment on lines +16 to +19
Copy link
Copy Markdown
Contributor

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:

# Check if the dashpay/platform repo has PR `#3137` and its origin
cd /tmp && git clone --depth=1 https://github.com/dashpay/platform.git 2>&1 | head -20

Repository: dashpay/platform

Length of output: 1475


🌐 Web query:

GitHub Actions permissions block fork pull request write access token restrictions official documentation

💡 Result:

  • Default restriction for fork PRs: Workflows triggered by a pull request from a fork run with a read-only GITHUB_TOKEN and do not receive secrets (except GITHUB_TOKEN). [1]
  • Why “write” is blocked: Even if your workflow sets permissions: write-all (or specific write scopes), fork PR workflows typically still can’t get write access—the repo/admin setting overrides this. [2]
  • The admin/owner override (the main switch): A repo/org/enterprise admin can explicitly allow write-capable tokens by enabling “Send write tokens to workflows from pull requests” (and separately can allow secrets). [3]
  • Important exception (pull_request_target): If you use pull_request_target, GitHub grants read/write repo permission to GITHUB_TOKEN even when triggered from a public fork, because the workflow runs in the base repository context (this is powerful and risky if you execute untrusted PR code). [2]

Official docs to cite for this behavior:

  • Fork PR read-only token + no secrets: GitHub “Events that trigger workflows” → Workflows in forked repositories [1]
  • permissions behavior + fork limitation + pull_request_target read/write note: GitHub “Workflow syntax” [2]
  • Admin policy/setting “Send write tokens to workflows from pull requests”: GitHub “Enforcing policies for GitHub Actions…” [3]

Sources: [1] (docs.github.com) [2] (docs.github.com) [3] (docs.github.com)

Citations:


🌐 Web query:

GitHub pull_request_target event workflow write permissions fork security

💡 Result:

pull_request_target is the “privileged” PR trigger in GitHub Actions, and it’s risky with forks because it runs in the base repo context (trusted workflow from the base branch) but is triggered by activity coming from an untrusted fork PR.

What changes vs pull_request (fork security model)

  • pull_request from forks: GITHUB_TOKEN is read-only and no secrets are provided (safe-by-default for untrusted contributions). (docs.github.com)
  • pull_request_target: GITHUB_TOKEN is read/write by default (unless you restrict via permissions:) and the workflow can access secrets, even when triggered from a fork. (docs.github.com)

The core vulnerability (“pwn request”)

If a pull_request_target workflow checks out the PR’s head commit/branch and then builds/tests/executes anything from it, an attacker can run code with base-repo privileges (exfiltrate secrets, push commits, create releases, poison caches, etc.). (docs.github.com)

When pull_request_target is appropriate

Use it only for actions that treat PR content as data, not executable code—e.g., labeling, commenting, triage, metadata updates. (docs.github.com)

Safer patterns

  • Prefer split workflows: run untrusted CI on pull_request, then do privileged actions in a separate workflow triggered by workflow_run. (codeql.github.com)
  • Least-privilege tokens: explicitly set permissions: (don’t rely on defaults), granting only what the job needs. (docs.github.com)
  • If you must gate privileged runs: require a maintainer action (for example, a “safe to test” label) before running anything sensitive—GitHub Security Lab notes this helps but can still have race-condition pitfalls. (securitylab.github.com)

If you share your workflow YAML (especially any actions/checkout usage and permissions: blocks), I can point out the exact fork-to-write escalation paths and how to restructure it safely.

Citations:


🏁 Script executed:

# Check the swift-sdk-build.yml workflow file
cat -n /tmp/platform/.github/workflows/swift-sdk-build.yml | head -30

Repository: dashpay/platform

Length of output: 996


🏁 Script executed:

# Look for PR `#3137` in git history/refs or check recent PRs
cd /tmp/platform && git log --all --oneline --grep="3137" | head -10

Repository: dashpay/platform

Length of output: 42


🏁 Script executed:

# Check if we can get PR details using git 
cd /tmp/platform && git show-ref | grep -i pull | head -20

Repository: dashpay/platform

Length of output: 42


🏁 Script executed:

# Read lines 16-30 to see the permissions block area
cd /tmp/platform && sed -n '16,30p' .github/workflows/swift-sdk-build.yml

Repository: dashpay/platform

Length of output: 441


🏁 Script executed:

# Read lines 170-250 to see the comment step
cd /tmp/platform && sed -n '170,250p' .github/workflows/swift-sdk-build.yml

Repository: dashpay/platform

Length of output: 3677


🏁 Script executed:

# Check git log for recent changes to this workflow
cd /tmp/platform && git log --oneline -10 -- .github/workflows/swift-sdk-build.yml

Repository: dashpay/platform

Length of output: 140


🏁 Script executed:

# Try to find if there are any branches or tags related to PR `#3137`
cd /tmp/platform && git show-ref | grep -E "(3137|swift-sdk-build)" | head -20

Repository: dashpay/platform

Length of output: 42


🏁 Script executed:

# Check if there's a PR branch or recent tag
cd /tmp/platform && git for-each-ref --sort=-creatordate --format='%(refname:short) %(creatordate:short)' refs/ | head -20

Repository: dashpay/platform

Length of output: 129


The permissions block cannot grant write access for external fork PRs—this fix is incomplete.

GitHub's security model mandates that pull requests from public forks always receive a read-only GITHUB_TOKEN, regardless of the permissions block settings in the workflow. This means the added permissions block will only fix the 403 for PRs opened from same-repo branches (i.e., from collaborators with push access).

If PR #3137 originated from an external fork, the issues: write permission will be silently downgraded to read-only by GitHub, and the comment step will continue to fail with a 403.

To reliably post comments for fork PRs, use one of these approaches:

  1. Split workflow (recommended): Create a separate workflow_run-triggered job that runs in the base-repo context:

    • The pull_request job builds artifacts and uploads them (no write needed).
    • A workflow_run job then runs after completion, retrieves the artifact, and posts the comment with write access.
  2. Repository setting: Enable "Send write tokens to workflows from pull requests" in the repo settings. This grants write permissions to fork PR workflows—note that this carries security implications, especially with self-hosted runners.

  3. pull_request_target event: Use pull_request_target instead of pull_request to run in the base-repo context with write access. Only use this if the workflow does not check out and execute untrusted PR code, as it creates a "pwn request" vulnerability.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/swift-sdk-build.yml around lines 16 - 19, The added
permissions block (permissions: / contents: read / pull-requests: write /
issues: write) won't grant write access for PRs from external forks because
GitHub downgrades GITHUB_TOKEN for forked PRs; fix by implementing one of the
recommended approaches: (1) split the workflow: keep the current pull_request
job for building/uploading artifacts (no write needed) and add a separate
workflow triggered by workflow_run in the base-repo context to download the
artifact and post comments, (2) enable the repo-level "Send write tokens to
workflows from pull requests" setting if acceptable, or (3) change the trigger
to pull_request_target only if you ensure the workflow does not check out or
execute untrusted PR code; reference the permissions block, issues: write,
pull_request trigger, workflow_run, and pull_request_target when making the
change.


jobs:
swift-sdk-build:
name: Swift SDK and Example build (warnings as errors)
Expand Down
Loading