diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index bb3a2105d..1e2f84c06 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -43,6 +43,49 @@ The detector that observes evidence is authoritative for its finding. `scanner/r External engines retain their own engine/rule/version provenance. AppGuardrail normalizes their output but does not claim their analysis was performed internally. +The proposed +`github-actions-pull-request-target-untrusted-head-execution` built-in rule +owns a job-local GitHub Actions trust-boundary signal. A deterministic analyzer +requires all four causal elements: a `pull_request_target` trigger, repository +privilege in the same job, explicit materialization of an event-derived PR head, +and subsequent execution of a local action, script, test, or build from that +tree. It recognizes equivalent dot/bracket event expressions and one-hop +workflow-, job-, or same-step block/flow (including multiline flow) `env` bindings used by the same shell command +segment as Git tree selection. A fetch alone is insufficient; checkout/switch +must select the revision, or a worktree must select it and execution must bind +through normalized `cd`, `pushd`, exact step `working-directory`, or an executable/script path. +The most recent fetch that writes `FETCH_HEAD` owns its provenance; a later trusted +overwriting fetch clears prior PR-head evidence, while `--no-write-fetch-head` and +`--append` (including bundled short options) preserve it. A later directly executed +checkout/switch that selects a different tree invalidates an earlier PR-tree +selection; path restore, branch creation at current HEAD, inert text, and repeated +PR-head selection do not. Interpreter options do not break executable-path binding. +Action checkout materialization is bound +specifically to its owned `with.ref` input, including flow mappings. It +does not merge evidence across jobs or treat +YAML-looking action inputs, comments, heredocs, or run-block data as workflow authority. +Same-repository author predicates do not change the result because collaborator +branches remain mutable. Ordinary `pull_request`, metadata-only +`pull_request_target`, trusted base checkout, authority isolated in another job, +and a conservatively recognized scalar or block job-level event guard whose +every disjunct contains a standalone non-PR-target event atom remain +outside the finding boundary. The canonical prevention boundary remains a +metadata-only trigger followed by a separately reviewed default-branch +execution workflow. + +The proposed `github-actions-runtime-package-without-integrity` built-in rule owns +the narrow workflow-source signal where one step binds a versioned registry +package environment value to the exact package-selector position of that step's +`npx`/`npm exec` auto-install command. A deterministic line/state analyzer tracks +step-local field indentation, blank block-scalar lines, exact variable boundaries, +compact or expanded step mappings, intervening YAML comments, and shell heredoc +state. Heredoc body text is ignored unless an unquoted body is +redirected to a target that the same step later makes executable with `chmod`. +Lexical proximity is therefore not promoted to causal execution. The rule does +not claim that a download or registry compromise occurred. Central protected workflow prevention, immutable tool +distribution, consumer configuration, and this repository-local +detector remain separate controls. + ## Issue-to-detection boundary ```mermaid @@ -120,4 +163,4 @@ These modes share normalized contracts but can operate separately. ## Change control -A new detector engine, persistent schema, tenant authority, arbitrary autofix class, outbound target policy, issue-audit semantics, or automation credential boundary requires ADR and synchronized technical/security/test documentation. \ No newline at end of file +A new detector engine, persistent schema, tenant authority, arbitrary autofix class, outbound target policy, issue-audit semantics, or automation credential boundary requires ADR and synchronized technical/security/test documentation. diff --git a/CHANGELOG.md b/CHANGELOG.md index 110a549d8..abf534c3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ - 대시보드 검색창 커서 유지 — 검색어 중간에서 텍스트를 수정할 때마다 커서가 검색어의 맨 끝으로 점프하는 불편함을 수정했습니다. 이제 입력창의 커서 위치(`selectionStart`/`selectionEnd`)가 동적 렌더링 이후에도 원래 위치에 정확히 유지되어 자연스러운 타이핑 경험을 제공합니다. ### 보안 +- GitHub Actions `pull_request_target` 신뢰 경계 검출 — 동일 job에서 repository write/OIDC/secret 권한을 가진 채 event-derived PR head를 action-owned `with.ref` 또는 workflow/job/same-step 수준 block/flow(one-line/multiline) one-hop `env` alias로 checkout/switch하거나, 가장 최근 `FETCH_HEAD`-writing PR-head fetch의 worktree를 만들고 normalized `cd`/`pushd`/exact step `working-directory`/interpreter-option-aware executable path로 결합한 뒤 그 트리의 local action·script·test·build를 실행하는 causal chain을 `github-actions-pull-request-target-untrusted-head-execution`(HIGH, CWE-829/CWE-269)으로 탐지합니다. `--no-write-fetch-head`/`--append`(bundled short option 포함)는 기존 provenance를 보존하고, 실제 실행되어 다른 tree를 선택하는 checkout/switch 또는 overwriting fetch만 이를 무효화합니다. path restore, current-HEAD branch 생성, inert command text, 동일 PR-head 재선택은 provenance를 보존합니다. same-repository 조건은 collaborator branch의 가변성을 제거하지 않으므로 예외로 보지 않습니다. metadata-only 처리, fetch-only, later trusted selection, 일반 `pull_request`, trusted-base checkout, 다른 job에 격리된 권한, 모든 disjunct가 standalone non-PR-target event atom을 갖는 보수적 scalar/block job guard는 음성 회귀로 고정했고, unrelated boolean negation, dot/bracket expression, top-level trigger 형식·field 순서·flow mapping·trailing comment는 우회가 되지 않으며 action input/comment/heredoc/run data의 YAML 유사 텍스트는 권한 증거로 승격하지 않습니다. +- GitHub Actions 공급망 검출 — deterministic step/run analyzer가 compact `- env:`와 expanded `env:`를 포함해 한 step의 버전 고정 registry package `*_PACKAGE` 환경값이 같은 step의 `npx -y/--yes` 또는 `npm exec -y/--yes` package selector에 정확히 결합되는 causal pair를 `github-actions-runtime-package-without-integrity`(HIGH, CWE-829)로 탐지합니다. YAML field 사이 주석, block-scalar 빈 줄과 heredoc 상태를 추적하며, heredoc 본문은 동일 step에서 정확한 출력 target을 `chmod`로 실행 가능하게 만든 경우에만 executable wrapper 증거로 인정합니다. 다른 step 참조, 일반 인자 사용, 변수 prefix 충돌, local tool/tarball, 주석·출력·문서 heredoc은 제외합니다. - 리포트 출력 하드닝 — 생성된 markdown 리포트가 HTML로 렌더될 때 악성 finding 내용(예: 외부 엔진이 스캔한 코드의 `