Files
document-haness/docs/clean-architecture-backend-template/tech-log-studio/duplicate-mechanisms/case/case-trust-policy-lives-in-nginx-not-in-the-code.md
T
DongHyeonkaandClaude Fable 5.1 b25357c48a docs(clean-architecture-backend-template): fold analysis into final and re-select one topic
- analysis/·source-index·state.json 을 final/document.md 제2부·제3부로 접었다. SSOT 는 하나다
- 파일럿 — commit-ambiguity-as-a-result 를 새 기준으로 재선별. 후보 14 → 글감 5
  (PROMOTE 5 · MERGE_INTO 3 · KEEP_IN_SSOT 4 · 보류 2). 기록 5건을 다시 썼고 그림 1개를
  techviz 로 만들었다
- 재선별이 잡은 것: 제1부 §6.2·§11.1 이 자기 §13.2 와 어긋나 있었다(레인을 안 돌렸다 vs
  돌렸다) — 정정. 이미 답이 나와 있던 Question 을 HEAD 재실행 질문으로 다시 세웠다.
  Concept 이 인용한 코드가 SSOT 에 없어 뺐다
- candidateScope·sourceRepository 기록. 나머지 43개 주제는 재선별 대기(PENDING 905)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 12:39:20 +09:00

107 lines
5.2 KiB
Markdown

---
kind: CASE
slug: trust-policy-lives-in-nginx-not-in-the-code
title: forwarded 헤더 신뢰 판정이 Nginx에만 있고 Java 정책 421 LOC은 배선되지 않았다
topic: duplicate-mechanisms
project: clean-architecture-backend-template
status: 게시 전
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
rootTreeNode: case:trust-policy-lives-in-nginx-not-in-the-code
evidenceCapturedOn: 2026-09-01
assets:
- key: trust-policy-lives-in-nginx-not-in-the-code
file: ../../../final/evidence/rendered/trust-policy-lives-in-nginx-not-in-the-code.svg
evidence:
- ../../../final/evidence/raw/trust-policy-lives-in-nginx-not-in-the-code.txt
source:
- 원본 분석 절은 final/document.md#3-1 · final/document.md#a14 §32.2 이다.
---
# forwarded 헤더 신뢰 판정이 Nginx에만 있고 Java 정책 421 LOC은 배선되지 않았다
웹 리프의 프록시 패키지는 421 줄로 신뢰 프록시 정책과 헤더 정화기와 정규화 타입을 갖는다. 실제 신뢰 판정은 Nginx 설정이 하고, 그 설정은 들어온 forwarded 헤더를 원격 주소로 교체한다.
## 관계
- **중복 장치를 찾으면 어느 쪽이 조립됐는지 먼저 확인한다**
이 사례가 그 규칙의 인프라 판이다.
- **요청 식별자를 클라이언트가 고를 수 없다는 정책이 다른 필터에서 뒤집힌다**
같은 리프에서 같은 계열의 사례다.
## 문제
웹 리프의 프록시 패키지는 네 파일로 421 줄이다.
TrustedProxyPolicy 161 줄
NormalizedForwardedHeaders 158 줄
ForwardedHeaderSanitizer 72 줄
UntrustedForwardedHeaderException 30 줄
이 코드가 하는 일은 어떤 프록시를 신뢰할지 정하고 forwarded 헤더를 정규화하는 것이다.
문제는 이것이 실제 판정 경로인가다.
## 결론
Nginx 설정이 그 판정을 대신한다.
프록시 헤더 설정 파일의 주석이 자기 지위를 명시한다. 이것이 권위 있는 forwarded 헤더이며 모든 location 에서 include 된다는 것이다.
설정 내용은 교체다.
Host 를 host 변수로 설정
X-Real-IP 를 remote_addr 로 설정
X-Forwarded-For 를 remote_addr 로 설정
X-Forwarded-Host 를 이 배포의 공개 이름으로 설정
주석이 모든 줄이 SET 이고 ADD 가 아니라고 못 박는다. 클라이언트가 보낸 X-Forwarded-For 는 remote_addr 로 교체되고 X-Forwarded-Host 는 이 배포의 공개 이름으로 교체된다.
즉 애플리케이션에 도달하는 시점에 그 헤더들은 이미 신뢰할 수 있는 값이다. Java 정책이 판정할 것이 남아 있지 않다.
Java 쪽 참조 수도 그것과 맞는다.
ForwardedHeaderSanitizer : main 참조 0
TrustedProxyPolicy : main 참조 1, test 참조 2
UntrustedForwardedHeaderException : main 참조 1, test 참조 1
NormalizedForwardedHeaders : main 참조 2
같은 설정 파일의 주석이 왜 include 방식인지도 적는다. Nginx 의 배열 지시어 상속 규칙이 병합이 아니라 교체이기 때문이다. location 안의 proxy_set_header 하나가 server 수준에서 상속된 모든 proxy_set_header 를 버린다. 보안 헤더를 server 수준에 두고 location 마다 하나씩 추가하는 설정은 보안 헤더를 하나도 보내지 않으며, 유일한 증상은 애플리케이션이 조용히 클라이언트를 다시 신뢰하는 것이다.
그 주석이 이 사례의 위험을 정확히 서술한다. 신뢰 판정이 인프라에 있으면 인프라 설정 실수가 애플리케이션의 신뢰 정책을 조용히 되돌린다. 그리고 그때 되돌아갈 Java 정책은 배선되어 있지 않다.
## 검증 환경
Nginx 설정 : 웹 리프의 nginxProxyTest 소스셋 아래 proxy_headers.conf
확인 방식 : 파일 LOC 계수와 타입별 참조 계수, 설정 파일 대조
소스 수정 : x
## 재현 조건
1. 웹 리프의 proxy 패키지 파일과 줄 수를 센다. 네 파일 421 줄이다.
2. 각 타입의 main 참조와 test 참조를 센다.
3. Nginx 프록시 헤더 설정을 읽는다. 모든 지시어가 SET 이다.
4. 그 설정의 주석에서 include 방식을 택한 이유를 읽는다.
## 본문
<!-- body:start -->
forwarded 헤더를 어디까지 믿을지 판정하는 Java 정책이 421 LOC 작성돼 있고 배선되지 않는다. 실제 판정은 Nginx 설정이 한다.
## 판정을 실제로 하는 곳
:::evidence key="trust-policy-lives-in-nginx-not-in-the-code" alt="분석 문서 final/document.md 에서 이 기록의 근거 절을 그대로 잘라낸 18줄. 코드베이스를 측정한 것이 아니라 원본 판정이 무엇을 적었는지를 보여 준다." caption="final/document.md 발췌 — 18줄" zoom="true"
:::
## 리뷰가 닿지 않는 자리로 정책이 옮겨졌다
두 곳이 어긋나면 코드 리뷰가 잡을 수 없고, Java 쪽을 고쳐도 동작이 바뀌지 않는다.
## 확인하지 못한 것
이 Nginx 설정이 실제 배포에서 쓰이는 설정과 같은지 확인하지 않았다. 확인한 파일은 웹 리프의 테스트 소스셋 아래에 있다. 별도로 인프라 디렉터리에 파일서버용 Nginx 설정이 있고 그것은 다른 파일이다.
Java 정책이 어떤 경로에서 호출되는지 그 한 건씩의 참조를 추적하지 않았다.
<!-- body:end -->