--- kind: CASE slug: grpc-codegen-f04 title: sha256: 검사가 길이 15자 이상만 요구한다. 저장소 자신의 테스트가 32자 해시를 통과시킨다 topic: verification-path-coverage project: clean-architecture-backend-template status: 게시 전 sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 rootTreeNode: case:grpc-codegen-f04 evidenceCapturedOn: 2026-09-01 assets: - key: grpc-codegen-f04 file: ../../../final/evidence/rendered/grpc-codegen-f04.svg evidence: - ../../../final/evidence/raw/grpc-codegen-f04.txt source: - 원본 분석 절은 final/document.md#a20-grpc-codegen#L287 이다. module: grpc-codegen priority: P3 --- # sha256: 검사가 길이 15자 이상만 요구한다. 저장소 자신의 테스트가 32자 해시를 통과시킨다 같은 검사가 두 곳에 손으로 복사돼 있다. "sha256:" 이 7자이므로 뒤에 8자만 있으면 통과한다. ## 문제 같은 검사가 두 곳에 손으로 복사돼 있다. "sha256:" 이 7자이므로 뒤에 8자만 있으면 통과한다. ## 결론 sha256 digest 는 hex 64자다. 그리고 이 헐거움이 테스트에 이미 드러나 있다. 32자 — sha256 이 아니다. 여기서는 "다른 해시" 역할이라 결과가 바뀌지 않지만, 형식 검사가 이런 값을 유효한 해시로 받는다는 사실 자체가 이 값 객체의 주장("the hashes that prove which bytes it was built from")을 약하게 만든다. sha256: 뒤 64자 hex 를 정규식으로 요구하고, 검사를 한 곳에 둔다 — 두 record 가 같은 규칙을 각자 적고 있는 지금 형태에서는 한쪽만 조여도 다른 쪽이 남는다. ## 검증 환경 OpenJDK : 21.0.12 java -version 으로 확인 Gradle : 9.0.0 src/gradle/wrapper/gradle-wrapper.properties 의 distributionUrl 로 확인 확인 방식 : 두 곳에 복사된 sha256 검사의 길이 조건과 저장소 테스트의 해시 리터럴 대조 소스 수정 : x ## 재현 조건 원문은 final/document.md#a20-grpc-codegen#L287 에 있다. ## 본문 같은 검사가 두 곳에 손으로 복사돼 있다. `"sha256:"` 이 7자이므로 뒤에 8자만 있으면 통과한다. sha256 digest 는 hex 64자다. ## 길이 검사가 요구하는 최소 :::evidence key="grpc-codegen-f04" alt="분석 문서 final/document.md#a20-grpc-codegen 에서 이 기록의 근거 절을 그대로 잘라낸 15줄. 코드베이스를 측정한 것이 아니라 원본 판정이 무엇을 적었는지를 보여 준다." caption="final/document.md#a20-grpc-codegen 발췌 — 15줄" zoom="true" ::: ## 헐거움이 테스트에 이미 드러나 있다 테스트가 쓰는 값이 32자 — sha256 이 아니다. 여기서는 "다른 해시" 역할이라 결과가 바뀌지 않지만, 형식 검사가 이런 값을 유효한 해시로 받는다는 사실 자체가 이 값 객체의 주장("the hashes that prove which bytes it was built from")을 약하게 만든다. ## 수정 `sha256:` 뒤 64자 hex 를 정규식으로 요구하고, 검사를 한 곳에 둔다 — 두 record 가 같은 규칙을 각자 적고 있는 지금 형태에서는 한쪽만 조여도 다른 쪽이 남는다. ## 확인하지 못한 것 짧은 해시를 실제 발행 경로에 넣어 통과를 관측하지 않았다. 길이 조건과 테스트 리터럴의 대조로 판정했다.