Skip to content

R-CMD-check and pkgdown workflows run arbitrary code without a minimal permissions:` block #508

Description

@docxology

Channel: public issue · Severity: medium (least-privilege hardening)


Two workflows execute the test suite, examples, and dependency code — including the unpinned Remotes dependencies — with the default (often write-capable) GITHUB_TOKEN scope, because they declare no top-level permissions:.

What happens

(HEAD 43b352f / main 7d8539b)

  • .github/workflows/R-CMD-check.yaml and .github/workflows/pkgdown.yaml declare no top-level permissions:.
  • By contrast, pr-commands.yaml:9 (permissions: read-all) and doc-preview.yaml:7 do set least-privilege blocks — so the pattern exists in-repo, just not on the two highest-code-execution workflows.
  • R-CMD-check runs with GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} (:17) and the Epidata API key (:33) in the job environment; check-r-package executes tests, man-page examples, and vignette builds — i.e. arbitrary dependency code (see the unpinned-Remotes issue).

Repro

Static inspection: on push/pull_request triggers, workflows without a permissions: block get the repo default token permissions, which for many repos includes write scopes.

Impact

Least-privilege violation amplifying the unpinned-dependency risk: compromised dependency code executed by check-r-package or build_site would inherit the default token context.

Suggested fix

Add a top-level permissions: read-all to both workflows (mirroring pr-commands.yaml/doc-preview.yaml), plus narrow per-job scopes where a job needs more.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions