PHP 지원 종료와 아무도 관리하지 않는 Composer 의존성

지원 종료(EOL)된 PHP용 php2shell 패치(CVE-2026-109618 및 CVE-2026-109619)가 출시되었습니다. 수요가 많아 평소보다 영업팀의 답변이 늦어지고 있으므로, 패치된 패키지를 가장 빠르게 확보하려면 온라인에서 Runtimes용 ELS를 구매하시기 바랍니다 (새 탭에서 열림). 패치 FAQ 읽어보기

이 블로그 글의 AI 요약으로 바로 가기

  • Perplexity를 사용하여 이 게시물을 요약해 주세요
  • Gemini로 이 게시물을 요약해 주세요

주요 내용

  • PHP는 수년 전에 지원 종료 일정을 미리 공지하는 반면, Composer 패키지의 경우 유지보수자가 더 이상 활동하지 않아도 아무런 공지 없이 방치됩니다.
  • PHP 업그레이드가 지연되는 이유는 대개 업그레이드 자체의 부작용이라기보다는 버려진 종속성 때문인 경우가 많습니다.
  • composer why-not 다음 런타임 업그레이드를 막고 있는 요인이 무엇인지 빠르게 알려줍니다.
  • Composer는 사용되지 않는 패키지를 찾아낼 수는 있지만, 툴체인 내에는 이를 자동으로 패치해 주는 기능은 없습니다.

한 팀이 4개월에 걸쳐 PHP 8.1에서 8.3으로 마이그레이션했습니다. 테스트, 스테이징, 주말에 진행된 전환 작업 등 모든 과정을 거쳤습니다. 잘 작동합니다.

그런 다음 composer audit 는 결제 웹훅을 처리하는 패키지를 ‘포기된’ 것으로 표시합니다. 누군가 해당 저장소를 열어보니 2021년 이후로 커밋 기록이 전혀 없습니다. EOL 정책도, 사용 중단 공지사항도 없이, 그저 조용히 관심을 잃어버린 프로젝트가 아무도 처음부터 끝까지 읽어보지 않은 의존성 트리의 네 단계 깊숙한 곳에 방치되어 있을 뿐입니다.

런타임이 업그레이드되었습니다. EOL 소프트웨어 관련 위험은 변경되지 않았습니다.

“지원되는 PHP 버전을 사용 중”이라는 사실과 “우리 애플리케이션이 지원된다”는 사실 사이의 그 간극에 수많은 PHP 보안 부채가 숨어 있으며, 이는 php -v에서 확인하는 버전 번호보다 훨씬 더 발견하기 어렵습니다.

모두가 주목하는 PHP 지원 종료 일정

PHP의 릴리스 정책은 정말 훌륭하며, 바로 이러한 예측 가능성 덕분에 런타임 EOL은 이 문제에서 비교적 쉬운 부분입니다. 각 브랜치는 2년 동안 적극적인 지원을 받으며, 그 후 2년 동안은 중대한 보안 문제만 처리됩니다.

표 내용을 확인하기 전에 알아두면 좋은 점이 하나 있습니다. 2024년에 릴리스 주기가 연장됨에 따라, 이 4년 기간은 PHP 8.1부터에만 적용됩니다. 그 이전 버전의 경우 보안 패치 지원 기간이 2년이 아닌 1년으로 제한되었기 때문에, 아래 표에서 7.4와 8.0의 지원 기간이 짧게 표시된 것입니다.

현재 상황은 다음과 같으며, 다음을 기준으로 확인되었습니다. PHP의 공식 지원 버전 페이지를 통해 확인한 내용입니다.

PHP 버전 출시됨 ~까지 적극적인 지원 ~까지 보안 지원
7.4 2019년 11월 2021년 11월 2022년 11월
8.0 2020년 11월 2022년 11월 2023년 11월
8.1 2021년 11월 2023년 11월 2025년 12월
8.2 2022년 12월 2024년 12월 2026년 12월
8.3 2023년 11월 2025년 12월 2027년 12월
8.4 2024년 11월 2026년 12월 2028년 12월
8.5 2025년 11월 2027년 12월 2029년 12월

 

