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

5.9 KiB

kind, slug, title, topic, project, status, sourceRevision, rootTreeNode, evidenceCapturedOn, assets, evidence, source
kind slug title topic project status sourceRevision rootTreeNode evidenceCapturedOn assets evidence source
CASE trust-policy-lives-in-nginx-not-in-the-code 테스트 Nginx 설정은 forwarded 헤더를 교체하지만 운영 경로는 확인하지 않았다 duplicate-mechanisms clean-architecture-backend-template 게시 전 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 case:trust-policy-lives-in-nginx-not-in-the-code 2026-09-01
key file
trust-policy-lives-in-nginx-not-in-the-code ../../../final/evidence/rendered/trust-policy-lives-in-nginx-not-in-the-code.svg
../../../final/evidence/raw/trust-policy-lives-in-nginx-not-in-the-code.txt
원본 분석 절은 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 정책이 어떤 경로에서 호출되는지 그 한 건씩의 참조를 추적하지 않았다.