--- kind: CASE slug: grpc-advanced-diagnostics-f01 title: 마스킹이 IPv4 만 알고, 그 결과 "마스킹되지 않은 주소" 검사가 나머지 형태를 전부 통과시킨다 topic: security-policy-enforcement project: clean-architecture-backend-template status: 게시 전 sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 rootTreeNode: case:grpc-advanced-diagnostics-f01 evidenceCapturedOn: 2026-09-01 assets: - key: grpc-advanced-diagnostics-f01 file: ../../../final/evidence/rendered/grpc-advanced-diagnostics-f01.svg - key: grpc-advanced-diagnostics-f01-diagram file: ../../../final/assets/diagrams/grpc-advanced-diagnostics-f01.svg evidence: - ../../../final/evidence/raw/grpc-advanced-diagnostics-f01.txt source: - 원본 분석 절은 final/document.md#a20-grpc-advanced-diagnostics#L167 이다. module: grpc-advanced-diagnostics priority: P2 --- # 마스킹이 IPv4 만 알고, 그 결과 "마스킹되지 않은 주소" 검사가 나머지 형태를 전부 통과시킨다 IPv4 가 아닌 주소는 패턴에 맞지 않아 입력 그대로 반환된다. 그리고 스냅숏 생성자의 검사는 이렇게 되어 있다. ## 문제 IPv4 가 아닌 주소는 패턴에 맞지 않아 입력 그대로 반환된다. 그리고 스냅숏 생성자의 검사는 이렇게 되어 있다. ## 결론 마스킹 결과가 입력과 같으면 이미 마스킹된 것으로 판정한다. 그러므로 IPv4 가 아닌 주소는 전부 이 검사를 통과한다. 세 번째와 네 번째가 문제다. 이 플랫폼이 겨냥하는 배포 형태가 쿠버네티스이고(grpc-discovery 전체가 그 주제다), 헤드리스 레코드의 엔드포인트는 파드 DNS 이름이며 이중 스택 클러스터에서는 IPv6 주소다. 편집기가 막으려 한 것이 정확히 그것이다 — "a diagnostics endpoint that publishes peer addresses publishes every tenant's connection." unix 소켓 경로도 통과한다. 그것은 호스트 파일 시스템 경로다. 테스트의 주소 리터럴이 전부 IPv4 다 — 10.4.13.201:9090 · 10.9.13.201 · 10.4.x.x · 10.5.x.x. IPv6 도 호스트 이름도 없다. ## 검증 환경 OpenJDK : 21.0.12 java -version 으로 확인 Gradle : 9.0.0 src/gradle/wrapper/gradle-wrapper.properties 의 distributionUrl 로 확인 확인 방식 : 마스킹 정규식이 받는 주소 형태와 스냅숏 생성자의 판정 조건 대조 소스 수정 : x ## 재현 조건 원문은 final/document.md#a20-grpc-advanced-diagnostics#L167 에 있다. ## 본문 IPv4 가 아닌 주소는 패턴에 맞지 않아 **입력 그대로 반환된다.** 그리고 스냅숏 생성자의 검사는 마스킹 결과가 입력과 같으면 이미 마스킹된 것으로 판정한다. ## 마스킹이 아는 형태 :::evidence key="grpc-advanced-diagnostics-f01-diagram" alt="IPv4 점 십진만 마스킹 대상 안에 놓이고 IPv6 주소와 호스트 이름 및 unix 경로가 바깥에 빗금으로 놓인다" caption="마스킹이 아는 형태" zoom="false" ::: 그러므로 IPv4 가 아닌 주소는 전부 이 검사를 통과한다. ## 마스킹되지 않은 입력이 통과하는 이유 :::evidence key="grpc-advanced-diagnostics-f01" alt="분석 문서 final/document.md#a20-grpc-advanced-diagnostics 에서 이 기록의 근거 절을 그대로 잘라낸 15줄. 코드베이스를 측정한 것이 아니라 원본 판정이 무엇을 적었는지를 보여 준다." caption="final/document.md#a20-grpc-advanced-diagnostics 발췌 — 15줄" zoom="true" ::: ## 셋째와 넷째가 문제다 이 플랫폼이 겨냥하는 배포 형태가 쿠버네티스이고(`grpc-discovery` 전체가 그 주제다), 헤드리스 레코드의 엔드포인트는 파드 DNS 이름이며 이중 스택 클러스터에서는 IPv6 주소다. 편집기가 막으려 한 것이 정확히 그것이다 — "a diagnostics endpoint that publishes peer addresses publishes every tenant's connection." `unix` 소켓 경로도 통과하는데, 그것은 호스트 파일 시스템 경로다. ## 테스트의 주소 리터럴이 전부 IPv4 다 `10.4.13.201:9090` · `10.9.13.201` · `10.4.x.x` · `10.5.x.x`. IPv6 도 호스트 이름도 없다. ## 수정 마스킹을 형태별로 나눈다 — IPv6 는 앞 두 그룹만 남기고 나머지를 `:x:x` 로, 호스트 이름은 최상위 라벨 몇 개만 남기고, 그 밖의 형태는 `unknown` 으로 접는다. 그리고 검사를 "결과가 입력과 같으면 통과" 가 아니라 "알려진 마스킹 형태와 일치해야 통과" 로 뒤집는다. 지금 형태는 마스킹이 모르는 입력을 전부 안전하다고 판정한다. ## 확인하지 못한 것 IPv6 주소로 스냅숏을 만들어 실행으로 재현하지 않았다. 정규식과 생성자 검사로 판정했다. 실제 Channelz 서비스를 띄우지 않았다.