오늘 주목할 만한 버전은 PHP 8.1과 8.2입니다. PHP 8.1은 2025년 12월에 지원 종료 , 따라서 여전히 이 버전을 사용 중인 시스템은 수개월 동안 업스트림 보안 패치를 받지 못한 상태입니다. PHP 8.2의 지원 종료(EOL) 은 2026년 12월 말로 예정되어 있으며, 현재 8.2 버전은 여전히 지원되고 있지만, 해당 날짜 이후에도 계속 사용할 계획인 팀은 그 전에 대비책을 마련해야 합니다.

제때 마이그레이션을 완료하지 못하는 팀은 런타임 자체에 공급업체가 지원하는 패치를 적용하여, 마이그레이션이 완료될 때까지 보안 수정 사항을 계속 받아볼 수 있습니다. 이것이 바로 TuxCare의 PHP용 ‘Endless Lifecycle Support’ 서비스가 PHP 버전의 지원 종료 후에도 해당 버전이 스택에 남아 있는 한 지속적으로 제공하는 내용입니다.

참고: 보안 전용 기간 내에 있다는 것은 활성 지원 기간에 있다는 것과는 다릅니다. 정기적인 버그 수정은 중단되었습니다. 성능 개선 작업도 중단되었습니다. 호환성 개선 작업도 중단되었습니다. 남은 것은 릴리스 관리자가 이미 다음 단계로 넘어간 브랜치에서 이루어지는 중대한 보안 수정뿐입니다.

왜 Composer 의존성에는 지원 종료일이 지정되지 않는가

2018년 주말에 직접 만든 패키지에 대한 지원 정책을 공개하는 사람은 거의 없습니다.

그것이 바로 진정한 차이점입니다. PHP에는 릴리스 관리자 그룹이 있고, 문서화된 정책이 있으며, 이를 바탕으로 계획을 세울 수 있는 일정이 있습니다. 반면 Composer 패키지는 대개 한 사람이나 소규모 팀이 담당하는데, 이들은 직장을 옮기거나 흥미를 잃거나 다른 일에 매달리게 되기도 합니다. 그럴 때 별도의 공지가 없는 이유는, 애초에 무언가를 공지하겠다는 약속이 없었기 때문입니다.

유지보수가 중단된 사실은 여러 가지 방식으로 드러나는데, 그중에서 쉽게 알아차릴 수 있는 경우는 단 하나뿐입니다. Packagist에서 ‘포기됨(abandoned)’으로 표시된 패키지는 비교적 알기 쉬운 경우인데, Composer가 이에 대해 실제로 경고를 표시하기 때문입니다. GitHub에 아카이브된 저장소는 경고가 전혀 없는 동일한 상황이지만, Composer는 이에 대해 아무런 알림도 주지 않습니다.

또, 마지막 릴리스가 2~3년 전인데도 해결되지 않은 문제가 산더미처럼 쌓여 있는 패키지도 있고, 관리자는 여전히 활동 중이지만 사용자가 막혀 있는 구버전에 대한 지원은 중단한 경우도 있으며, 리다이렉트 없이 다른 프로젝트로 통합된 패키지도 있고, 원본 프로젝트가 이름을 그대로 유지하는 동안 포크된 버전이 조용히 진짜 프로젝트가 되어버린 경우도 있습니다.

기술적으로는 여전히 존재하고, 설치도 가능하며, 문제없이 해결되지만 보안 측면에서는 전혀 주목받지 못하는 패키지는, composer.lock안에서는 마치 아무런 문제가 없는 패키지처럼 보입니다.

현재 실행 중인 프로그램을 확인하는 방법

응용 프로그램 하나당 몇 분 정도 시간을 할애하세요. 출력 결과는 대개 읽기 지루한 편입니다.

Composer가 이미 알고 있는 정보부터 시작하세요.

작곡가 감사

Composer 2.4 이상 버전은 설치된 종속성을 Packagist의 자문 API와 대조하여 확인하는데, 이 API는 PHP 보안 권고 데이터베이스 와 GitHub 권고 데이터베이스를 통합한 것입니다. –locked 를 추가하면 composer.lock파일을 직접 감사하려면–locked 파일을 먼저 설치하지 않고 직접 감사하고 싶다면 `–locked`를 추가하세요. 이는 CI 환경에서 일반적으로 선택되는 방식입니다. Composer 2.6.3부터 폐기된 패키지가 포함되기 시작했으며, 2.7 버전부터는 기본적으로 감사에 실패하므로, 최신 버전의 Composer에서 정상적으로 실행하기만 해도 예전보다 더 많은 정보를 얻을 수 있습니다.

