--- kind: CASE slug: trust-policy-lives-in-nginx-not-in-the-code title: 테스트 Nginx 설정은 forwarded 헤더를 교체하지만 운영 경로는 확인하지 않았다 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 이다. --- # 테스트 Nginx 설정은 forwarded 헤더를 교체하지만 운영 경로는 확인하지 않았다 웹 리프의 프록시 패키지는 421줄로 신뢰 프록시 정책과 헤더 정화기와 정규화 타입을 갖는다. 이번 evidence에서 확인한 `nginxProxyTest` 설정은 들어온 forwarded 헤더를 authoritative value로 교체한다. 이 테스트 설정이 실제 운영 배포의 trust boundary인지까지는 확인하지 않았다. ## 관계 - **중복 장치를 찾으면 어느 쪽이 조립됐는지 먼저 확인한다** 이 사례가 그 규칙의 인프라 판이다. - **요청 식별자를 클라이언트가 고를 수 없다는 정책이 다른 필터에서 뒤집힌다** 같은 웹 리프에서 Java 정책과 프록시 설정이 중복되어 실제 신뢰 경계를 어느 쪽이 결정하는지 다시 확인해야 했다. ## 문제 웹 리프의 프록시 패키지는 네 파일로 421 줄이다. TrustedProxyPolicy 161 줄 NormalizedForwardedHeaders 158 줄 ForwardedHeaderSanitizer 72 줄 UntrustedForwardedHeaderException 30 줄 이 코드는 신뢰할 프록시를 판정하고 forwarded 헤더를 정규화한다. 문제는 이것이 실제 판정 경로인가다. ## 결론 확인한 테스트용 Nginx 설정은 Java 앞단에서 forwarded 헤더를 교체한다. 프록시 헤더 설정 파일의 주석은 이 파일을 forwarded 헤더의 authoritative 설정으로 두고 모든 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 는 이 배포의 공개 이름으로 교체된다. 이 테스트 구성에서는 애플리케이션에 도달하기 전에 forwarded 헤더가 교체된다. 하지만 운영 배포가 같은 설정을 사용한다는 evidence는 없으므로 실제 운영에서 Java 정책이 불필요하다고 단정하지 않는다. Java 쪽 참조 수도 그것과 맞는다. ForwardedHeaderSanitizer : main 참조 0 TrustedProxyPolicy : main 참조 1, test 참조 2 UntrustedForwardedHeaderException : main 참조 1, test 참조 1 NormalizedForwardedHeaders : main 참조 2 같은 설정 파일의 주석은 Nginx 배열 지시어가 병합되지 않고 교체되기 때문에 include 방식을 쓴다고 설명한다. location 안에서 `proxy_set_header`를 하나라도 다시 선언하면 server 수준에서 상속받던 같은 계열 지시어를 잃을 수 있다. 따라서 forwarded 헤더 설정을 location마다 부분적으로 재정의하면 애플리케이션이 받는 신뢰 입력이 달라질 수 있다. 이 테스트 설정이 운영에서도 trust boundary라면 인프라 설정 실수가 애플리케이션이 받는 forwarded 헤더 의미를 바꿀 수 있다. 다만 이번 searched direct-reference evidence만으로는 운영 시 fallback이 될 Java trust policy의 실제 framework/lifecycle wiring을 확정하지 못했다. ## 검증 환경 Nginx 설정 : 웹 리프의 nginxProxyTest 소스셋 아래 proxy_headers.conf 확인 방식 : 파일 LOC 계수와 타입별 참조 계수, 설정 파일 대조 소스 수정 : x ## 재현 조건 1. 웹 리프의 proxy 패키지 파일과 줄 수를 센다. 네 파일 421 줄이다. 2. 각 타입의 main 참조와 test 참조를 센다. 3. Nginx 프록시 헤더 설정을 읽는다. 모든 지시어가 SET 이다. 4. 그 설정의 주석에서 include 방식을 택한 이유를 읽는다. ## 본문 forwarded 헤더를 다루는 Java 정책이 421 LOC 있고 searched direct reference 기준으로 사용 지점이 매우 적다. 별도로 `nginxProxyTest` 설정은 forwarded 헤더를 authoritative value로 교체한다. 두 사실을 확인했지만 이 테스트 설정이 운영 배포의 실제 trust boundary인지와 Java 정책의 모든 framework/lifecycle wiring 부재까지는 확인하지 않았다. ## 판정을 실제로 하는 곳 :::evidence key="trust-policy-lives-in-nginx-not-in-the-code" alt="분석 문서 final/document.md 에서 이 기록의 근거 절을 그대로 잘라낸 18줄. 코드베이스를 측정한 것이 아니라 원본 판정이 무엇을 적었는지를 보여 준다." caption="final/document.md 발췌 — 18줄" zoom="true" ::: ## Java 코드와 프록시 설정을 함께 봐야 한다 운영 배포가 이 프록시 설정을 실제로 사용한다면 Java 코드만 검토해서는 forwarded 헤더 교체 정책을 검증할 수 없다. 반대로 운영 설정을 확인하지 않은 상태에서는 Java 변경이 동작에 영향을 주지 않는다고 단정할 수도 없다. ## 확인하지 못한 것 이 Nginx 설정이 실제 배포에서 쓰이는 설정과 같은지 확인하지 않았다. 확인한 파일은 웹 리프의 테스트 소스셋 아래에 있다. 별도로 인프라 디렉터리에 파일서버용 Nginx 설정이 있고 그것은 다른 파일이다. Java 정책이 어떤 경로에서 호출되는지 그 한 건씩의 참조를 추적하지 않았다.