PHP 보안 예방 설정을 적용한 날 — 업로드 진행률을 끄고 확인한 것들
2026년 10월 24일 오전, 운영 서버의 PHP 설정을 한 가지 바꿨다. 세션에 파일 업로드 진행 상황을 기록하는 기능을 끈 작업이다. 적용한 설정은 session.upload_progress.enabled = 0이다. 변경 후 PHP-FPM을 재시작하고 실제 웹 요청을 처리하는 환경에서 값이 반영됐는지 확인했다.
보안 작업을 끝내면 짧게 “패치 완료”라고 적기 쉽다. 하지만 오늘은 PHP 패키지를 새 버전으로 교체하지 않았다. 공식 공지에 나온 예방 설정을 적용한 것이므로 이 글에도 그 범위를 그대로 남겨 두려 한다. 어떤 값을 바꿨는지뿐 아니라 어디에서 확인했고 무엇까지 검사하지 않았는지가 이번 기록의 중심이다.
공식 공지와 실제 설정을 구분하기
출발점은 10월 23일 PHP 공식 사이트에 올라온 세션 업로드 진행률 관련 안내였다. 공지는 특정 설정과 애플리케이션 코드가 함께 사용되는 조건을 설명하며 다음 정기 수정 릴리스 전까지 업로드 진행률 기능을 끄는 방안을 안내했다. 해당 항목은 CVE-2026-115560으로 소개됐다. 모든 PHP 사이트가 같은 조건에 놓였다고 해석할 내용은 아니었다.
작업 전 서버의 업로드 진행률 설정은 On이었다. 이 기능이 켜져 있다는 사실만으로 실제 공격 조건이 모두 성립한다고 단정하지는 않았다. 대신 공식 안내에 맞춰 값을 0으로 바꾸고 웹 요청에서 실제로 어떤 값이 사용되는지를 확인하는 범위로 진행했다. 취약점을 재현하거나 공격 요청을 보내는 시험은 이번 작업에 포함하지 않았다.
공식 공지의 내용은 PHP의 2026년 공지 모음에서 확인할 수 있다. 같은 페이지에는 별도의 보안 업데이트 안내도 있다. 예방 설정 하나를 적용했다는 이유로 패키지 업데이트나 다른 취약점 검토까지 끝난 것으로 묶어 쓰지 않으려 했다.
변경은 작게, 돌아갈 방법은 먼저
실제로 손댄 곳은 PHP 8.3의 FPM 공통 설정이었다. 09:13 KST에 기존 설정 파일에 아래 항목을 추가했다.
session.upload_progress.enabled = 0

