- PHP 보안 패치는 공개되는 순간 공격자도 수정 내용을 분석할 수 있어, 성공한 공격이 아직 없다는 사실이 업데이트를 미룰 근거가 되지 못한다.
- 업데이트 전에 CLI와 웹 서버가 실제로 쓰는 PHP 버전, 그리고 배포판 패키지·외부 저장소·컨테이너·호스팅 중 어떤 방식으로 설치됐는지부터 파악해야 한다.
- 패키지를 올린 뒤 PHP-FPM이나 웹 서버를 재시작하고 웹 경로에서 버전을 다시 확인해야 패치가 실제로 적용된다.
PHP 취약점 하나 때문에 세계 곳곳의 웹사이트가 오프라인이 됐다. 각국 당국은 서둘러 패치를 적용하라고 촉구했다. 그런데 개발자 커뮤니티는 다른 쪽을 봤다. 패치를 만드는 사람이다. 소프트웨어 개발자 이언 랜즈먼(Ian Landsman)은 PHP 취약점 패치 작업을 맡아 온 자원봉사자 온드르제이 수리(Ondřej Surý)를 인터넷 전체의 숨은 영웅이라고 부르며 X에 이렇게 썼다. “이 사람에게 무슨 일이라도 생기면 그걸로 끝이다. 모두 끝장이다.”
패치는 누가 만들든 받아서 서버에 적용하는 일은 운영자에게 남는다. 이 글은 PHP 취약점 소식이 나왔을 때 무엇부터 확인하고 어떤 순서로 업데이트해야 하는지를 다룬다. 아래 명령어와 경로는 리눅스 배포판과 호스팅 제어판 버전에 따라 표기가 조금씩 다를 수 있다. 자기 환경에 맞춰 읽으면 된다.
패치가 공개되면 공격자도 같은 코드를 읽는다
보안 패치는 방어하는 쪽에게는 해결책이지만 공격하는 쪽에게는 지도 노릇을 한다. 오픈소스 프로젝트는 수정 코드를 공개 저장소에 올린다. 그래서 패치 전후 코드를 나란히 놓고 비교하면 어느 함수에서 어떤 검사가 빠져 있었는지 드러난다. 이런 작업을 패치 디핑(patch diffing)이라고 하고, 이미 알려진 취약점을 노리는 공격은 흔히 엔데이(n-day) 공격이라고 부른다. 공개된 수정 사항이 해커를 도울 수 있다는 이코노미스트의 지적도 이 구조를 두고 한 말이다.
지금까지 확인된 사실은 두 가지다. 전문가들은 이번 PHP 취약점이 예상보다 악용하기 어렵다고 평가했다. 공격에 성공한 사례도 아직 나오지 않았다. 아래는 해석이다. 이 평가는 지금까지 관찰한 결과일 뿐이고 앞으로를 보장하지는 않는다. 누군가 공격 코드를 공개하면 그 코드는 바로 대량 스캔 도구에 들어간다. 그때부터 패치하지 않은 서버는 자동화된 공격의 표적이 된다. 악용 난도가 높다는 소식을 업데이트를 몇 주 미뤄도 된다는 신호로 받아들이면 곤란하다. 공격 코드가 나오기 전에 패치할 시간이 조금 더 남았다는 뜻으로 읽는 편이 안전하다.
터미널의 PHP와 웹 요청을 받는 PHP는 버전이 다를 수 있다
첫 단계는 내 서버에서 PHP가 어떤 형태로 돌고 있는지 파악하는 일이다. 한 서버에 여러 버전이 설치된 경우는 흔하다. 터미널에서 쓰는 PHP(CLI)와 웹 요청을 처리하는 PHP(PHP-FPM 또는 아파치 모듈)의 버전이 다를 수도 있다. 터미널에서 php -v 한 번 쳐 보고 끝내면 안 되는 이유다.
- CLI 버전: 터미널에서
php -v를 실행한다. 실행 파일 경로는which php로, 불러오는 설정 파일 경로는php --ini로 함께 확인한다. - 웹 서버가 쓰는 버전: 웹 루트에
<?php phpinfo();한 줄짜리 파일을 임시로 만들어 브라우저로 열면 PHP Version과 Server API 항목이 나온다. Server API가 FPM/FastCGI면 PHP-FPM, Apache 2.0 Handler면 아파치 모듈 방식이다. 이 파일은 서버 구성을 그대로 드러내므로 확인이 끝나면 바로 지워야 한다. - 실행 중인 서비스:
systemctl list-units --type=service | grep -i php로 PHP-FPM 서비스 이름을 찾는다. 버전별 서비스가 여러 개 떠 있으면 모두 업데이트하고 재시작해야 한다. - 워드프레스 관리자 화면: 도구 → 사이트 건강 → 정보 탭 → 서버 항목에 웹 서버가 쓰는 PHP 버전이 나온다.
버전 숫자만 보고 판단하면 틀릴 수 있다. 데비안·우분투·RHEL 계열 배포판은 버전은 그대로 두고 보안 수정만 덧붙이는 백포트 방식을 쓴다. 그래서 php -v에 찍힌 버전이 오래돼 보여도 이미 패치가 들어가 있을 수 있다. 배포판 패키지라면 apt changelog 패키지명(데비안·우분투)이나 rpm -q --changelog 패키지명(RHEL 계열)으로 변경 이력을 열어 보고, 해당 취약점 식별 번호(CVE)가 있는지 찾는 편이 정확하다. 보안 공지를 처음 볼 때 버전 번호보다 CVE 번호를 먼저 적어 두면 이 단계에서 시간을 아낄 수 있다.
설치 방식에 따라 패치를 내주는 곳이 다르다
PHP를 어떤 방식으로 설치했느냐에 따라 패치를 받는 경로가 달라지고, 그 패치를 책임지는 주체도 달라진다. 대표적인 설치 방식별 업데이트 방법과 주의점을 아래 표에 정리했다.
| 설치 방식 | 패치 제공 주체 | 업데이트 방법 | 주의점 |
|---|---|---|---|
| 배포판 공식 패키지(데비안·우분투) | 배포판 보안팀 | sudo apt update 후 apt list --upgradable | grep php로 대상 확인, sudo apt upgrade |
버전 번호 대신 패키지 변경 이력으로 수정 여부 확인 |
| 배포판 공식 패키지(RHEL 계열) | 배포판 보안팀 | sudo dnf check-update 'php*' 후 sudo dnf upgrade 'php*' |
모듈 스트림을 쓰는 버전이면 선택한 스트림 안에서만 업데이트됨 |
| 외부 저장소 패키지 | 저장소 메인테이너(개인·자원봉사자 포함) | 배포판과 같은 패키지 관리자 명령으로 업데이트 | 저장소가 해당 PHP 버전을 계속 지원하는지 확인 |
| 소스 직접 빌드 | 운영자 본인 | PHP 공식 사이트의 수정 릴리스를 받아 다시 컴파일·설치 | 직접 빌드한 확장 모듈도 함께 다시 빌드해야 할 수 있음 |
| 컨테이너 이미지 | 이미지 제작자 | docker build --pull로 기반 이미지를 새로 받아 재빌드 후 재배포 |
실행 중인 컨테이너는 교체 전까지 구버전 그대로 |
| 공유 호스팅·관리형 서비스 | 호스팅 업체 | 제어판에서 PHP 버전 선택, 엔진 패치는 업체가 적용 | 업체 공지로 조치 여부 확인 |
표에서 따로 볼 줄은 외부 저장소다. 배포판 공식 저장소에 없는 PHP 버전을 쓰려고 개인 메인테이너가 운영하는 저장소를 추가하는 경우가 많다. 이 경우 패치가 얼마나 빨리 나오는지, 지원이 언제까지 이어지는지는 그 메인테이너의 작업량과 일정에 달려 있다. PHP 패치 작업을 자원봉사자 한 사람이 떠받치고 있다는 랜즈먼의 지적은, 해석하자면 바로 이 공급망 구조의 약점을 짚은 것이다. 이 구조를 운영자가 바꿀 수는 없다. 배포판 공식 패키지나 공식 컨테이너 이미지처럼 옮겨 갈 수 있는 경로를 미리 알아 두는 것이 현실적인 대비다.
‘업데이트 완료’ 메시지 다음에 할 일: 재시작과 검증
패키지 관리자가 업데이트 완료를 출력했어도 패치가 끝난 것은 아니다. PHP-FPM과 아파치는 시작할 때 PHP 엔진을 메모리에 올려 두고 쓴다. 그래서 프로세스를 다시 띄우기 전까지는 구버전 코드가 계속 요청을 처리한다. OPcache에 남아 있던 캐시도 재시작할 때 비워진다.
- PHP-FPM 재시작: 앞에서 찾은 서비스 이름으로
sudo systemctl restart 서비스명을 실행한다. 서비스 이름은 데비안·우분투에서는 버전 번호가 붙은 형태(php버전-fpm)이고, RHEL 계열에서는 보통php-fpm이다. - 아파치 모듈 방식: 데비안·우분투는
sudo systemctl restart apache2, RHEL 계열은sudo systemctl restart httpd를 실행한다. - 버전 검증: phpinfo 임시 파일을 다시 열어 PHP Version과 Build Date가 바뀌었는지 확인하고 바로 지운다. 백포트 방식 배포판에서는 PHP Version 숫자가 그대로일 수 있으므로 Build Date를 보는 편이 확실하다. 패키지 설치 상태는
dpkg -l | grep php또는rpm -qa | grep php로 본다. - 로그 점검: 재시작 직후 웹 서버와 PHP-FPM 에러 로그를 열어 확장 모듈 로딩 실패 같은 오류가 없는지 살핀다.
컨테이너 환경에서는 확인할 것이 하나 더 있다. 새 이미지를 배포한 뒤 실제로 떠 있는 컨테이너가 새 이미지로 바뀌었는지 docker ps와 docker inspect로 확인해야 한다. 이미지만 새로 빌드하고 컨테이너를 교체하지 않으면 서비스는 계속 구버전 PHP로 돈다. 표의 주의점 칸에 적은 ‘실행 중인 컨테이너는 교체 전까지 구버전 그대로’가 바로 이 경우다.
그누보드·워드프레스 사이트는 호스팅 PHP 버전부터 점검
국내에서는 워드프레스, 그누보드처럼 PHP로 만든 CMS와 게시판 솔루션이 소규모 쇼핑몰, 커뮤니티, 기관 홈페이지에 널리 쓰인다. 이런 사이트는 서버를 직접 관리하지 않고 웹호스팅을 쓰는 경우가 많다. 따라서 운영자가 할 일과 호스팅 업체가 할 일을 먼저 나눠야 한다.
- 공유 호스팅: PHP 엔진 자체의 보안 패치는 호스팅 업체가 서버 단위로 적용한다. 운영자가 할 일은 두 가지다. 업체 공지사항이나 고객센터에서 해당 취약점을 조치했는지 확인하는 것, 그리고 제어판에서 지원이 끝난 구버전 PHP를 선택해 두지 않았는지 점검하는 것. cPanel 기반 호스팅이라면 소프트웨어 → MultiPHP Manager(업체에 따라 Select PHP Version)에서 버전을 바꾼다. 국내 업체 자체 제어판에서도 PHP 버전 선택 항목을 찾아 같은 방식으로 바꾸면 된다(항목 위치는 불확실하니 업체 도움말 참고).
- VPS·클라우드 서버: 서버 OS와 PHP 패키지는 운영자 책임이다. 앞의 표대로 직접 업데이트하고 재시작까지 끝내야 한다. 관리형 상품이라도 OS 패치가 계약 범위에 들어가는지는 따로 확인해야 한다.
- CMS 호환성: PHP 버전을 크게 올리면 오래된 테마, 플러그인, 게시판 스킨이 동작하지 않을 수 있다. 같은 버전대 안의 보안 업데이트는 호환성 문제가 상대적으로 적다. 지원이 끝난 버전에서 새 버전으로 옮길 때는 백업을 받고 테스트 환경에서 먼저 확인한 다음 옮긴다.
국내 사이트가 얼마나 피해를 봤는지 가늠할 자료는 아직 없다. 국내 기준의 대응 지침은 KISA 보호나라 보안 공지에 관련 권고가 올라왔는지 확인하면 얻을 수 있다.
확인된 것과 아직 불확실한 것
확인된 것
- PHP에서 취약점이 공개됐고, 그 여파로 세계 곳곳의 웹사이트가 오프라인이 됐다. 당국은 패치 적용을 촉구했다.
- 전문가들은 해당 취약점이 예상보다 악용하기 어렵다고 평가했고, 성공한 공격 사례는 아직 나오지 않았다.
- 공개된 수정 사항이 오히려 해커에게 단서가 될 수 있다는 지적이 나왔다.
- 자원봉사자 온드르제이 수리가 PHP 취약점 패치 작업을 맡아 왔고, 개발자 이언 랜즈먼은 그를 인터넷 전체의 숨은 영웅으로 평가했다.
아직 불확실한 것
- 정확히 어떤 PHP 버전과 구성이 영향을 받는지는 PHP 공식 보안 공지와 각 배포판 보안 권고에서 직접 확인해야 한다.
- 웹사이트가 오프라인이 된 경위가 실제 공격 때문인지, 장애나 예방 차원의 조치 때문인지는 알려진 내용만으로 구분하기 어렵다.
- 악용이 어렵다는 평가가 공격 코드 공개 이후에도 유지될지는 알 수 없다.
- 국내 호스팅 업체별 조치 시점과 국내 피해 규모는 확인되지 않았다.
다음 PHP 취약점 때 확인 시간을 줄이는 다섯 가지 습관
긴급 패치 때 허비하는 시간은 대부분 업데이트가 아니라 확인 작업에서 나온다. 앞에서 본 버전 확인, 설치 방식 파악, 서비스 이름 찾기가 모두 여기에 해당한다. 평소에 아래 항목을 준비해 두면 취약점 소식이 나온 날 바로 업데이트 단계로 넘어갈 수 있다.
- 지원 기간 점검: PHP 공식 사이트의 지원 버전(Supported Versions) 안내에서 지금 쓰는 버전이 보안 지원 기간 안에 있는지 정기적으로 확인한다. 지원이 끝난 버전에는 공식 보안 수정이 나오지 않는다.
- 보안 공지 구독: 사용하는 배포판의 보안 권고 페이지나 메일링 리스트를 구독한다. 외부 저장소를 쓴다면 그 저장소의 공지 채널도 함께 구독한다.
- 자동 보안 업데이트: 데비안·우분투는
unattended-upgrades, RHEL 계열은dnf-automatic으로 보안 업데이트만 자동 적용하도록 설정할 수 있다. 다만 자동 설치 뒤 PHP-FPM 재시작까지 이어지는지는 따로 확인해야 한다. 재시작을 하지 않으면 새 패키지는 설치돼 있어도 요청은 여전히 구버전 엔진이 처리한다. - 설치 방식 기록: 서버마다 PHP를 어떤 경로로 설치했는지, FPM 서비스 이름이 무엇인지 문서로 남겨 둔다. 그러면 긴급 상황에서 확인 단계를 건너뛸 수 있다.
- 스테이징 서버 유지: 운영 서버와 같은 구성의 테스트 서버에 먼저 적용해 확장 모듈과 애플리케이션 동작을 확인한 뒤 운영 서버에 반영한다.
공개된 패치를 오래 방치할수록 그 패치는 방어 수단보다 공격 안내서에 가까워진다. 이번처럼 악용이 어렵다는 평가가 나온 취약점도 마찬가지다. 버전 확인, 설치 방식 파악, 업데이트, 재시작, 검증. 이 다섯 단계를 정해진 절차로 만들어 두면 패치가 공개된 뒤 공격 코드가 나오기까지의 시간을 운영자에게 유리하게 쓸 수 있다.
