# Bot guard bypass via edits

Bots that validate only on create or only the first page of PR files, then trust the result

_Area: Software supply chain and CI/CD. Seen in 3 disclosed reports; one confirmed bounty: $25,000; latest 2026-01-15. Updated 2026-10-23._

## How it works
A review bot or CI gate derives a security decision from a field or listing it does not fully control. Two assumptions break: (1) that a value validated when a PR is created stays valid after edits, and (2) that a paginated API listing is complete. When validation runs only on creation, or only over the first page of results, later edits or files beyond the page escape the check while downstream systems still trust the field as vetted. The gate reports "approved" on data it never actually inspected.

## Where it shows up
- Validation logic wired to create events but not update/edit events on the same object.
- A field (base ref, actor, author) treated as a protected/trusted identity downstream, e.g. `pull_request_target` trusting the base ref.
- Paginated fetches (`files(first: N)`) where truncation is logged (`console.warn`) rather than aborting.
- Allow-lists built as unanchored regexes or substring matches over IDs.
- Upstream API caps (e.g. 3000 files) that make full pagination impossible.

## How to review
Identify every field the gate trusts and ask: is it re-validated on every mutation, and is the listing complete? The invariant: a gate must fail closed. If it cannot enumerate all items or re-check the field after edit, it must deny, not warn. Check that allow-list matching is anchored/exact, not substring. Check that the trusted field (base ref, actor ID) cannot be set to a value the attacker controls or that is semantically invalid (a commit hash where a branch is expected).

## Variants seen
- Base ref validated on PR creation only; edit to a commit hash bypassed it, and `pull_request_target` ran attacker code with secrets [E1](https://bugbountylibrary.com/r/blog%3Ablog-teddykatz-com-2021-03-17-github-actions-write-access-html.md).
- Unanchored ACTOR_ID regex in CodeBuild webhook filters; a bot ID containing an approved maintainer ID as substring passed the allow-list [E2](https://bugbountylibrary.com/r/blog%3Awiz-io-blog-wiz-research-codebreach-vulnerability-aws-codebuild.md).
- dt-mergebot read only the first page of PR files (100, later 3000), warning on truncation, so hidden edits to other packages skipped permission checks [E3](https://bugbountylibrary.com/r/blog%3Ablog-ryotak-net-post-definitelytyped-tamper-with-arbitrary-packages-en.md).

## Why fixes fail
E3's cap was raised from 100 to 3000 but truncation still only warned, and GitHub's own 3000-file API cap means pagination cannot cover all cases — the fail-open behavior persisted [E3](https://bugbountylibrary.com/r/blog%3Ablog-ryotak-net-post-definitelytyped-tamper-with-arbitrary-packages-en.md).

## Impact and severity
Critical: secret theft and admin PAT leakage over major repos [E1](https://bugbountylibrary.com/r/blog%3Ablog-teddykatz-com-2021-03-17-github-actions-write-access-html.md)[E2](https://bugbountylibrary.com/r/blog%3Awiz-io-blog-wiz-research-codebreach-vulnerability-aws-codebuild.md), and tampering with arbitrary published npm packages [E3](https://bugbountylibrary.com/r/blog%3Ablog-ryotak-net-post-definitelytyped-tamper-with-arbitrary-packages-en.md). Severity rises when the gate guards release/signing or broad package scopes, and when truncation is silent.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Ablog-teddykatz-com-2021-03-17-github-actions-write-access-html.md
- E2: https://bugbountylibrary.com/r/blog%3Awiz-io-blog-wiz-research-codebreach-vulnerability-aws-codebuild.md
- E3: https://bugbountylibrary.com/r/blog%3Ablog-ryotak-net-post-definitelytyped-tamper-with-arbitrary-packages-en.md
