Record/Trubble Shooting

외부망에서만 API가 Empty Response로 끊긴 사례 해결

범데이 2026. 6. 16. 18:40

외부망에서만 API 임시저장이 응답 없이 끊겼다. 애플리케이션 로그는 없었고, 내부망에서는 같은 기능이 정상 동작했다.

 


증상

  • POST 직후 HTTP 상태·본문 없음 (약 40ms, 타임아웃 아님)
  • 브라우저 Network Timing: Waiting(TTFB) 구간 없음 → 응답 첫 바이트조차 오기 전에 끊김 (아래 참고)
  • 브라우저: ERR_EMPTY_RESPONSE / curl: (52) Empty reply from server
  • 내부망에서는 동일 기능 정상, 외부망에서만 재현

 

처음에는 폼 null, 임시저장 불러오기, DB 오류를 의심했지만, curl로도 재현되고 body를 줄이면 400 JSON이 돌아와 앱·경로는 살아 있음이 확인됐다. API가 통째로 죽은 상황은 아니었다.

 

 

 

 

어떻게 좁혔나

1) body 크기로 층 나누기

body 결과
최소 필드만 400 JSON (앱 도달)
실제 신청 form 전체 Empty

 

 

2) 필드 하나씩 추가

대표자 변경만, 면적 변경만, 긴 주소만 → 모두 400.

루트에 직영/위탁 운영형태 필드만 넣으면 → Empty.

 

 

3) 결정적 테스트

운영형태 코드 값 결과
DIR Empty
ABC / DI 400 JSON

DIR 문자열이 트리거. 필드 이름이나 한글 주소 길이가 아니다.

 

 

 

원인

DIR은 업무 코드다

  • 직영/위탁 운영형태를 구분하는 공통코드
  • DIR = 직영(Direct) 등, 업무상 정상 코드값 (윈도우 DIR 명령과 무관)
  • 업체 마스터·신청 form에 이미 들어 있어 POST body에 "DIR" 코드값이 포함되어 실림

 

 

WAF(웹 방화벽)가 끊는 이유

  • body를 실행하지 않고 문자열만 검사
  • "DIR" → directory / path traversal 류 시그니처 오탐
  • 차단 시 403이 아니라 연결만 종료 → Empty Response

 

 

내부 OK / 외부 NG

내부망은 WAF를 타지 않거나 정책이 느슨하고, 외부망 인터넷 구간 WAF에서만 막힌다.

 

 

 

해결

공통코드 값 변경. 직영/위탁 운영형태 공통코드에서 DIR 코드값을 WAF에 걸리지 않는 값으로 변경했다. 화면에 보이는 직영/위탁 구분(cdNm 등)은 그대로 두고, POST body에 "DIR" 문자열이 실리지 않게 한 것이 최종 조치다.

(WAF 예외·POST 필드 제거 등도 대안이 될 수 있으나, 이번에는 공통코드 변경으로 해결.)

 

 

 

정리

  1. Empty Response는 앞단 차단 신호 — TTFB* 없이 수십 ms면 WAF·프록시를 먼저 본다.
  2. 내부 OK / 외부 NG는 WAF 경로 차이의 강한 힌트.
  3. curl 최소 body vs 전체 body로 문제 필드를 이분할 수 있다.
  4. 업무상 정상인 짧은 코드(DIR, NAT …)도 보안 시그니처와 충돌할 수 있다 — 공통코드 설계·WAF 예외·전송 필드 최소화를 함께 검토한다.

* TTFB(Time To First Byte) = 요청을 보낸 뒤 HTTP 응답의 첫 바이트가 도착하기까지 걸린 시간 (Chrome 개발자 도구 Network → Timing의 Waiting 구간과 같다.)

[요청 전송] → [서버·WAF 처리] → [첫 바이트] → [본문 전체]
                              ↑ TTFB

 

Timing 의미
Waiting(TTFB) 있음 200·400 등 HTTP 응답이 시작됨 (앱·프록시까지 도달)
Waiting(TTFB) 없음 응답 시작 전 연결 종료 → Empty Response, ERR_EMPTY_RESPONSE

 

이번처럼 TTFB 없이 ~40ms에 끊기면, DB 느림·30초 타임아웃보다 앞단(WAF 등)에서 body 검사 후 차단을 먼저 의심한다.

728x90
반응형