Amazon Web Services 한국 블로그
AWS WAF를 활용한 PHP2Shell RCE 취약점(CVE-2026-109618 및 CVE-2026-109619) 완화 방법
2026년 10월 21일, PHP 프로젝트는 PHP 코어 런타임에서 CVE-2026-109618 및 CVE-2026-109619로 분류된 두 가지 중요한 원격 코드 실행(RCE) 취약점에 대한 긴급 수정 코드를 공개했으며 , 이를 통틀어 PHP2Shell이라고 명명했습니다. 두 버전 모두 CVSS v4.0에서 9.2(치명적) 등급을 받았으며, 인증되지 않은 공격자가 취약한 서버에서 코드를 실행할 수 있도록 허용합니다. 고정 버전은 PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35입니다. 원래 보안 패치가 유일한 완전한 해결책이며, PHP를 최우선으로 업그레이드하는 것이 좋습니다. 하지만 플릿을 패치하는 데는 시간이 걸립니다: PHP가 실행되는 위치를 조사하고, 유지보수 창을 예약하며, 새 빌드와 대비한 애플리케이션을 테스트해야 합니다.
이 글에서는 AWS WAF 을 사용해 해당 기간 동안 확인된 공격 경로에 대한 노출을 줄이는 방법을 안내합니다. 어떤 요청 패턴을 차단해야 하는지, AWS WAFv2에서 규칙을 어떻게 작성하는지, 합법적인 트래픽을 망치지 않고 배포하는 방법과 보호가 어디서 끝나는지 확인하셔야 합니다. 아마존 위협 인텔리전스가 공개 전에 PHP2Shell 악용을 어떻게 탐지했는지에 대해서는 MadPot에서 Amazon Threat Intelligence가 공개 전에 PHP2Shell 익스플로잇을 식별 하는 방법을 참조하세요. AWS 서비스 상태와 AWS가 권장하는 WAF 규칙에 대해서는 AWS 보안 게시판 2026-143-AWS 를 참조하세요.
중요: 패치 설치만이 유일한 완전한 해결책이며, PHP를 최우선으로 업그레이드해야 합니다.
보안 취약점 요약
두 가지 PHP2Shell 취약점 모두 PHP가 처리하는 방식에 뿌리를 둔 비인증된 RCE 문제입니다 multipart/form-data애플리케이션 코드가 실행되기 전에 브라우저가 파일 업로드에 사용하는 요청 처리(request processing)를 처리하기 때문에, 이 글에서 AWS WAF 규칙은 다중 트래픽, 요청 본체 크기, 세션 업로드 진행 필드에 초점을 맞추고 있습니다. 상위 수준에서 CVE-2026-109618은 PHP 요청 도중 메모리가 부족할 때 메모리를 손상시키고, CVE-2026-109619는 한 요청이 오래된 데이터를 남기고 같은 워커 프로세스에서 나중에 다시 사용할 수 있게 합니다. 근본 원인 분석, 해당 버전, 그리고 PHP의 자체 지침은 공식 PHP 권고 및 출시 공지를 참고하세요:
- CVE-2026-109618 (메모리 손상) – PHP 권고문 GHSA-w8hw-w9fx-j79w
- CVE-2026-109619 (오래된 글로벌 상태) – PHP 권고문 GHSA-6wmf-4rv5-p3rp
- PHP 보안 출시 발표, 2026년 10월 21일
AWS WAF를 이용한 완화책의 제공 범위
AWS WAF는 이 상황에서 방어 심층 제어기이지 PHP 업그레이드를 완전히 대체하는 것이 아닙니다. PHP 권고문은 명확히 명시되어 있습니다: 패치된 릴리스로의 업데이트만이 유일한 완전한 완화책입니다. 이 두 취약점 중 하나는 앞서 설명하듯 웹 애플리케이션 방화벽의 범위 밖에 있습니다. 이 글의 규칙은 패치 작업 동안 노출을 줄이는 완화 통제로 생각하고, 패치 후에는 제거하거나 보조 통제로 유지하세요.
AWS WAF는 엣지에서 HTTP 요청을 검사합니다. 멀티파트 바디의 내부 구조를 파싱하지 않으며, PHP 워커 메모리나 서버 측 구성을 가시화할 수 없습니다. 다음 표는 각 공격 요소를 AWS WAF가 이를 완화하는 데 도움을 줄 수 있는지 매핑합니다.
| 취약점 공격 요소 | AWS WAF 커버리지 |
멀티파트 POST에서 세션 업로드 진행 상황 필드 ( PHP_SESSION_UPLOAD_PROGRESS, PHP의 업로드 추적 기능을 활성화하는 폼 필드) |
가능. 타겟팅 규칙은 해당 필드를 가진 요청을 차단할 수 있습니다. |
다중 부분 업로드 경로 ( multipart/form-data, 파일 업로드에 사용되는 요청 유형이자 두 취약점의 진입 지점) |
가능, 만약 애플리케이션에 합법적인 멀티파트 업로드가 없다면 가능합니다. 블록 multipart/form-data. |
| 과도한 페이로드로 인한 메모리 불안 상태 | 부분적으로 가능. 요청하는 체격 크기를 제한하세요. 헤더 증폭(와이어 크기보다 훨씬 더 많은 메모리가 드는 작은 부품 헤더)은 캡 아래에 머 |
| 동일한 작업자(많은 요청을 처리하는 재사용 PHP 프로세스)에 대한 반복 시도 | 가능. 속도 기반 규칙은 익스플로잇이 필요로 하는 볼륨을 줄여줍니다. |
fatal_error_backtraces 생성자 (요청 전반에 걸쳐 크래시 추적 상태를 저장하는 PHP 8.5 설정) |
불가능. 이것은 서버 구성 설정입니다 ( fatal_error_backtraces=0). |
| 컨슈머로서 유효하지 않거나 권장되지 않은 INI 진단 (잘못된 설정 설정 시 PHP가 경고 알림을 발생 | 불가능. 이 경로는 클라이언트 HTTP가 아닌 서버 측에서 실행됩니다. |
애플리케이션이 멀티파트 업로드를 받지 않는 경우, 에지 규칙이 차단됩니다 multipart/form-data이 기능은 모든 애플리케이션에 대해 작동하는 다중 부분 메모리 초과 경로와 패치 창 동안 방어 심층 제어 역할을 하는 세션-업로드-진행 트리거를 제거합니다.
만약 애플리케이션이 다중 부품 업로드를 사용한다면, AWS WAF는 위험을 줄여주지만 취약점을 완전히 해결하지는 못합니다. 왜냐하면 헤더 증폭(몇 킬로바이트의 부품 헤더가 PHP 내에서 훨씬 더 많은 메모리로 확장됨)이 크기 제한 내에 머무르고 방화벽이 개별 본체 내 헤더를 파싱할 수 없기 때문입니다. 이 경우 PHP 업그레이드를 우선순위로 두고 나중에 설명하는 서버 측 완화 조치를 적용하세요.
AWS WAF 규칙 구현
아래 규칙은 AWS WAFv2 JSON 코드이며, 각 규칙을 Amazon CloudFront 배포판, 애플리케이션 로드 밸런서, 또는 PHP 워크로드 앞의 Amazon API 게이트웨이 단계에서 연동된 WAF 보호 팩(웹 ACL)에 배포하세요.
중요: 변경을 구현하기 전에 WAFv2 로깅이 AWS WAF 로깅 지침에 따라 설정되었는지 확인하세요.모든 규칙을 카운트 모드에서 시작하고 정당한 트래픽과 일치하지 않는지 확인한 다음 차단으로 바꿔요.
요청 본문(Request Body)의 검사 크기 제한
AWS WAF는 요청한 본문의 일정 부분만 검사합니다. Application Load Balancer와 AWS AppSync 에서는 제한이 고정된 8KB입니다. CloudFront나 API Gateway 같은 AWS 서비스의 기본 용량은 16KB이며, 웹 ACL을 통해 32, 48, 64KB로 올릴 수 있습니다 AssociationConfig 아래에서 볼 수 있습니다. 검사 기준을 초과하는 신체 부위는 초과 크기로 간주됩니다. 적용하는 규칙에 맞는 제한을 선택하세요. 체격 규정은 검사된 크기까지만 제한할 수 있기 때문입니다.
AWS WAF 규칙
이 규칙은 andStatement의 세 가지 조건이 모두 참일 때만 요청을 차단하여 두 CVE를 모두 대상으로 합니다.
POST– HTTP 메서드에서 매칭되며, 변환은 없습니다.- PHP 세션 식별자(중첩된 식별자)가 존재합니다
OrStatement, 따라서 어느 하위 조건이든 이 다리를 만족한다):PHPSESSID쿠키 키로 나타나며(키와 정확히 일치, 모든 쿠키를 스캔), 또는PHPSESSID요청 본문 어디에나 나타납니다(매칭 포함).
- 본문에
PHP_SESSION_UPLOAD_PROGRESS– PHP의 세션 업로드 진행 기능을 활성화하는 폼 필드입니다.
서버에서 session.upload_progress.enabled=0 를 조합하면, 이 기능을 차단합니다.
고려해야 할 추가 WAF 규칙
1. 애플리케이션에 업로드가 없을 때, 다중 파트 요청을 차단하세요
참고: 이 규칙이 블록 모드로 구현될 경우, 파일 업로드가 필요한 애플리케이션이 작동하지 않습니다. 만약 신청서에 파일 업로드가 필요 없다면, 차단하세요 multipart/form-data엣 지에서 두 CVE의 모든 애플리케이션에 대해 작동하는 다중 부분 메모리 초과 경로를 제거합니다.
단일 명명 헤더가 전체 검사를 받으며, 8KB 헤더 제한이 없 Content-Type 헤더는 신뢰할 수 있습니다.
요청 본문 크기 제한
본문 크기 제한은 CVE-2026-109618 뒤에 있는 메모리 초과 상태와 남길 수 있는 오래된 상태를 줄여줍니다. 사용 OversizeHandling: MATCH임 계값보다 큰 물체는 차단되며, 검사 한계를 초과하는 부분도 포함됩니다. N바이트 제한을 강제하려면 Web ACL 본문 검사 제한이 최소 N이어야 합니다. Content-Length크기 제약이 있는데, 이는 헤더 값 문자열의 길이를 측정하는 것이지, 그 안에 포함된 숫자를 측정하기 때문입니다. 만약 애플리케이션에 정상적인 대규모 업로드가 있다면, 이 규칙을 비업로드 경로에 적용하여 다음을 적용하세요 AndStatement URI 경로에 있지 않으면 업로드가 끊어집니다.
참고: 이미 AWSManagedRulesCommonRuleSet 관리되는 규칙 그룹, SizeRestrictions_BODY 규칙은 기본적으로 8KB보다 큰 본문을 차단합니다. 특정 관리된 규칙이 정당한 트래픽을 방해한다면, 전체 그룹을 비활성화하지 말고 그 규칙을 카운트로 덮어쓰세요.
속도 제한 반복 시도
POST 요청에 대한 속도 기반 규칙은 공격자가 보낼 수 있는 용량을 줄여, 워커 과부하로 취약점이 유발될 가능성을 낮출 수 있으며, 스테이지 경로는 동일한 워커에 도달하려면 생산자 요청과 소비자 요청이 필요합니다. 이 규칙은 서버 설정을 보완합니다. pm.max_requests=1, 이 방법은 각 요청마다 작업자를 재활용합니다.
AWS WAF를 보완하는 서버 측 완화 조치
이러한 호스트 및 런타임 변경은 WAF가 검사하는 HTTP 계층 아래에 위치한 CVE-2026-109619 부분을 다루므로, 설계상 HTTP 범위 밖에 포함됩니다. AWS WAF 규칙과 함께 호스트 및 런타임 계층으로 방어 기능을 적용하세요.
- PHP를 8.5.12, 8.4.27, 8.3.36, 또는 8.2.35로 업그레이드하세요. 이게 유일한 완전한 해결책입니다. PHP 8.1 이전 버전은 더 이상 업스트림에서 지원되지 않으니, 배포판이나 장기 지원 업체에 백포트 수정 여부를 확인하거나 지원되는 브랜치로 옮길 계획을 세
- CVE-2026-109618을 PHP 수준에서 해결하세요. memory_limit=-1로 설정해 애플리케이션이 이를 덮어쓰지 못하게 하고, post_max_size 낮게 유지하세요 (업로드가 전혀 허용되지 않는 경우 8M, 업로드가 허용되는 경우 32M). 메모리 경계는 RLIMIT_AS나 RLIMIT_DATA 제한을 통해 강제하며, 나 경로로 취약한 메모리 밖 경로를 유발하지 않습니다.
fatal_error_backtraces=0로 설정하고, PHP 8.5로 모든 작업자를 재시작하세요. 이 경우 요청 전반에 걸쳐 크래시 트레이스 상태를 저장하는 설정이 비활성화되며, 이는 취약점이 발생하는 확인된 방법 중 하나입니다.session.upload_progress.enabled=0로 설정하고, 모든 작업자를 다시 시작하세요. 이 기능은 다른 확인된 트리거인 업로드 추적 기능을 꺼지며, 패치 후에도 끄는 것이 현명합니다.php.ini, FPM 풀, 또는 요청 당 INI 오버라이드에 의한 서버 시작 구성(각 요청마다 적용되는 설정을 통해.htaccess,php_value, 또는 FastCGIPHP_VALUE). 진단 경고가 발생하지 않도록 구식 지침을 제거하세요.- 치명적인 오류와 실행 타임아웃을 제거합니다 업로드, 가져오기, 오류 페이지, 종료, 직렬화, 확장 경로 등 공격자가 접근 가능한 경로에서
- 성능이 허락한다면,
pm.max_requests=1로 설정하세요. 각 워커 프로세스는 한 번의 요청 후에 재활용되어, 오래된 데이터를 심는 요청과 이를 재사용할 후속 요청 사이의 연결이 끊 - 오류 기록을 켜세요 (
log_errors=On,error_log,error_reporting=E_ALL). 공격자가 통제하는 경로에서 반복적인 경고, 폐기, 치명적인 오류, 타임아웃 등이 있는지 Apache, FPM, 프록시 로그를 검토하세요. 오류가 없다고 해서 안전하다는 증거는 아닙니다.
시작하기
다음 단계를 완료하여 시작하세요:
- PHP가 실행되는 곳과 사용 중인 버전 및 서버 API(
mod_php,FPM,FrankenPHP,LSAPI)를 인벤토리로 알려주세요. 요청 본문을 수락하는 모든 공개 엔드포인트를 식별합니다. - 각 애플리케이션이 멀티파트 업로드를 사용하는지 결정하세요. 이 과정에서 WAF 규칙을 배포해 다중 파트 요청을 차단할 수 있는지 결정됩니다.
- 각 PHP 워크로드 앞에 WebACL을 생성하거나 업데이트하고, Count 모드에서 해당 규칙을 추가하세요. 규칙에 따라 CloudFront나 API 게이트웨이에서 본문 검사 한도를 올리세요.
- 각 규칙에 대한 샘플 요청과 Amazon CloudWatch 지표를 모니터링 하세요. 정식 업로드와 대규모 JSON POST가 일치하지 않는지 확인하세요.
- 지표가 정리되면 규칙을 차단으로 바꾸시기 바랍니다.세션 업로드 진행 상황과 멀티파트 규칙이 크기 및 속도 규칙보다 먼저 실행되도록 우선 순위를 정렬하세요.
multipart/form-dataPOST, 대형 본문,PHP_SESSION_UPLOAD_PROGRESS를 포함하는 요청으로 테스트하세요.403 응답하고 매칭 룰 메트릭을 사용하세요.- 동시에 PHP 업그레이드와 설정 완화 조치를 적용하세요. 플릿 패치가 완료된 후에는 AWS WAF 규칙을 지원 제어로 제거하거나 유지하세요.
결론
PHP2Shell 취약점인 CVE-2026-109618과 CVE-2026-109619는 인증되지 않은 RCE 취약점으로, 애플리케이션 코드가 실행되기 전에 PHP에 도달합니다. AWS WAF는 패치 기간 동안 공격 표면을 좁히는 방법을 제공합니다: 세션 업로드 진행 필드를 차단하고, 업로드가 예상되지 않는 다중 파트 요청을 차단하며, 요청 본체 크기 제한, 반복 시도 속도 제한 등을 포함합니다. 이러한 완화 조치들은 노출을 줄이는 데 도움이 될 수 있지만, 취약점을 완전히 막지는 못합니다. PHP를 고정 버전으로 업그레이드하고, 서버 구성 변경을 적용하며, AWS WAF 규칙을 수정 자체가 아니라 그 수정을 지원하는 엣지 레이어로 취급하세요.
여기서 사용되는 규칙 유형에 대해 더 알고 싶다면, AWS WAF의 웹 ACL 바디 검사 한계, 초과 요청 구성 요소 처리, 초과 HTTP 요청 바디 처리문서를 참고하세요. 취약점 세부 사항은 PHP 권고 GHSA-w8hw-w9fx-j79w 와 GHSA-6wmf-4rv5-p3rp , 그리고 PHP 세션 업로드 진행 매뉴 얼을 참조하세요.
이 글은 AWS Security Blog에 게시된 Using AWS WAF to apply mitigations for PHP2Shell RCE vulnerabilities (CVE-2026-109618 and CVE-2026-109619)의 한국어 번역본입니다. 정확한 사항은 영문 블로그를 참고하세요.