Skip to content

fix(security): reject malformed deployment evidence bytes - #121

Open
seonghobae wants to merge 7 commits into
mainfrom
fix/deployment-evidence-fatal-utf8
Open

fix(security): reject malformed deployment evidence bytes#121
seonghobae wants to merge 7 commits into
mainfrom
fix/deployment-evidence-fatal-utf8

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Purpose

Test-first repair for #120. Production deployment receipt inputs must preserve exact retained-byte identity, reject malformed UTF-8, and bind semantic parsing plus SHA-256 receipts to one stable no-follow descriptor snapshot.

Exact current identity

  • protected/live base: main c85d710804139c0697d7ef8fa47d02b1389e6d84;
  • branch: fix/deployment-evidence-fatal-utf8;
  • initial malformed-UTF-8 RED: e33b3abae531ad8491ff3827d798dfa262a0af00;
  • parse/hash path-race RED: a3cb35011999e1645ed827fdfc741aaa64ad7dc9;
  • one-buffer GREEN: f77c03bf0c09013defe88e162d9f43b0f10a0fbd;
  • symlink-swap RED: b60221981ce8faceecb12f576e1b78d8d0aab24c;
  • no-follow descriptor repair: 4731c7e89fb6159848961b118eaab67adc7afcb8;
  • GREEN/current head: 370070ac65f5b3453a39b6a77bf7264bbc966121;
  • current compare: 7 commits ahead / 0 behind main, merge base exactly the live protected head;
  • changed paths: scripts/deployment-evidence.mjs, test/deployment-evidence-utf8.test.ts.

RCA -> distinct boundaries -> GREEN

Three integrity defects were isolated independently:

  1. retained bytes -> text semantics: ordinary UTF-8 decoding could replacement-normalize malformed JSON/NDJSON bytes;
  2. semantic read -> recorded digest: reopening a path for hashing could bind a digest to different bytes than the JSON semantics already trusted;
  3. validated path -> opened file: path metadata inspection did not itself prevent a path-to-symlink substitution before content read.

The current implementation performs bounded regular-file validation, requires real integer O_RDONLY and O_NOFOLLOW, opens one descriptor, checks descriptor identity/size before and after reading, decodes parsed inputs with fatal UTF-8, and computes release/smoke/KPI SHA-256 values from the same retained Buffer used for semantics. A pathname replacement after the descriptor snapshot cannot change the already-open evidence bytes.

The regression suite covers malformed UTF-8, raw-byte digest identity, parse/hash mutation, path-to-symlink replacement, and stable-descriptor pathname replacement while retaining valid deployment/release/KPI/smoke behavior.

Exact current-head proof

For unchanged current head 370070ac65f5b3453a39b6a77bf7264bbc966121:

  • application ci 31452932940: terminal success;
  • reviewer-ci 31452932920: terminal success;
  • eligible central Security Scan 31452932935: terminal success;
  • current CodeRabbit inline threads: 2 resolved / 0 unresolved (one current, one outdated);
  • visible formal CodeRabbit review: COMMENTED on predecessor 7bd0e828fabf618c86d53de969b6f925401e7750, not a qualifying APPROVED review;
  • GitHub reports the PR Ready and mergeable.

Authority boundary

This repair authenticates retained deployment-evidence bytes and file identity only. It does not prove a real production deployment, immutable release publication, production environment governance, real 30-day KPI provenance, owner/legal rights, revenue, transfer evidence, or acquisition readiness. Technical GREEN does not substitute for live governance or qualifying independent non-author approval; #27/#29 remain separate merge-authority gates.

Related: #5, #27, #29, #40, #112, #114, #118, #120

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

배포 증거 CLI가 입력 파일과 Wrangler 출력의 UTF-8을 엄격하게 검증합니다. JSON 파싱은 검증된 텍스트를 사용합니다. SHA-256은 원시 바이트를 해시합니다. 정상 및 잘못된 UTF-8 입력 테스트를 추가합니다.

Changes

배포 증거 UTF-8 처리

Layer / File(s) Summary
UTF-8 읽기 및 해시 경계
scripts/deployment-evidence.mjs
파일을 바이트로 읽고 TextDecoder로 엄격하게 UTF-8을 검증합니다. JSON과 Wrangler 출력은 검증된 텍스트를 사용합니다. SHA-256은 원시 바이트를 해시합니다.
잘못된 UTF-8 회귀 검증
test/deployment-evidence-utf8.test.ts
정상 입력의 성공과 결과 파일 생성을 검증합니다. JSON 및 Wrangler NDJSON의 잘못된 UTF-8 입력은 상태 코드 1과 invalid UTF-8 오류를 반환하며 결과 파일을 생성하지 않는지 검증합니다.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

  • 이슈 120: 배포 증거 경계에서 fatal UTF-8 디코딩, 원시 바이트 해시, 잘못된 UTF-8 회귀 테스트를 다루며 이 변경과 직접 연결됩니다.
  • 이슈 124: 다른 스크립트와 경로에서 동일한 UTF-8 디코딩 및 원시 바이트 SHA-256 처리를 다룹니다.
  • 이슈 118: 증거 파일을 JSON 또는 의미 검증 전에 잘못된 UTF-8로 거부하는 처리를 다룹니다.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 잘못된 배포 증거 바이트를 거부하는 주요 변경 사항을 정확하고 간결하게 설명합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/deployment-evidence-fatal-utf8

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/deployment-evidence.mjs`:
- Around line 364-374: Update the evidence-reading flow around readJson and
sha256 to read each file once and reuse the same Buffer for all operations.
Return the Buffer from the shared read helper, perform fatal UTF-8 decoding and
JSON parsing from it, and calculate the SHA-256 digest from that identical
Buffer instead of reopening the path.

In `@test/deployment-evidence-utf8.test.ts`:
- Around line 113-178: Extend the valid CLI fixture test around
runDeploymentEvidence to write a UTF-8 BOM-containing release-evidence.json
Buffer, compute its SHA-256 digest from the original raw Buffer, and assert the
output’s source.releaseEvidenceSha256 matches that digest. Keep the existing
success and output-existence assertions.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eea7882d-fb0f-4dac-96db-c5e10767344b

📥 Commits

Reviewing files that changed from the base of the PR and between c85d710 and 7bd0e82.

📒 Files selected for processing (2)
  • scripts/deployment-evidence.mjs
  • test/deployment-evidence-utf8.test.ts

Comment thread scripts/deployment-evidence.mjs Outdated
Comment thread test/deployment-evidence-utf8.test.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant