얼마 전 CI Korea에 올릴 PHP 보안 대응 가이드를 정리하면서 표 하나를 만들었습니다. "내 서버의 PHP가 패치됐는지 무엇으로 판단하느냐"를 환경별로 정리한 표입니다. 만들고 나서 보니, 이 표에서 가장 많이 틀릴 부분이 기술적인 내용이 아니라 습관이라는 생각이 들었습니다. 보안 공지가 뜨면 우리는 거의 반사적으로 php -v를 칩니다. 그런데 우분투 서버에서는 이 숫자가 패치 여부를 말해주지 않습니다.
공지는 8.3.36, 내 서버는 8.3.6
이번 PHP 보안 이슈(CVE-2026-109618 / 109619)의 php.net 공식 수정 버전은 이렇습니다.
- 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 이상
Ubuntu 24.04 LTS 서버에서 php -v를 쳐 보면 대부분 이렇게 나옵니다.
PHP 8.3.6 (cli) (built: ...)
8.3.36 이상이어야 하는데 8.3.6이니, 숫자만 보면 한참 뒤처진 취약 버전입니다. 그런데 apt upgrade를 아무리 돌려도 이 숫자는 8.3.6에서 꿈쩍도 하지 않습니다. 여기서 두 가지 잘못된 결론이 나오기 쉽습니다.
- "우분투 저장소는 패치가 안 나온다" → 급하게 PPA를 붙이거나 소스 빌드를 시도
- "어차피 숫자가 안 바뀌니 업데이트해도 소용없다" → 아무것도 안 함
둘 다 틀렸습니다. 우분투는 이미 패치를 내놨고, 업데이트하면 실제로 막힙니다. 다만 버전 번호를 바꾸지 않을 뿐입니다.
우분투는 버전을 올리지 않고 패치만 가져온다
Ubuntu LTS(그리고 Debian)는 릴리스 기간 동안 패키지의 업스트림 버전을 고정합니다. Ubuntu 24.04가 PHP 8.3.6으로 출시됐다면, 지원이 끝날 때까지 php8.3 패키지는 8.3.6입니다. 대신 보안 문제가 생기면 업스트림의 수정 코드만 골라서 8.3.6 소스에 덧붙여 다시 빌드합니다. 이걸 백포트(backport) 라고 합니다.
이렇게 하는 이유는 안정성입니다. 8.3.6에서 8.3.36으로 올리면 그 사이 30번의 릴리스에 들어간 버그 수정과 동작 변경이 한꺼번에 들어옵니다. 서버 운영자 입장에서는 보안 수정만 받고 나머지는 건드리지 않는 쪽이 안전합니다. LTS를 쓰는 이유가 바로 이것이죠.
문제는 이 방식 때문에 버전 번호가 패치 여부를 나타내지 못한다는 점입니다. 그래서 우분투에서는 다른 숫자를 봐야 합니다.
봐야 할 숫자는 패키지 리비전

dpkg로 보면 전체 패키지 버전이 나옵니다.
dpkg -l | grep php8.3-common
# ii php8.3-common 8.3.6-0ubuntu0.24.04.13 amd64 ...
8.3.6-0ubuntu0.24.04.13을 나눠 보면 이렇습니다.
| 부분 | 의미 |
|---|---|
8.3.6 |
업스트림 PHP 버전. php -v가 보여주는 값이고 LTS 기간 내내 고정 |
-0ubuntu0.24.04 |
Ubuntu 패키징 정보 (Debian 리비전, ubuntu 빌드, 24.04 대상) |
.13 |
24.04용으로 몇 번째 업데이트를 냈는지. 보안 패치가 들어가면 여기가 올라감 |
이번 이슈에 대한 Ubuntu 보안 공지(USN-8948-1)에서 24.04의 수정 버전은 8.3.6-0ubuntu0.24.04.13입니다. 내 서버가 .13 이상이면 php -v가 여전히 8.3.6이어도 패치된 상태입니다.
내가 정리한 기준표
보안 가이드에 넣은 표를 그대로 옮깁니다.
| 환경 | 안전한 기준 |
|---|---|
| php.net 공식 빌드 | 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 이상 |
| Ubuntu 26.10 (php8.5) | 8.5.9-0ubuntu2.1 이상 |
| Ubuntu 26.04 LTS (php8.5) | 8.5.4-0ubuntu1.5 이상 |
| Ubuntu 24.04 LTS (php8.3) | 8.3.6-0ubuntu0.24.04.13 이상 |
| Ubuntu 22.04 LTS (php8.1) | 8.1.2-1ubuntu2.28 이상 |
| Ubuntu 20.04 이하 (php7.x, php5) | Ubuntu CVE 페이지에서 상태 확인 필요 → 사실상 업그레이드 대상 |
| PHP 8.1 이하 (공식 빌드) | 공식 업데이트 없음. 배포판·LTS 벤더 백포트 확인 또는 업그레이드 |
눈여겨볼 줄은 Ubuntu 22.04입니다. PHP 8.1은 php.net 기준으로 이미 지원이 끝난 브랜치라 공식 패치가 없습니다. 하지만 Ubuntu 22.04의 php8.1은 Canonical이 백포트로 패치를 내줍니다. 버전 번호만 보면 "지원 종료 + 취약"으로 보이는데, 리비전으로 보면 패치된 상태일 수 있습니다. 반대로 공식 빌드로 8.1을 직접 설치해 쓰고 있다면 그건 정말로 막을 방법이 없습니다. 같은 "8.1"이라도 어디서 설치했느냐에 따라 결론이 정반대가 됩니다.
표의 Ubuntu 리비전은 USN-8948-1 기준입니다. 후속 공지가 나오면 숫자가 바뀌니 적용 전에 ubuntu.com/security/notices에서 최신 값을 다시 확인하세요.
확인 명령어 모음
1) 설치된 PHP 패키지 리비전 보기
bashdpkg -l | grep -E 'php[0-9.]+-(fpm|cli|common)|libapache2-mod-php'
apt-cache policy php8.3-fpm # 설치 버전과 저장소 후보 버전을 같이 보여줌
apt-cache policy에서 Installed와 Candidate가 다르면 아직 업데이트를 안 한 것입니다.
2) 기준 버전과 자동 비교하기
리비전 문자열은 눈으로 비교하다 틀리기 쉽습니다. .13과 .9를 문자열로 비교하면 .9가 더 커 보이니까요. dpkg의 버전 비교를 쓰는 게 정확합니다.
v=$(dpkg-query -W -f='${Version}' php8.3-common)
dpkg --compare-versions "$v" ge "8.3.6-0ubuntu0.24.04.13" \
&& echo "패치됨: $v" || echo "업데이트 필요: $v"
3) 패키지 changelog에서 CVE 번호 직접 찾기
가장 확실한 방법입니다. 백포트한 수정은 패키지 changelog에 CVE 번호와 함께 기록됩니다.
bashzcat /usr/share/doc/php8.3-common/changelog.Debian.gz | grep -m5 CVE-2026
찾는 CVE 번호가 나오면 그 수정이 들어간 패키지입니다.
설치 경로마다 보는 숫자가 다르다