빌드를 깨지 않고 버려진 목록을 얻고 싶다면, 2.8 버전에서는 바로 이를 위한 플래그가 추가되었습니다.

작곡가 감사 – 중단됨=보고서

이렇게 하면 처리되지 않은 패키지의 상태가 ‘실패’에서 ‘보고’로 변경되는데, 백로그를 처리해 나가는 동안 CI 환경에서는 대개 이것이 바람직한 상태입니다.

자, 이제 직접 의존성들이 실제로 얼마나 뒤처져 있는지 살펴보세요.

composer show –outdated –direct

The –direct 플래그가 중요합니다. 이 플래그를 생략하면 전체 트리가 반환되는데, 이때 유용한 신호가 잡음 속에 묻혀 버립니다. 직접 의존성은 의도적으로 선택한 것이므로, 가장 실행 가능한 출발점이 됩니다. –sort-by-age 옵션을 추가하면 가장 오래된 릴리스가 먼저 표시되므로, 진정으로 오래된 항목을 더 빠르게 찾아낼 수 있습니다.

갱신되지 않은 것처럼 보이는 항목이 있다면, 버전 번호만 믿지 말고 패키지의 실제 상태를 확인하세요.

composer show vendor/package

이렇게 하면 Packagist에서 해당 패키지를 ‘포기된’ 상태로 표시했는지 여부나, 관리자가 대체 패키지를 제안했다면 어떤 것을 제안했는지 등 패키지 자체의 메타데이터를 확인할 수 있습니다. 유지보수 활동, 최근 커밋, 릴리스, 미해결 이슈, 그리고 풀 리퀘스트가 실제로 처리되고 있는지 여부를 제대로 파악하려면 저장소를 직접 확인하세요.

PHP를 업그레이드해도 이 문제가 해결되지 않는 이유

이제 일반적인 가정을 뒤집어 봅시다. 버려진 종속성은 대개 여러분이 여전히 구버전 PHP를 사용하고 있는 원인이며, 그 증상이 아닙니다.

An unmaintained package requiring php: >=8.1 <8.3 will refuse to install on 8.4, and with nobody maintaining it, that upper bound never gets loosened. The upgrade stalls on a library that stopped receiving maintenance years ago.

Composer는 어떤 패키지가 실행을 방해하고 있는지 정확히 알려줍니다.

composer why-not php 8.4

런타임 업그레이드를 검토하기 전에 이 작업을 먼저 수행해 보세요. 그러면 “PHP 8.4로의 마이그레이션은 큰 불확실성”이라는 말이 구체적이고, 대개 예상보다 짧은 목록으로 바뀌게 되며, 그 목록에는 종종 회의실을 썰렁하게 만드는 이름이 한두 개 포함되어 있기도 합니다.

대략 다음과 같은 결과가 나옵니다:

제약 조건 “8.4”를 충족하는 “php” 패키지를 찾을 수 없으므로, 아래 결과는 불완전할 가능성이 높습니다.

acme/webhook-handler 2.0.0 requires php (>=8.1 <8.3)

원하는 내용을 찾지 못하셨나요? `composer require “php:8.4” –dry-run`을 실행해 보시면 문제를 다른 관점에서 살펴볼 수 있습니다.

composer why-not 는 어떤 패키지와 어떤 제약 조건이 포함되어 있는지 원시 목록을 제공합니다. 각 항목에 대해 어떻게 처리할지는 빠른 후속 확인에 따라 결정되며, composer show vendor/package 명령어를 실행하고 저장소를 살펴보는 것이 필요합니다. 네 가지 결과로 여러분이 마주하게 될 거의 모든 상황을 다룰 수 있습니다.

