GitHub Artifact Download from Cross-Fork Workflow


Description

The "download artifacts" API, and various custom actions encapsulating it, doesn't differentiate between artifacts that were uploaded by forked repositories and base repositories, which could lead privileged workflows to download artifacts that were created by forked repositories and that are potentially poisoned.

Query

Detection:
  - Group:
      - ID: CrossForkWorkflowRun
        RuleID: GitHub.CrossFork.Workflow.Run
      - ID: ArtifactDownload
        RuleID: GitHub.Webhook.WorkflowArtifactDownload
    MatchCriteria:
      field_name:
        - GroupID: CrossForkWorkflowRun
          Match: workflow_run.id
        - GroupID: ArtifactDownload
          Match: workflow_job.run_id
    EventEvaluationOrder: Chronological
    LookbackWindowMinutes: 1800
    Schedule:
      RateMinutes: 1440
      TimeoutMinutes: 10

Rule dependencies

Higher-order rule. It fires on other rules' alerts, not on raw events, so it cannot fire on its own. Deploy the rules it depends on too.

Depends on

Analyst notes

  1. Consider ensuring that the artifact download job uses the specific run_id for the generated artifact. It is recommended to specify which run id or commit hash to download the artifact from.
  2. Consider filtering out artifacts created from pull requests.
  3. Consider limiting the possibility for outside collaborators to trigger workflows.
  4. Sanitize cross-fork contents.
Raw source GitHub Artifact Download from Cross-Fork Workflow · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: correlation_rule
RuleID: "GitHub.ArtifactDownload.FROM.CrossFork.Workflow"
DisplayName: "GitHub Artifact Download from Cross-Fork Workflow"
Enabled: false
Severity: Medium
Tags:
  - CI/CD
  - Workflow
  - Supply Chain
  - Artifact Poisoning
Reports:
  MITRE ATT&CK:
    - TA0001:T1195.002  # Supply Chain Compromise: Compromise Software Supply Chain
    - TA0002:T1072  # Execution: Software Deployment Tools
    - TA0004:T1134  # Privilege Escalation: Access Token Manipulation
Description: >
  The "download artifacts" API, and various custom actions encapsulating it,
  doesn't differentiate between artifacts that were uploaded by forked repositories 
  and base repositories, which could lead privileged workflows to download artifacts
  that were created by forked repositories and that are potentially poisoned.
Runbook: |
  1. Consider ensuring that the artifact download job uses the specific run_id for the generated artifact. 
     It is recommended to specify which run id or commit hash to download the artifact from.
  2. Consider filtering out artifacts created from pull requests.
  3. Consider limiting the possibility for outside collaborators to trigger workflows.
  4. Sanitize cross-fork contents.
Reference: https://www.legitsecurity.com/blog/artifact-poisoning-vulnerability-discovered-in-rust
Detection:
  - Group:
      - ID: CrossForkWorkflowRun
        RuleID: GitHub.CrossFork.Workflow.Run
      - ID: ArtifactDownload
        RuleID: GitHub.Webhook.WorkflowArtifactDownload
    MatchCriteria:
      field_name:
        - GroupID: CrossForkWorkflowRun
          Match: workflow_run.id
        - GroupID: ArtifactDownload
          Match: workflow_job.run_id
    EventEvaluationOrder: Chronological
    LookbackWindowMinutes: 1800
    Schedule:
      RateMinutes: 1440
      TimeoutMinutes: 10
Tests:
  - Name: cross-fork workflow with artifact download
    ExpectedResult: true
    RuleOutputs:
      - ID: CrossForkWorkflowRun
        Matches:
          workflow_run.id:
            "12345678":
              - "2025-10-15T18:41:00Z"
      - ID: ArtifactDownload
        Matches:
          workflow_job.run_id:
            "12345678":
              - "2025-10-15T18:42:00Z"

  - Name: cross-fork workflow without artifact download
    ExpectedResult: false
    RuleOutputs:
      - ID: CrossForkWorkflowRun
        Matches:
          workflow_run.id:
            "12345678":
              - "2025-10-15T18:41:00Z"

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.