URL 자체는 일치한데 서버에서 검색이 안될 경우 (한글 path segment 오류)

yujin kim·2025년 12월 16일
post-thumbnail

서버 API 호출 시 URL도 맞고 컨트롤러도 정상인데, 이상하게 400 Bad Request가 떨어지는 상황을 겪어본 적이 있을 것입니다. 특히 한글 검색어나 특수 문자를 path parameter에 넣을 때 이런 문제가 자주 발생합니다. 이번 글에서는 왜 경로 파라미터 방식이 특정 서버 환경에서 막히는지, 그리고 쿼리 방식으로 바꿨을 때 문제가 해결되는 이유를 실제 예시와 함께 상세히 설명합니다. 또한, %EC%98%A4 같은 퍼센트 인코딩 문제와 WAF(Web Application Firewall), 프록시 서버가 개입하며 발생하는 오류의 메커니즘까지 이해할 수 있도록 풀어드리겠습니다.

1.한글 Path Parameter가 WAF/프록시에서 400을 일으키는 이유

1) 경로 파라미터 방식은 왜 위험 요소로 취급될까?

경로(path segment)에 한글이나 특수 문자가 포함된 URL은 보안 로드밸런서/WAF등 입장에서 “위험 요청”으로 간주되기 쉽습니다.
예를 들어 다음 요청을 보겠습니다.

GET /community/search/오

사람이 보기엔 아무 문제 없어 보이지만, 네트워크 장비나 WAF는 ‘비 ASCII 문자’ 가 들어간 경로 자체를 의심하는 경우가 많습니다. 마치 택배 주소에 외계어가 끼어 있으면 시스템이 자동으로 스캔하는 것처럼요.

보안 장비들은 보통 아래와 같은 패턴에 민감하게 반응합니다.

1. URL 경로에 비정상적인 문자 포함

2. 퍼센트 인코딩이 제대로 되지 않은 상태로 전달된 요청

3. 세그먼트가 비정상적으로 짧거나 길 때

4. 한글·일본어·중국어가 포함된 경우 (일부 구형 장비에서 오탐 발생)

즉, 개발 서버는 멀쩡한데, 서버 앞단의 WAF/LB가 먼저 400을 던져 버리는 구조입니다.

2) 퍼센트 인코딩이 안 되어 있으면 더욱 문제가 커진다

브라우저와 HTTP 표준에서는 한글 path segment를 반드시 퍼센트 인코딩 해야 합니다.

예:
오 → %EC%98%A4

따라서 아래 요청이 맞는 형식입니다.

GET https://서버/community/search/%EC%98%A4

하지만 많은 프록시나 WAF는 퍼센트 인코딩 되어 있어도 경로에 인코딩 문자열이 들어간 것을 위험하다고 판단해 요청 자체를 차단하기도 합니다. 특히 AWS WAF, Cloudflare 일부 룰, F5 ASM 등에서 이런 일이 자주 발생합니다.

3) 쿼리 방식은 왜 안전한가?

같은 요청이라도 다음처럼 쿼리 파라미터로 보내면 대부분의 보안 장비가 허용합니다.

GET https://서버주소/community?search=오

또는 퍼센트 인코딩 버전:

GET https://서버주소/community?search=%EC%98%A4

쿼리는 검색 조건·필터링에서 흔히 쓰이기 때문에, 보안 장비들도 기본적으로 “정상 요청”으로 간주합니다.

2. JS 기반 서버 기준 쿼리 방식이 가장 올바른 해결책인 이유

1) 이미 컨트롤러에서 쿼리 방식이 준비되어 있다

작성된 NestJS 컨트롤러에는 이미 다음 메서드가 존재합니다.

@Get()
async listBoard(@Query() dto: SearchBoardRequestDto): Promise<SearchBoardResponseDto> {
  return this.communityService.searchBoard(dto);
}

즉, 서버에서 쿼리 방식 호출을 기본으로 지원하고 있습니다.

이를 클라이언트에서 이렇게 호출할 수 있습니다:

GET https://api.ieg-lab.com/community?search=오

페이지네이션도 가능:


GET https://api.ieg-lab.com/community?search=오&skip=0&take=10

이 방식은 path segment에 민감한 WAF에서 훨씬 안전하게 통과합니다.

2) Postman으로 아래 두 가지를 비교 테스트해보세요

GET https://api.ieg-lab.com/community?search=오

GET https://api.ieg-lab.com/community?search=%EC%98%A4

➜ 1번이 정상 동작하면?

프론트에서도 반드시 쿼리 방식으로 전환해야 합니다.

➜ 둘 다 막힌다면?

그건 WAF 정책 문제이므로 로드밸런서·보안팀 로그를 확인해야 합니다.

  1. (선택) 그래도 /community/search/오 같은 Path 방식을 유지하고 싶다면
    1) 퍼센트 인코딩된 URL을 사용하시면 됩니다.
https://api.ieg-lab.com/community/search/%EC%98%A4

4. 프론트엔드에서는 어떻게 수정해야 할까?

❌ 기존(문제 발생 가능)
fetch(/community/search/${searchKeyword});

✅ 수정(완전 안전)
fetch(/community?search=${encodeURIComponent(searchKeyword)});

이 방식은:

보안 장비에서 막히지 않고

한글·특수문자·이모지 모두 정상 처리가 되며

JS DTO 기반의 Query Validation과도 자연스럽게 연동이 됩니다.

마무리

이번 글에서는 400 Bad Request가 서버 로직 문제가 아닌, WAF·프록시·로드밸런서 등 네트워크 보안 계층에서 발생하는 경우에 대해 자세히 설명했습니다. 특히 한글이 포함된 path parameter가 보안 장비에서 차단되는 사례가 매우 흔하다는 점, 그리고
이를 해결하는 가장 안전한 방식은 쿼리 방식(?search=...)으로 전환하는 것임을 확인했습니다.

NestJS에서도 이미 쿼리 방식을 지원하고 있으므로, 프론트에서도 encodeURIComponent를 사용해 쿼리 파라미터로 보내면 문제 없이 검색 기능을 안정적으로 운영할 수 있습니다.! 감사합니다!

profile
에러제조기 좀좀따리 지식...

0개의 댓글