'why-not'이 반환하는 값 일반적으로 의미하는 바는 현실적인 경로
아무것도 없음 현재의 제약 조건상 업그레이드가 이미 가능합니다. 이제 애플리케이션 호환성 및 테스트로 넘어가겠습니다
관리 중인 패키지 1~2개 상류 버전의 출시를 기다리고 있습니다 이들의 이슈 트래커와 예정된 릴리스를 확인해 보세요
알려진 포크가 포함된 버려진 패키지 지역사회는 변했지만 당신은 변하지 않았어요 포크로 전환하고 호환성 테스트를 위한 예산을 편성하십시오
교환품이 없는 버려진 소포 이제 이 코드의 소유자가 되셨습니다 직접 처리하거나, 패치를 적용하거나, 아니면 누군가에게 돈을 주고 패치를 적용하게 하세요

 

버려진 라이브러리를 자체 저장소로 가져오는 것은 이제 해당 팀이 그 라이브러리의 CVE에 대한 책임이 있다는 것을 의미하지만, 이 방식을 채택하는 대부분의 팀은 이를 위해 별도의 인력을 배치하지 않습니다. 코드는 복사되어 들어오지만, 그에 따른 책임은 함께 따라오지 않습니다.

업스트림 개발자가 개발을 중단한 후 Composer 패키지에 패치를 적용하는 것은 매우 전문적인 분야이며, 이것이 바로 SecureChain for PHP 는 대부분의 엔지니어링 조직이 사내에서 직접 구축하고 유지 관리하고자 하는 기능이라기보다는, 이러한 문제를 처리하기 위해 설계되었습니다.

업스트림 개발이 중단된 후 보안 패치는 어떻게 되나요?

상류 단계에서는 아무런 일도 일어나지 않습니다. 이 부분을 명확히 짚어둘 필요가 있는데, 많은 팀이 어딘가에 안전망이 있을 것이라고 무심코 가정하고 있기 때문입니다.

Packagist는 패키지에 패치를 적용하지 않습니다. 보안 권고 데이터베이스는 취약점을 기록하는데, 이는 유용하지만 취약점을 수정하는 것과는 다릅니다. 유지보수가 중단된 Composer 패키지에 대한 보안 권고는, 유지보수가 재개되거나 포크 버전이 해당 수정 사항을 반영하지 않는 한, 업그레이드할 수 있는 공식 패치 릴리스가 없기 때문에 무기한으로 해결되지 않은 상태로 남아 있을 수 있습니다.

이 상황에서 선택할 수 있는 방안은 많지 않습니다. 코드를 포크하여 직접 수정하거나, 의존성을 교체하거나, 문서화된 보완 통제 조치를 통해 위험을 감수하거나, 뒤처진 코드를 업스트림으로 되돌려 적용하는 것을 전문으로 하는 인력을 영입하는 방법뿐입니다.

참고: 포크에 패치를 적용할 때는 Composer 전략을 신중하게 선택하십시오. 애플리케이션의 경우, 문서화된 방법은 포크를 가리키는 VCS 저장소를 사용하고, 원래 패키지 이름은 그대로 유지하며, 제약 조건은 dev- 브랜치를 대상으로 하는 제약 조건을 설정하는 것입니다. 대신 포크를 본인의 이름으로 게시할 경우, replace를 대체해야 합니다. 그래야 원본을 참조하는 모든 부분이 여전히 정상적으로 해결됩니다. 인라인 별칭은 함정이 될 수 있습니다. 이는 루트에서만 사용할 수 있는 기능으로, as 의 왼쪽 부분이 무시되며, 이로 인한 오류는 대개 몇 달 뒤 다른 사람의 CI에서 드러나게 됩니다.

버려진 각 종속성을 어떻게 처리할지 결정하기

영향 범위와 심각도를 종합적으로 고려해야 합니다. 인증, 결제, 파일 업로드 또는 역직렬화와 관련된 취약점은 그 심각도가 ‘중간’ 수준이라 하더라도 더욱 면밀히 검토해야 합니다. 하지만 이는 양날의 검과도 같습니다. 덜 주목받는 영역에서 발견된, 심각도가 높고 악용되기 쉬운 취약점에 대한 권고 사항이라 하더라도, 영향 범위가 작아 보인다는 이유만으로 그냥 넘어가서는 안 됩니다.