여기서 한 번 더 헷갈리는 지점이 있습니다. 같은 우분투 서버라도 PHP를 어디서 설치했느냐에 따라 판단 기준이 달라집니다.
- Ubuntu 기본 저장소: 위에서 설명한 대로 리비전으로 판단합니다.
- Ondrej PPA (
ppa:ondrej/php): 우분투에서 최신 PHP를 쓰려고 많이들 붙이는 PPA입니다. 이쪽은 업스트림 릴리스를 그대로 따라가므로php -v의 8.4.27, 8.5.12 같은 숫자가 곧 기준입니다. 패키지 버전에deb.sury.org같은 표시가 붙어 있으면 PPA 패키지입니다. - Docker 공식 이미지 (
php:8.x-fpm): 역시 업스트림 빌드라 숫자로 판단합니다. 다만 컨테이너 재시작만으로는 안 바뀝니다. 새 베이스 이미지로 다시 빌드하고 컨테이너를 재생성해야 합니다. - RHEL·Alpine·cPanel 등: 벤더마다 백포트 정책이 다르니 벤더 보안 공지의 패키지 버전을 기준으로 봅니다.
한 서버에 기본 저장소 php8.3과 PPA php8.5가 같이 깔려 있는 경우도 흔합니다. 이럴 때는 패키지마다 기준을 따로 적용해야 합니다.
리비전을 올린 뒤에도 남는 함정
리비전이 .13으로 올라갔다고 끝이 아닙니다.
- 재시작을 해야 적용됩니다. PHP-FPM과 Apache(mod_php)는 이전 바이너리를 메모리에 올린 채 계속 돌고 있습니다.
sudo systemctl restart php8.3-fpm, mod_php라면apache2까지 재시작해야 합니다. CI4 큐 워커나 스케줄러처럼 오래 떠 있는 CLI 프로세스도 다시 띄워야 합니다. - CLI와 웹이 다른 PHP일 수 있습니다. 터미널의
php -v는 CLI 기준입니다. 웹이 FPM 8.5를 쓰고 CLI는 8.3인 서버도 있습니다.ls /etc/php/로 설치된 버전을 전부 확인하세요.
자가진단 스크립트도 이 원리로 만들었다
CI Korea 보안 가이드와 함께 만든 자가진단 스크립트도 이 판단을 그대로 코드로 옮겼습니다. Ubuntu·Debian이면 dpkg-query로 설치된 phpX.Y-common 패키지 리비전을 전부 읽어서 판정하고, PPA 패키지면 업스트림 숫자로, 패키지 정보를 못 읽으면 실행 중인 PHP 버전으로 판정합니다. Ubuntu에서는 "php -v 숫자가 바뀌지 않으니 리비전 판정을 기준으로 보라"는 안내도 같이 출력합니다.
테스트 환경이 마침 Ubuntu 24.04 + PHP 8.3.6이었는데, php -v만 보면 취약 판정이 나올 버전입니다. 리비전으로 판정하게 하니 .13을 정확히 "패치 적용됨"으로 잡아냈습니다. 버전 번호로만 비교하는 도구였다면 멀쩡한 서버를 취약하다고 겁줬을 겁니다.
정리
- 우분투 기본 패키지의
php -v는 LTS 기간 내내 같은 숫자입니다. 패치 여부를 알려주지 않습니다. - 판단 기준은
dpkg로 보는 패키지 리비전이고, 비교는dpkg --compare-versions로 하는 게 안전합니다. - 가장 확실한 확인은 changelog에서 CVE 번호를 찾는 것입니다.
- PPA·Docker는 반대로 업스트림 숫자로 판단합니다. 어디서 설치했는지부터 확인하세요.
- 업데이트 후에는 반드시 FPM·Apache·워커를 재시작합니다.
보안 공지가 뜨면 php -v 대신 dpkg -l | grep php부터 치는 습관을 들여 두면, 쓸데없이 PPA를 붙이거나 반대로 손 놓고 있는 일을 둘 다 피할 수 있습니다.

댓글 0개