변경 전 파일은 복구용으로 따로 보관하고 체크섬을 확인했다. 설정이 예상과 다른 영향을 줄 때 무엇을 되돌릴지 정해 두기 위해서다. 복구할 경우에도 파일을 원래 위치에 놓는 것으로 끝내지 않고 FPM 구성 검사를 거쳐 재시작하는 순서를 기록했다. 이 글에는 서버 내부 백업 경로나 운영 계정 정보 대신 필요한 절차만 적는다.
이번 설정 변경에서 PHP 설치 패키지는 그대로 유지했다. Nginx 설정과 이미 중지된 별도 PHP-FPM 서비스도 수정하지 않았다. 한 번의 작업에 다른 서비스 정리나 설정 변경까지 섞으면 문제가 생겼을 때 원인을 구분하기 어려워진다. 오늘 기록에서는 업로드 진행률 설정, 공용 FPM 재시작, 적용 확인을 한 묶음으로 남겼다.
파일에 적힌 값과 웹에서 쓰는 값
설정 파일을 고친 뒤에는 먼저 php-fpm8.3 -t로 구성을 검사했다. 검사를 통과한 다음 공용 PHP-FPM을 재시작했다. 서비스 상태만 다시 보는 데서 끝내지 않고 기존 마스터 프로세스가 종료되고 새 프로세스가 시작됐는지, systemd 로그에 정상 종료와 기동이 남았는지도 확인했다.
여기서 확인하고 싶었던 것은 설정 파일의 문자열이 아니라 웹 요청을 처리하는 FPM의 상태였다. 터미널에서 실행하는 PHP와 웹 서버가 요청을 넘기는 PHP를 같은 것으로 취급하면 확인 범위가 흐려질 수 있다. 그래서 당시 PHP를 사용하던 ITSENT와 Trudy의 FPM 소켓에 직접 FastCGI 요청을 보내 값을 읽었다.
두 풀 모두 session.upload_progress.enabled=0으로 나왔다. 함께 확인한 값은 session.serialize_handler=php, 실행 환경은 PHP_SAPI=fpm-fcgi였다. 검사 응답의 표준 오류 출력도 비어 있었다. 적어도 확인한 두 FPM 실행 경로에서는 새 설정이 적용됐다는 근거를 얻었다.
검사에 사용한 임시 파일은 웹 루트 밖에 두었고 확인이 끝난 뒤 삭제 여부까지 점검했다. 상태를 알아보기 위해 만든 파일이 공개 웹 경로에 남는 일을 피하려는 조치였다. 운영 점검에서는 검사 결과뿐 아니라 검사 때문에 만든 파일이 남았는지도 함께 정리할 필요가 있다.
응답 확인과 기능 확인 사이
FPM 설정을 읽은 뒤에는 HTTPS 응답을 확인했다. 서버 공인 IP로 연결 대상을 고정하되 TLS 검증은 유지했다. 당시 ITSENT와 Trudy 메인, Trudy의 워드프레스 API 경로가 모두 200을 반환했다. 두 메인 화면은 변경 전에도 200이었으므로 재시작 전후의 기본 응답을 비교할 수 있었다.
이 결과는 웹 서버를 거친 요청이 정상 응답했다는 확인이다. 로그인 후 편집 화면을 사용하거나 실제 파일을 올려 보는 검사는 하지 않았다. 특히 오늘 끈 기능은 업로드와 관련된 설정이므로 홈페이지가 열린다는 사실을 업로드 기능 전체가 검증됐다는 뜻으로 넓혀 적으면 안 된다. 운영 기록에도 로그인 후 기능과 실제 업로드가 미검증이라고 남겼다.
서비스 재시작의 성공, FPM에서 읽은 설정값, 공개 HTTPS 응답은 서로 다른 확인이다. 세 가지를 함께 적어야 나중에 문제가 생겼을 때 어느 지점까지 확인했는지 알 수 있다. 반대로 이번 기록에 없는 동작까지 “이상 없음”으로 묶으면 이후 점검에서 오히려 혼란이 생긴다. 확인한 결과를 좁고 구체적으로 남기는 편이 낫다고 본다.
오늘 남긴 결과와 남은 확인
오늘 적용한 것은 업로드 진행률 기능을 끄는 설정 한 줄이다. FPM 구성 검사를 통과했고 재시작 후 실제 두 풀에서 값 0을 확인했다. 당시 공개 경로의 HTTPS 응답도 확인했으며 임시 검사 파일은 정리했다. 설정을 되돌릴 파일과 절차도 보관했다.
이번 작업은 취약점 수정 패키지 설치나 침해 여부 조사 결과가 아니다. 로그인 이후 기능과 실제 파일 업로드의 동작도 이번 검사로 확인하지 않았다. 해당 작업이 필요하면 지금 남긴 결과를 출발점으로 삼아 그 범위부터 이어서 확인해야 한다.
운영 서버를 만지는 일은 변경한 줄 수보다 적용 결과를 어디까지 확인했는지가 오래 남는다. 오늘은 한 줄을 바꿨지만 설정 검사, 재시작, 실제 FPM 값, HTTPS 응답을 차례로 확인했다. 글의 제목에도 “완전 해결” 대신 “예방 설정 적용”이라고 적은 이유다. 이번에 한 일과 하지 않은 일을 함께 남겨 두는 것으로 오늘 기록을 마친다.
댓글 0
댓글 남기기