1. rewrite 및 set

- rewrite 지시어는 PCRE 정규식을 사용하여 요청 URI를 다른 경로로 변경하거나 리다이렉션 하는데 사용되는 지시어 [1][2]

- set 지시어는 변수를 선언하고 값을 할당하는 지시어 [3]

2. 취약점

[사진 1] CVE-2026-42945 [4]

- 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

+ Recent posts