1. rewrite 및 set
- rewrite 지시어는 PCRE 정규식을 사용하여 요청 URI를 다른 경로로 변경하거나 리다이렉션 하는데 사용되는 지시어 [1][2]
- set 지시어는 변수를 선언하고 값을 할당하는 지시어 [3]
2. 취약점

- rewrite와 set 지시어 처리 과정에서 서로 다른 플래그를 참조하여 발생하는 힙 버퍼 오버플로우 취약점
> 주소 공간 레이아웃 임의화(ASLR) 기능이 비활성화된 환경일 경우 임의 코드 실행이 가능
> 해당 취약점은 18년 간 발견되지 않은 취약점으로, AI(자율 취약점 분석 시스템)의 코드 스캔을 통해 발견
> rewrite 치환 문자열에 ?가 포함되어 있고, 이후 set·if·rewrite에서 unnamed PCRE 캡처를 참조하는 구성일 경우 취약
location ~ ^/api/(.*)$ {
rewrite ^/api/(.*)$ /internal?migrated=true;
set $original_endpoint $1;
}
영향받는 버전
- NGINX Open Source 0.6.27 ~ 1.30.0
- NGINX Plus R32 ~ R36
- NGINX의 스크립트 엔진은 URL을 재작성(rewrite)할 때 두 단계를 거치며, 취약점은 각 단계에서 서로 다른 플래그를 참조하여 발생 [5][6][7]
① 결과 문자열의 길이를 계산해 그만큼 메모리 할당 (길이 계산 단계)
② 실제 데이터 복사 (복사 단계)
- rewrite 치환 문자열에 ?가 포함되어 있을 경우 NGINX는 메인 엔진의 is_args 플래그를 영구적으로 1로 설정 [8]
> 해당 플래그가 설정되어 있으면 복사 단계에서 URI 특수문자를 퍼센트 인코딩(percent-encoding)으로 변환하며, 예를 들어 공백 한 바이트가 %20이라는 세 바이트로 확장
void ngx_http_script_start_args_code(ngx_http_script_engine_t *e)
{
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
"http script args");
e->is_args = 1;
e->args = e->pos;
e->ip += sizeof(uintptr_t);
}
- 그러나, 길이 계산 단계는 메인 엔진이 아닌 새로 초기화된 별도의 서브 엔진에서 실행되며, 해당 엔진의 is_args 플래그는 항상 0으로 설정되어 있음 [9]
> 결과적으로, 길이 계산 단계에서는 특수문자 확장 없음으로 판단해 원본 캡처 그대로의 길이만 반환
void ngx_http_script_complex_value_code(ngx_http_script_engine_t *e)
{
size_t len;
ngx_http_script_engine_t le;
ngx_http_script_len_code_pt lcode;
ngx_http_script_complex_value_code_t *code;
...
ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
...
}
- 이후 복사 단계에서는 메인 엔진의 is_args 플래그를 참조
> 특수문자를 3바이트로 확장해 할당된 버퍼보다 많은 데이터가 쓰이면서 힙 버퍼 오버플로 발생 [10]
void ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e)
{
...
if ((e->is_args || e->quote)
&& (e->request->quoted_uri || e->request->plus_in_uri))
{
...
// OVERFLOW HAPPENS HERE
// The destination buffer `pos` was allocated with `raw_size`,
// but `ngx_escape_uri` expands the characters and writes
// the much larger `raw_size + 2 * N` bytes directly into it!
e->pos = (u_char *) ngx_escape_uri(pos, &p[cap[n]],
cap[n + 1] - cap[n],
NGX_ESCAPE_ARGS);
} else {
e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]);
}
3. 대응방안
- 벤더사 제공 업데이트 적용 [11][12]
> 메인 엔진의 is_args 플래그 상태를 서브 엔진에 전파하여 길이 계산 시에도 동일한 이스케이프가 적용되어 버퍼 크기 불일치 해결
> 즉시 패치가 불가능한 경우, unnamed 캡처($1, $2)를 named 캡처((?<name>...) / $name)로 변경
| 취약점 | 제품명 | 영향받는 버전 | 해결 버전 |
| CVE-2026-42945 | NGINX Plus | R36 P4 미만 | R36 P4 이상 |
| R35 | 해결 버전으로 마이그레이션 | ||
| R34 | |||
| R33 | |||
| R32 P6 미만 | R32 P6 이상 | ||
| NGINX Open Source | 1.30.1 미만 | 1.30.1 이상 | |
| 0.9.7 이하 | 해결 버전으로 마이그레이션 |
- 설정 파일에서 취약 패턴 확인 : grep -rn 'rewrite.*\?.*\$[0-9]' /etc/nginx/
- NGINX 에러 로그에서 워커 비정상 종료 시그널(signal 11 (SIGSEGV), signal 6 (SIGABRT))이 반복적으로 나타나는지 점검
- 액세스 로그에서 %26, %2B, %25 등 인코딩 문자가 대량 포함된 비정상 URI 패턴을 모니터링
- 배포판 패키지를 사용하는 경우, 패키지명이 아닌 실제 NGINX 바이너리 버전을 확인(nginx -V 출력의 빌드 버전 참조)
- WAF 또는 IDS에 단일 URI 내 인코딩 문자(%26, %2B, %25)가 비정상적으로 다수 포함된 요청을 탐지·차단하는 적용
4. 참고
[1] https://nginx.org/en/docs/http/ngx_http_rewrite_module.html
[2] https://nginxstore.com/blog/nginx/nginx-rewrite-%EA%B7%9C%EC%B9%99-%EB%A7%8C%EB%93%A4%EA%B8%B0/#1-2
[3] https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#set
[4] https://nvd.nist.gov/vuln/detail/CVE-2026-42945
[5] https://depthfirst.com/research/nginx-rift-achieving-nginx-rce-via-an-18-year-old-vulnerability
[6] https://www.skshieldus.com/security-insights/trends/nginx-rewrite-module-cve-2026-42945
[7] https://wikidocs.net/blog/@jaehong/13544/
[8] https://github.com/nginx/nginx/blob/5eaf45f11e85459b52c18f876e69320df420ae29/src/http/ngx_http_script.c#L1023
[9] https://github.com/nginx/nginx/blob/5eaf45f11e85459b52c18f876e69320df420ae29/src/http/ngx_http_script.c#L1751
[10] https://github.com/nginx/nginx/blob/5eaf45f11e85459b52c18f876e69320df420ae29/src/http/ngx_http_script.c#L1372
[11] https://my.f5.com/manage/s/article/K000161019
[12] https://www.boho.or.kr/kr/bbs/view.do?bbsId=B0000133&pageIndex=1&nttId=72057&menuNo=205020
[13] https://www.boannews.com/media/view.asp?idx=143669&kind=4&search=title&find=nginx
[14] https://news.hada.io/topic?id=29537
[15] https://blog.naver.com/pjt3591oo/224290402773
'취약점 > BoF' 카테고리의 다른 글
| Ollama 힙 메모리 범위를 벗어난 읽기 취약점 (CVE-2026-7482, Bleeding Llama) (0) | 2026.05.18 |
|---|---|
| NetScaler ADC and NetScaler Gateway 경계 밖 메모리 읽기 취약점 (CVE-2025-5777, CitrixBleed2) (1) | 2025.07.15 |
| Ivanti Connect Secure Stack Buffer Overflow 취약점 (CVE-2025-0282, CVE-2025-22457) (0) | 2025.05.15 |
| Redis 스택 버퍼 오버플로우 취약점 (CVE-2024-31449) (1) | 2024.11.23 |
| DrayTek BoF 취약점 (CVE-2024-41592, CVE-2024-41585) (0) | 2024.11.11 |
