> ## Documentation Index
> Fetch the complete documentation index at: https://bloodhound.specterops.io/llms.txt
> Use this file to discover all available pages before exploring further.

# GH_CanPwnRequest

> [Computed] Repo role can exploit a pwn-requestable workflow to execute arbitrary code with the target's secrets and permissions — GH_RepoRole → GH_Repository / GH_Branch

<img noZoom src="https://mintcdn.com/specterops/tTIczgde9H07oLXf/assets/enterprise-AND-community-edition-pill-tag.svg?fit=max&auto=format&n=tTIczgde9H07oLXf&q=85&s=ad49a576589f4d2a8081df77d07fdf56" alt="Applies to BloodHound Enterprise and CE" width="482" height="45" data-path="assets/enterprise-AND-community-edition-pill-tag.svg" />

## Edge Schema

* Traversable: ✅

| Start | Kind | End |
| - | - | - |
| [GH\_RepoRole](/opengraph/extensions/github/nodes/gh_reporole) | GH\_CanPwnRequest | [GH\_Repository](/opengraph/extensions/github/nodes/gh_repository) |
| [GH\_RepoRole](/opengraph/extensions/github/nodes/gh_reporole) | GH\_CanPwnRequest | [GH\_Branch](/opengraph/extensions/github/nodes/gh_branch) |

```mermaid theme={null}
flowchart LR
    GH_Branch["GH_Branch"]
    GH_RepoRole["GH_RepoRole"]
    GH_Repository["GH_Repository"]
    GH_RepoRole -- GH_CanPwnRequest --> GH_Branch
    GH_RepoRole -- GH_CanPwnRequest --> GH_Repository
```

## General Information

The traversable GH\_CanPwnRequest edge indicates that a repository role can exploit a pwn-requestable workflow to execute arbitrary code with the base branch's secrets, GITHUB\_TOKEN permissions, and OIDC identity. This is a computed edge that combines workflow analysis with repository access and fork policy evaluation.

### Pwn Request Conditions

A workflow is considered pwn-requestable (`is_pwn_requestable = true`) when **all** of the following are true:

1. **`pull_request_target` trigger**: The workflow is triggered by `pull_request_target`, which runs in the context of the base branch (not the fork) and has access to the base branch's secrets and permissions.
2. **Attacker-controlled checkout**: A step uses `actions/checkout` with a `ref` parameter pointing to the pull request head, meaning attacker-supplied code from the fork replaces the trusted repository contents. Detected ref patterns:
   * `${{ github.event.pull_request.head.sha }}`
   * `${{ github.event.pull_request.head.ref }}`
   * `${{ github.head_ref }}`

### Edge Drawing Conditions

An edge is drawn from a [GH\_RepoRole](/opengraph/extensions/github/nodes/gh_reporole) to the repository (and its branches) when:

1. **Read access**: The role has a [GH\_ReadRepoContents](/opengraph/extensions/github/edges/gh_readrepocontents) edge to the repository (read access is the minimum required to fork).
2. **Forkability**: The repository can be forked by the role holder:
   * **Public repos**: Always forkable by anyone on GitHub.
   * **Private/internal repos**: Requires both the organization setting `members_can_fork_private_repositories = true` AND the repository setting `allow_forking = true`.
3. **Pwn-requestable workflow**: The repository has at least one workflow with `is_pwn_requestable = true`.

### Branch Targeting

* If the `pull_request_target` trigger has a `branches:` filter (e.g., `branches: [main]`), edges are drawn only to matching branches and the repository.
* If unconstrained, edges are drawn to the repository and all of its branches.

### Attack Impact

An attacker who exploits a pwn request gains code execution in the workflow runner with access to:

* **Repository secrets** scoped to the base branch
* **Organization secrets** accessible by the repository
* **GITHUB\_TOKEN** with the workflow's declared permissions (often `write`)
* **OIDC tokens** if `id-token: write` is set, enabling cloud identity assumption via [GH\_CanAssumeIdentity](/opengraph/extensions/github/edges/gh_canassumeidentity)
* **Environment secrets** if the workflow job targets a deployment environment

### Caveats

* **OIDC traversal requires `id-token: write`**: The attack chain from GH\_CanPwnRequest through [GH\_CanAssumeIdentity](/opengraph/extensions/github/edges/gh_canassumeidentity) to a cloud role is only valid if the pwn-requestable job's calculated `effective_github_token_permissions` includes `id-token:write`. The `id-token` permission defaults to `none` and is never implicitly granted — even when the workflow has no `permissions:` block at all. Inspect `workflow_permissions` on [GH\_Workflow](/opengraph/extensions/github/nodes/gh_workflow), `job_permissions` on [GH\_WorkflowJob](/opengraph/extensions/github/nodes/gh_workflowjob), and the job's `effective_github_token_permissions` to understand how the effective value was derived.
* **GITHUB\_TOKEN permissions**: The `permissions:` block controls what the `GITHUB_TOKEN` can do (e.g., push commits, create releases), but has no effect on secret access, OIDC token requests (governed separately by `id-token`), or arbitrary code execution. A workflow with `contents: read` is still fully exploitable via pwn request for secret exfiltration and lateral movement — only write-back to the repository is limited.

## Edge Schema

| Source | Destination | Traversable |
| - | - | - |
| [GH\_RepoRole](/opengraph/extensions/github/nodes/gh_reporole) | [GH\_Branch](/opengraph/extensions/github/nodes/gh_branch) | `true` |
| [GH\_RepoRole](/opengraph/extensions/github/nodes/gh_reporole) | [GH\_Repository](/opengraph/extensions/github/nodes/gh_repository) | `true` |

## Diagram

```mermaid theme={null}
graph LR
    n0["GH_RepoRole"]
    n1["GH_Branch"]
    n2["GH_Repository"]
    n0 -->|GH_CanPwnRequest| n1
    n0 -->|GH_CanPwnRequest| n2
```
