아직 EOL된 PHP를 사용 중이신가요? 보안을 철저히 유지하세요.
CVE-2026-111497은 TuxCare의 Windows용 PHP ‘Endless Lifecycle Support(ELS)’를 통해 제공되는 빌드에는 전혀 영향을 미치지 않았습니다. 또한 취약점이 발견될 경우, ELS는 Windows용 PHP 버전 5.2부터 8.2까지에 대해 강제 업그레이드 없이 백포트된 보안 패치를 제공합니다. 애플리케이션이 이미 의존하고 있는 버전에 대해 지속적인 보호를 받으세요.
주요 내용
- TuxCare가 제공하는 Windows용 PHP(버전 5.2~8.2)에 대한 ‘무기한 라이프사이클 지원’은 CVE-2026-111497의 영향을 받지 않습니다.
- TuxCare의 빌드에는 Brotli 코드가 포함되어 있지 않고, 해당 libcurl은 Brotli를 절대 협상하지 않기 때문에 별도의 업데이트가 필요하지 않습니다.
- 바이너리 스캔, libcurl 기능 확인, 실시간 HTTP 테스트 및 DLL 사이드 로딩 테스트를 통해 모두 결과가 확인되었습니다.
- PHP 8.2.31부터 시작하는 php.net의 업스트림 Windows 빌드에는 Brotli가 포함되어 있으며, php.net의 10월 26일자 재빌드 버전이 필요합니다.
CVE-2026-111497은 일부 Windows용 PHP 빌드를 비롯한 여러 인기 소프트웨어 플랫폼에서 사용되는 Brotli 디코더의 심각한 취약점을 드러냈습니다. PHP 측은 10월 26일 업데이트된 Windows용 패키지를 배포하며 대응했습니다. 하지만 애초에 모든 PHP 빌드에 해당 취약점이 있는 코드가 포함된 것은 아니었습니다.
TuxCare의 PHP용 ‘무한 수명주기 지원(ELS)’은 CVE-2026-111497의 영향을 받지 않는 Windows용 빌드를 5.2부터 8.2 버전까지 제공합니다. 이 빌드들에는 Brotli 지원 기능이 처음부터 포함되어 있지 않았기 때문에, 이 특정 취약점에 대해 패치할 필요가 없습니다.
그 결론은 버전 번호나 종속성에 대한 추측에 근거한 것이 아니었습니다. TuxCare의 엔지니어 두 명이 실제 릴리스 패키지를 검토하고, Brotli를 로드하거나 사용할 수 없음을 확인하기 위해 네 가지 서로 다른 테스트를 수행했습니다.
다음은 그들이 발견한 내용과, 여러분의 PHP 환경에서 Brotli 지원 여부를 확인하는 방법입니다.
CVE-2026-111497이 실제로 어떤 영향을 미치는가
2026년 10월 22일 게시됨, 111497 이는 구글의 Brotli 디코더에서 발생하는 버퍼 오버플로우(정확히 말하면 범위를 벗어난 쓰기)이며, c/dec/decode.c, 해당 취약점이 발견된 버전은 Brotli 1.0.3부터 1.0.9, 1.1.0 및 1.2.0입니다. 공격자가 취약한 디코더를 이용해 조작된 Brotli 스트림을 처리하게 할 경우, 메모리 손상, 메모리 유출, 시스템 중단 또는 잠재적으로 코드 실행이 발생할 수 있습니다.
구글은 이 취약점에 CVSS 4.0 기준 9.2점을 부여했으며, 이미 공개된 개념 증명(PoC) 익스플로잇이 존재합니다. 10월 27일, CISA는 이 취약점을 ‘알려진 악용 사례(Known Exploited Vulnerabilities)’ 목록에 추가했으며, 현재까지 보고된 악용 시도는 Node.js를 대상으로 했습니다. 수정 사항은 Brotli 1.0.10, 1.1.1 및 1.2.1 버전에 포함되어 있습니다.
Brotli는 어디에나 있습니다. 브라우저, 웹 서버, Node.js, .NET 및 수많은 HTTP 클라이언트가 이를 사용하기 때문에, 이 CVE가 PHP를 포함한 수많은 벤더의 보안 권고문에 등장한 것입니다. 하지만 PHP 보안 권고문에 한 줄이 언급되었다고 해서 모든 PHP 바이너리에 해당 디코더가 포함되어 있는 것은 아닙니다.
왜 일부 Windows용 PHP 빌드가 영향을 받는지
PHP에서 Brotli를 사용하려면 cURL 확장 기능을 거쳐야 하며, ext/curl. libcurl이 Brotli를 사용하여 컴파일되었고, 스크립트에서 자동 압축 해제를 활성화하면, libcurl은 br 에서 Accept-Encoding 헤더를 처리하고 반환된 내용을 모두 디코딩합니다. cURL에서는 기본적으로 자동 압축 해제가 비활성화되어 있지만, 애플리케이션이나 HTTP 클라이언트 라이브러리에서 이를 활성화할 수 있습니다. 그 후에는 악의적인 서버가 조작된 스트림으로 응답하기만 하면 됩니다.
Windows에서 가장 큰 변화는 PHP 8.2.31, 업스트림 빌드에서 curl을 Brotli와 링크하기 시작했을 때 (php-src 커밋 0c6fc66848, ext/curl/config.w32). 해당 릴리스부터, php.net의 공식 Windows용 ZIP 파일은 brotlidec.dll 그리고 brotlicommon.dll. 8.1.33/8.1.34 및 8.2.29/8.2.30을 포함한 이전 공식 패키지들은 해당되지 않습니다. 이 때문에 PHP 프로젝트의 권고 사항은 8.2부터 8.5 브랜치까지만 다룹니다. 10월 26일, php.net은 수정된 Brotli 1.2.1이 포함된 재빌드된 Windows 패키지(8.2.35-1, 8.3.36-1, 8.4.27-1 및 8.5.12-1)를 추가로 배포했습니다.
TuxCare의 ELS 빌드는 해당 변경 사항이 적용되기 직전의 버전을 기반으로 합니다. 당사의 8.2 계열은 8.2.29를, 8.1 계열은 8.1.33을 기반으로 하며, 그보다 더 오래된 계열들은 이 변경 사항이 적용되기 수년 전부터 존재해 왔습니다. 그럼에도 불구하고, 단순한 기준선 비교만으로는 이 문제를 종결하기에는 충분하지 않았습니다.
PHP에 대한 무제한 라이프사이클 지원을 받아보세요 →
Windows용 PHP의 어떤 ELS 버전이 영향을 받나요?
그 중 어느 것도 아닙니다. Windows용 PHP 빌드용 ELS 중 어느 것도 바이너리에 Brotli를 포함하고 있지 않으며, libcurl을 통해 Brotli 지원을 제공하는 것으로 보고된 바도 없습니다.
| Windows용 PHP용 ELS | 바이너리 파일 내의 Brotli | libcurl의 Brotli 지원 | CVE-2026-111497 상태 |
| 5.2 | 아니요 | 아니요 | 취약하지 않음 |
| 5.4 | 아니요 | 아니요 | 취약하지 않음 |
| 5.6 | 아니요 | 아니요 | 취약하지 않음 |
| 7.2 | 아니요 | 아니요 | 취약하지 않음 |
| 7.3 | 아니요 | 아니요 | 취약하지 않음 |
| 7.4 | 아니요 | 아니요 | 취약하지 않음 |
| 8.0 | 아니요 | 아니요 | 취약하지 않음 |
| 8.1 (8.1.33 기준) | 아니요 | 아니요 | 취약하지 않음 |
| 8.2 (8.2.29 기준) | 아니요 | 아니요 | 취약하지 않음 |
이는 저희가 제공하는 PHP 런타임에 대한 발견 사항일 뿐, 호스트에 설치된 모든 것에 대한 포괄적인 진술은 아닙니다.
실제 릴리스 빌드를 어떻게 확인했는지
“취약점이 없음”이라는 판정은 이를 뒷받침하는 증거가 있어야만 의미가 있으므로, 우리 엔지니어 두 명이 출시된 릴리스 아티팩트를 병행하여 검토했습니다. DLL 파일이 없다고 해서 Brotli가 어딘가에 컴파일되어 있지 않거나 다른 방식으로 로드될 수 없다는 것을 증명할 수는 없기 때문에, 그들은 네 가지 테스트를 수행했습니다.
바이너리 파일에서 Brotli 코드를 검색했습니다.
모든 Brotli 디코더는 크고 독특한 정적 사전(static dictionary)을 포함하고 있습니다. 우리는 모든 .dll 그리고 .exe 현재 릴리스의 압축 파일을 확인해 봤지만, 어떤 빌드에서도 일치하는 항목이 하나도 없었습니다. 또한 어떤 패키지에도 Brotli DLL이 포함되어 있지 않습니다.
libcurl이 어떤 기능을 지원하는지 확인해 보았습니다.
모든 빌드에서, curl_version() Brotli 기능을 지원하지 않습니다. 내부의 libcurl은 php_curl 그것 없이 컴파일되었습니다. 이는 HTTP 클라이언트가 실제로 무엇을 할 수 있는지를 보여주기 때문에, 어떤 파일명 검색보다 더 많은 것을 말해줍니다.
어쨌든 우리는 Brotli 형식의 응답을 보냈습니다
설정 CURLOPT_ENCODING 빈 문자열을 전달하면 libcurl이 지원하는 모든 인코딩을 제안하도록 지시합니다. libcurl은 다음과 같은 인코딩을 제안했습니다. deflate, gzip 그리고 아니요 br. 그런 다음 해당 요청에 Brotli로 인코딩된 응답을 강제로 전송했습니다. 5.6부터 8.2까지의 버전에서 libcurl은 오류 61을 반환하며 이를 거부했고, “libcurl은 deflate, gzip 콘텐츠 인코딩을 지원합니다.”. 5.2와 5.4에서는 디코딩되지 않은 상태로 본문을 반환했습니다. 두 그룹의 동작 방식은 서로 다르지만, 어느 경우에도 Brotli 데이터가 디코더에 도달하지는 않았습니다.
우리는 DLL 파일을 직접 넣어두었습니다
한 가지 의문이 남았습니다. 만약 시스템에 이미 Brotli DLL이 설치되어 있다면 어떻게 될까요? PHP가 실행 시점에 이를 인식할 수 있을까요?
수입 심사 결과 거부되었습니다. 저희의 php_curl.dll 가져오지 않습니다 brotlidec.dll, 그리고 어떤 바이너리도 다음을 가리키지 않습니다. brotlidec 또는 brotlicommon 이름별로. 어쨌든 우리는 시도해 보았다. 단순히 가져오기 테이블만 믿는 건 너무 쉬워 보였기 때문이다. 우리는 복사했다. brotlidec.dll 그리고 brotlicommon.dll php.net의 공식 8.2.35-1 패키지에서 PHP 폴더로 복사하면, ext 폴더와 System32, 그런 다음 8.1 및 8.2 빌드에서 테스트를 다시 실행했습니다. 아무런 변화가 없었습니다. 여전히 Brotli가 제안되지 않았고, Brotli 응답을 강제로 적용하려 해도 여전히 오류 61이 발생했습니다.
사용 중인 PHP 호스팅에서 Brotli 지원 여부를 확인하는 방법
Windows에서 TuxCare의 PHP용 ‘Endless Lifecycle Support’를 실행 중이라면, libcurl 관련 사항을 직접 확인할 수 있습니다. 확인하려는 PHP 실행 파일을 사용하여 다음 명령을 실행해 보세요:
<?php
$v = curl_version();
echo 'libcurl ', $v['version'], PHP_EOL;
// CURL_VERSION_BROTLI exists on PHP 7.3+; its value is 1 << 23
$brotli = defined('CURL_VERSION_BROTLI') ? CURL_VERSION_BROTLI : (1 << 23);
echo 'Brotli: ', ($v['features'] & $brotli) ? 'YES' : 'no', PHP_EOL;
이 글에서 다룬 모든 ELS 빌드에서 마지막 줄은 다음과 같습니다. Brotli: no. 하지만 이 명령어는 libcurl의 컴파일된 기능만 확인할 뿐, 해당 시스템에 설치된 다른 소프트웨어는 확인하지 않습니다.
‘취약하지 않다’는 판결이 어디까지 적용되는가
이 판정은 Windows용 TuxCare의 ELS for PHP 5.2부터 8.2까지에만 적용되며, 그 외의 항목은 포함되지 않습니다. 동일한 서버에 설치된 웹 서버 모듈, Node.js, .NET, 브라우저 또는 독립 실행형 curl은 각각 자체적인 Brotli를 포함하고 있을 수 있으므로 별도의 검사가 필요합니다. Node.js는 22.x, 24.x 및 26.x 계열 전반에 걸쳐 번들된 Brotli에 문제가 있으므로 가장 먼저 확인해야 할 대상이며, 22.23.4, 24.22.1 및 26.12.1 버전에서 수정되었습니다. 별도로 설치한 PHP Brotli 확장 모듈의 경우에도 자체 디코더가 포함되어 있으며(0.21.1 버전에서 수정됨), 그 외의 모든 경우에는 영향을 받는 Brotli 버전을 1.0.10, 1.1.1 또는 1.2.1로 업데이트하십시오.
8.2.31 버전부터의 업스트림 php.net Windows 패키지를 실행 중이신가요? 그렇다면 해당 빌드에는 Brotli가 포함되어 있으므로, PHP 프로젝트의 권고 사항을 따라야 합니다. 해결 방법은 해당 브랜치에 대해 -1을 붙여 재빌드하는 것입니다. PHP 소스 코드가 변경되지 않았기 때문에, php -v 명령어를 실행했을 때 빌드 전후로 표시되는 버전 번호는 동일하며, 오직 빌드 날짜만 달라집니다(8.2.35는 “built: Oct 20 2026”을, 8.2.35-1은 “built: Oct 26 2026”을 표시합니다). 직접 확인하려면 curl_version()['brotli_version']을 확인하면 됩니다. 원래 8.2.35 패키지는 brotli/1.2.0을 반환하고, 8.2.35-1 재빌드 버전은 brotli/1.2.1을 반환합니다.
부정 사실을 입증하는 것이 왜 중요한가
지원 종료된 런타임에 대한 보안 작업의 대부분은 해당되는 취약점을 찾아내어 패치하는 것입니다. 나머지 부분은 어떤 취약점이 해당되지 않는지 확인하는 것으로, 이를 통해 팀이 문제가 아닌 사항에 유지보수 시간을 낭비하거나 스캐너가 발견한 취약점을 무기한 방치하는 상황을 방지할 수 있습니다.
CVE-2026-111497의 경우, 네 가지 테스트 결과 모두 동일한 결론을 보여주므로, 해당 빌드를 사용하는 팀은 ‘취약점이 없음’이라는 결과를 문서화하고 이 문제를 종결 처리할 수 있습니다. TuxCare CVE 트래커에서 TuxCare 제품 전반에 걸친 이 CVE 및 기타 CVE 정보를 확인할 수 있습니다.
Windows용 PHP의 ELS에 대해 궁금한 점이 있으신가요? 당사의 PHP 패치 전문가에게 문의해 주세요.
PHP에 대한 무제한 라이프사이클 지원을 받아보세요 →
자주 묻는 질문
~인가요? php -v 내 Windows용 PHP에 Brotli 수정 사항이 적용되어 있는지 확인할 수 있나요?
직접적으로는 아닙니다. php.net의 10월 26일자 Windows 재빌드 버전은 PHP 소스 코드를 수정하지 않고 Brotli만 업데이트했기 때문에, 패치된 8.2.35-1 패키지는 여전히 8.2.35로 표시됩니다. 빌드 날짜만 2026년 10월 20일에서 10월 26일로 변경됩니다. 직접적인 답변을 얻으려면 php -r “echo curl_version()[‘brotli_version’];”을 실행해 보세요. brotli/1.2.1이 표시되면 디코더가 수정된 것이며, brotli/1.2.0이 표시되면 여전히 재빌드가 필요합니다.
CVE-2026-111497이 악용되고 있나요?
네. CISA는 10월 27일 이 취약점을 ‘알려진 악용 사례 취약점’ 목록에 추가했으며, 이후 보안 업체들은 Node.js를 대상으로 한 악용 시도가 있었다고 보고했습니다. 그렇다고 해서 Windows용 PHP가 악용되고 있다는 뜻은 아니며, TuxCare의 Windows용 PHP ELS 빌드에는 해당 취약점이 있는 디코더가 전혀 포함되어 있지 않습니다.
Windows에서 TuxCare ELS for PHP를 사용하는 고객들은 별도로 조치를 취해야 하나요?
이 CVE에 대해서는 해당되지 않습니다. 여기에서 다루는 빌드(버전 5.2부터 8.2까지)는 업데이트가 필요하지 않으므로, ‘취약점이 없음’이라는 결과를 기록하고 스캐너 티켓을 종료하시면 됩니다.