Repository navigation
Description
Summary
check_workflow_timestamp_api.cjs validates that the .md source has not changed since compilation by comparing hash(.md frontmatter) against the hash stored in the gh-aw-metadata comment of the .lock.yml. It does not verify that the .lock.yml YAML content matches what the compiler would produce from the current .md. An attacker with repository write access can edit the .lock.yml directly — for example changing issues: read to issues: write, widening the network allowlist, or removing the AWF firewall container — while leaving the .md source and the frontmatter_hash comment unchanged. The tampered file passes all activation checks and the agent job runs with the elevated configuration. Confirmed at v0.68.1; the class of weakness was first noted in specs/workflow-lock-metadata-tampering-2026-02-14.md at v0.43.23 with status "Requires Validation".
Affected Area
Compiled workflow integrity boundary — the boundary between the .md source (author-controlled intent) and the .lock.yml (runtime-executed artifact). Specifically: actions/setup/js/check_workflow_timestamp_api.cjs and actions/setup/js/frontmatter_hash_pure.cjs.
Reproduction Outline
- Identify a compiled
.lock.ymlin a repository where you have write access (or a PR review path that does not diff.lock.ymlcarefully). - Edit one line in the
.lock.ymlYAML body, e.g. changeissues: read→issues: writein theagentjob'spermissionsblock. - Leave the
# gh-aw-metadata: {"frontmatter_hash":"..."}comment line unchanged. - Commit and push the tampered
.lock.yml(the.mdsource is untouched). - Trigger the workflow —
check_workflow_timestamp_api.cjscomputeshash(.md frontmatter)and compares it to the stored comment hash; both match, sostale_lock_file_failed = false. - The agent job runs with the elevated permission (
issues: write) with no runtime error or integrity failure.
Observed Behavior
stale_lock_file_failed remains false for a tampered .lock.yml when the .md source is unchanged. The frontmatter_hash embedded in the gh-aw-metadata comment is never recomputed against the .lock.yml YAML body. GitHub Actions' YAML parser silently ignores all comments, so the integrity metadata stored in comments provides no tamper evidence.
Expected Behavior
The activation check-lock-file step should detect that the .lock.yml YAML content no longer corresponds to what the compiler would produce from the current .md source, and fail the workflow with an integrity error.
Security Relevance
The precondition (repository write access) narrows exploitability, but PRs routinely include .lock.yml changes that reviewers may not scrutinize as carefully as the .md source. The documented model implies integrity guarantees ("validates declarative configuration artifacts", "Validate Lock File" activation step) that the current check does not provide. Beyond permission elevation, an attacker could widen network allowlists or remove the AWF firewall container — both meaningful security boundary changes invisible to the runtime check.
Suggested Mitigations
- Extend the hash to cover
.lock.ymlYAML content: Include the compiled YAML body (or a canonical recompilation of.md) in the integrity check, not just the.mdfrontmatter hash. - Move integrity metadata to a verified YAML field: YAML comments are silently ignored; a top-level YAML field would at minimum survive round-trips and could be verified.
- Add PR-time recompilation CI check: Automatically recompile every modified
.mdand diff against the committed.lock.yml; fail the PR if any difference is found. - Document the current trust model: Clarify that
.lock.ymlfiles require the same code-review scrutiny as.mdfiles and thatfrontmatter_hashis currently advisory-only.
Additional Context
If this design is intentional (e.g., the hash is meant only as a staleness guard, not a full content integrity check), that assumption should be documented explicitly in the security model and architecture documentation so repository operators understand the current trust boundary.
gh-aw version: v0.68.1
Original finding: https://github.com/githubnext/gh-aw-security/issues/1847
Generated by File Issue · ● 244K · ◷
Activity
pelikhan commentedon Apr 16, 2026
Editing lock.yml is a common way to work around our issues. This is by design.