그런 다음 목록을 하나씩 처리해 나가세요. 유지보수 중인 포크가 존재하고 API 호환성이 확보된다면, 해당 포크로 전환하고 테스트를 거친 뒤 다음 단계로 넘어가세요. 이 방법만으로도 팀들이 예상하는 것보다 더 많은 경우를 처리할 수 있지만, 소요되는 노력은 API가 얼마나 달라졌는지와 의지할 수 있는 테스트 커버리지의 정도에 따라 달라집니다. 패키지가 작고 내용을 실제로 이해하고 있다면, 벤더링하여 직접 유지보수를 담당하되, 책임자를 명확히 기록해 두세요. 책임자가 정해지지 않은 벤더링된 코드는 바로 3년 후에 이 문제가 다시 불거지는 원인이 되기 때문입니다.

패키지가 규모가 크거나 보안에 민감한데도 관리하는 사람이 없다면, 벤더링하기 전에 신중하게 고려해야 합니다. 이는 팀이 인력을 투입해 장기적으로 해결해야 할 의무이며, 관리자가 없는 보안 관련 라이브러리는 명백한 외부 의존성보다 더 위험합니다.

이미 진행하기로 결정한 PHP 업그레이드를 버려진 종속성이 가로막고 있다면, 먼저 해당 종속성 문제를 해결하고 런타임 업그레이드는 두 번째 과제로 처리하십시오. 두 가지를 한꺼번에 해결하려고 하면, 범위가 한정된 런타임 마이그레이션이 훨씬 더 방대한 종속성 수정 프로젝트로 변질될 수 있습니다.

또한 규제나 계약상의 제약으로 인해 업스트림의 일정에 맞춰 진행할 수 없는 경우, 런타임과 영향을 받는 패키지 모두에 대해 공급업체가 지원하는 패치 적용을 고려할 수 있습니다. 이를 통해 기업이 실제로 자금을 조달할 수 있는 일정에 따라 마이그레이션이 진행되는 동안에도 보안 수정 사항을 지속적으로 적용받을 수 있습니다.

업그레이드 과정은 애플리케이션의 출시 시기와 프레임워크에 따라 크게 달라집니다. 비교적 최신 버전의 Laravel 애플리케이션이고 의존성 라이브러리가 활발히 유지보수되고 있다면, 업그레이드 과정은 대체로 별다른 어려움 없이 진행됩니다. 반면, 자체 개발 프레임워크를 기반으로 하고 40개의 직접적인 의존성을 가진 10년 된 애플리케이션의 경우 상황은 완전히 다르며, 두 경우 모두에 동일한 일정을 제시하는 사람은 composer why-not 명령어를 실행해 본 적이 없는 것입니다.

또한 당사의 전용 가이드에서 Laravel 보안 모범 사례와 프레임워크 위협 완화 방법에 대해 더 자세히 알아보실 수 있습니다.

PHP 공급망 보안 강화

PHP의 지원 종료 일정은 수년 전에 미리 공개되므로, 일정표를 갖춘 팀이라면 누구나 이를 고려해 계획을 세울 수 있습니다. 더 어려운 문제는 바로 여러분의 composer.lock 파일 안에 숨어 있는 문제입니다. 이는 예고도, 일정도 없이, 유지보수자가 자리를 떠나는 순간 누구도 통제할 수 없는 상태로 발생합니다.

Composer의 자체 도구를 사용하면 어떤 기능이 더 이상 지원되지 않는지 확인할 수 있습니다. 하지만 해당 기능에 대한 패치는 제공하지 않습니다. 바로 이것이 문제점입니다. SecureChain for PHP 는 소스에서 패키지를 재컴파일하고 빌드 단계에 도달하기 전에 검증을 거친 뒤, 취약점이 발견될 때마다 모니터링 및 패치를 적용함으로써 이러한 공백을 메웁니다. 업스트림 패키지 유지보수가 종료되면 TuxCare ELS가 패치 지원 범위를 확장하며, 지원 종료(EOL)에 도달한 PHP 런타임 버전에도 동일한 조치를 취합니다.

라이브러리를 자체 저장소로 포크하여 해당 라이브러리의 CVE를 묵묵히 떠안는 대신, Packagist의 대안으로 검증되고 소스 코드부터 재컴파일된 라이브러리를 동일한 Composer 워크플로우에 바로 적용할 수 있으므로, “유지 관리 중단”이 더 이상 팀이 홀로 감당해야 할 위험 요소가 되지 않습니다.

자주 묻는 질문

PHP 8.1은 언제 지원 종료되나요?

PHP 8.1은 이미 2025년 12월 31일에 지원 종료 시점을 맞이했기 때문에, 제3자 패치 지원이 그 공백을 메우고 있지 않는 한, 현재까지도 이 버전으로 실행 중인 모든 시스템은 그 이후로 업스트림 보안 수정 사항을 적용받지 못하고 있습니다.

현재 어떤 PHP 버전이 여전히 지원되고 있나요?

PHP 8.2, 8.3, 8.4 및 8.5입니다. 이 중 8.2와 8.3은 보안 지원만 제공되며, 8.2의 경우 2026년 12월 31일에 이 지원마저 종료됩니다. 현재 지원 현황은 PHP 공식 지원 버전 페이지에서 확인하시기 바랍니다. 

프로젝트에서 사용되지 않는 Composer 패키지는 어떻게 찾을 수 있나요?

실행 composer audit를 실행하세요. Composer 2.7 이상 버전에서는 기본적으로 폐기된 패키지에 대해 오류가 발생합니다. 또는 composer audit –abandoned=report 를 실행하여 빌드를 중단하지 않고 목록만 확인하세요. 그런 다음 composer show –outdated –direct 를 실행하여 더 새로운 버전이 있는 직접 의존성을 찾아내고, –sort-by-age 옵션을 추가하여 가장 오래된 항목이 맨 위에 표시되도록 하세요. Packagist의 'abandoned' 플래그는 완벽하지 않으므로, 활동이 뜸해 보이는 항목은 저장소 활동 내역을 직접 확인하세요.

CVE가 등록되어 있지만 관리자가 없는 Composer 패키지는 어떻게 되나요?

자문 문서는 공개되지만, 개발이 중단된 프로젝트의 경우 패치된 버전이 출시되지 않을 수도 있습니다. 이 경우 선택할 수 있는 방안은 포크하여 직접 수정하거나, 해당 종속성을 대체하거나, 대체 통제 수단을 문서화하거나, 개발이 중단된 패키지에 대한 수정 사항을 역포트해 주는 공급업체를 이용하는 것입니다.

PHP를 업그레이드하면 오래된 Composer 종속성 문제가 해결되나요?

아닙니다. 보통은 그 반대의 경우가 더 많습니다. 특정 PHP 버전만 지원하는 버려진 패키지가 런타임 업그레이드를 가로막는 주된 원인이 되는 경우가 많기 때문에, composer why-not php 8.4 명령어는 업그레이드 범위 논의의 마지막이 아니라 맨 처음에 다뤄져야 합니다.

지원 종료(EOL)된 PHP를 사용하는 것이 규정 준수상의 문제가 될까요?

그럴 수도 있습니다. 프레임워크에서 취약점의 적시 수정이나 공급업체 지원 소프트웨어를 요구하는 경우, EOL 런타임은 이와 조화를 이루기 어렵습니다. 업스트림에서 수정 제공이 중단되면, 팀은 새로 공개된 취약점이 여전히 수정되고 있음을 입증할 다른 방법을 찾아야 하기 때문입니다. 지원과 같은 확장된 보안 패치 제공 TuxCare 가 제공하는 것과 같은 확장된 보안 패치 서비스는 마이그레이션 기간 동안 이러한 증거를 온전히 유지하는 데 도움이 될 수 있지만, 감사관이 무엇을 만족스러운 증거로 인정할지는 구체적인 프레임워크와 그 구현 방식에 따라 달라집니다.

 

요약
PHP 지원 종료와 아무도 관리하지 않는 Composer 의존성
기사 이름
PHP 지원 종료와 아무도 관리하지 않는 Composer 의존성
설명
PHP의 지원 종료 일자는 쉽게 파악할 수 있습니다. 하지만 애플리케이션 내에 있는 더 이상 유지보수되지 않는 Composer 패키지의 경우 파악하기 어려우며, 대개 이러한 패키지들이 실제로 업그레이드를 가로막는 주된 원인입니다.
작성자
게시자 이름
TuxCare
게시자 로고

4,500명 이상의 Linux 및 오픈 소스 전문가와 함께하세요!

한 달에 두 번. 스팸이 없습니다.

목차
필요한 오픈 소스 보안에 대한 답변 얻기

4,500명 이상의 Linux 및 오픈 소스 전문가와 함께하세요!

한 달에 두 번. 스팸이 없습니다.