Laravel Lang 태그 변조 공급망 공격


요약
2026-05-23 공개된 분석에서 Laravel Lang 계열 Composer 패키지를 겨냥한 공급망 공격이 보고됐다. 핵심은 새 악성 패키지를 배포한 방식이 아니라, GitHub release tag가 악성 commit을 가리키도록 바뀐 점이다. GitHub issue에는 lang, http-statuses, attributes, actions 저장소의 tag가 악성 commit을 가리키도록 재작성됐다는 내용이 올라왔다.
악성 변경의 실행 지점은 Composer autoload에 추가된 src/helpers.php로 지목됐다. vendor/autoload.php가 로드되는 개발 장비, CI runner, 빌드 서버에서 2차 PHP payload 실행과 credential 수집으로 이어질 수 있는 구조다.
| 항목 | 내용 |
|---|---|
| 공개일 | 2026-05-23 |
| 대상 | Laravel Lang localization 관련 저장소와 Composer 패키지 |
| 주요 저장소 | Laravel-Lang/lang, Laravel-Lang/http-statuses, Laravel-Lang/attributes, Laravel-Lang/actions |
| 공격 방식 | GitHub tag reference를 악성 commit으로 재지정 |
| 실행 지점 | composer.json의 autoload.files에 포함된 src/helpers.php |
| 주요 primitive | PHP dropper 실행, 외부 payload 다운로드, credential 수집 |
| 우선 관측 대상 | composer.lock, vendor tree, CI 로그, 패키지 캐시, 외부 통신, secret 사용 이력 |
버전 문자열만으로는 부족하다
tag rewrite는 같은 version constraint가 다른 commit으로 풀릴 수 있게 만든다. composer.lock이 있는 환경도 version만 보지 말고 source.reference와 dist.reference가 기대한 commit인지 확인해야 한다.
공격 흐름
공개 issue 제목 기준으로 Laravel Lang 조직의 여러 저장소에서 tag가 악성 commit을 가리키도록 재작성됐다. Composer는 패키지 버전 해석 과정에서 tag와 source reference를 사용한다. 설치자는 익숙한 패키지명과 기존 버전을 사용하지만, tag가 바뀐 시점에는 vendor 경로에 다른 코드가 내려올 수 있다.
정상 branch 전체가 대규모로 변조된 사건이라기보다, tag 기반 배포 신뢰를 공격한 사건이다. lockfile이 없거나, lockfile을 새로 생성하거나, 내부 mirror와 artifact cache가 변조된 tag 해석 결과를 저장한 환경이 특히 중요하다.
### composer install 또는 composer update
-> GitHub tag가 악성 commit으로 해석
-> vendor/laravel-lang/... 아래 변조된 패키지 설치
-> composer.json autoload.files에 src/helpers.php 포함
-> vendor/autoload.php 로드 시 helpers.php 실행
-> helpers.php가 외부 PHP payload 다운로드 및 실행
-> payload가 로컬 및 CI/CD secret 수집
-> 수집 데이터가 공격자 인프라로 전송
코드 수준 지점
악성 변경의 중심은 composer.json의 autoload 설정과 src/helpers.php다. Composer의 autoload.files 항목은 클래스가 직접 호출되지 않아도 autoloader 로드 시 파일을 include할 수 있다. Laravel localization 패키지처럼 실행 로직이 많지 않아야 하는 패키지에서 새 helper 파일이 autoload에 들어가면 조사 우선순위가 높다.
{
"autoload": {
"files": [
"src/helpers.php"
]
}
}
src/helpers.php는 일반 helper 파일처럼 보일 수 있지만, 공개 분석에서는 외부 payload를 내려받아 실행하는 dropper로 설명됐다. 2차 payload는 Linux, macOS, Windows 환경을 대상으로 credential과 개발 도구 데이터를 찾는 흐름으로 정리됐다.
확인 대상으로 잡을 항목은 cloud credential, Kubernetes config와 secret, Vault token, Git credential, CI/CD secret, SSH key, 브라우저 데이터, cryptocurrency wallet, password manager 데이터, VPN 설정, 로컬 .env 파일이다. Windows에서는 PHP payload 안의 base64 실행 파일이 %TEMP% 아래 임의의 .exe로 기록된 뒤 실행되는 흐름이 보고됐고, 관련 구성요소명으로 DebugElevator가 언급됐다.
영향 범위
정확한 영향 버전 수는 출처별 집계 기준이 다를 수 있다. 운영 판단은 전체 숫자보다 현재 사용하는 package reference 확인에 맞춰야 한다.
| 저장소 또는 패키지 | 공개 자료상 확인된 내용 | 확인 지점 |
|---|---|---|
Laravel-Lang/lang / laravel-lang/lang | tag가 악성 commit을 가리키도록 재작성됐다는 issue 공개 | composer.lock, vendor/laravel-lang/lang, src/helpers.php |
Laravel-Lang/http-statuses / laravel-lang/http-statuses | tag rewrite issue 공개 | vendor 내 helper 파일, autoload 변경 |
Laravel-Lang/attributes / laravel-lang/attributes | tag rewrite issue 공개 | source/dist reference, 설치 산출물 |
Laravel-Lang/actions | tag rewrite issue 공개 | GitHub Actions 또는 CI 참조 여부, tag reference |
이 패키지들은 공식 Laravel framework가 아니라 third-party localization 생태계의 패키지다. 다만 Laravel 프로젝트의 개발 장비, 빌드 서버, preview 환경에 포함될 수 있어 production web request 로그만으로 영향 여부를 판단하면 빠지는 구간이 생긴다.
탐지 포인트
네트워크
주요 IOC로 flipboxstudio[.]info가 언급됐다. DNS, proxy, firewall, EDR network telemetry에서 개발 장비와 CI runner의 egress를 먼저 본다.
flipboxstudio[.]info
단일 도메인 매칭으로 끝내면 부족하다. payload 실행 가능성이 있는 환경에서는 .env, SSH key, GitHub token, cloud access key, Vault token, Kubernetes config가 노출됐다는 전제로 사용 이력을 확인한다.
엔드포인트
vendor tree와 lockfile에서 Laravel Lang 패키지의 helper 파일과 autoload 변경을 찾는다.
grep -R "src/helpers.php" vendor/ composer.lock composer.json 2>/dev/null
grep -R "flipboxstudio" vendor/ storage/ bootstrap/ 2>/dev/null
find vendor -path "*laravel-lang*" -type f -name "helpers.php" -print
Windows 개발 장비와 runner에서는 %TEMP% 아래 생성된 임의 .exe, PHP 프로세스가 만든 실행 파일, 브라우저 credential 저장소 접근 흔적을 함께 본다.
서버
CI/CD runner, build server, package mirror, artifact cache를 우선 확인한다. 이 공격은 애플리케이션 요청 처리보다 Composer 설치와 autoloader 로드 경로에서 먼저 의미가 커진다.
composer show laravel-lang/lang laravel-lang/http-statuses laravel-lang/attributes laravel-lang/actions --locked
composer install --dry-run -vvv
composer.lock에서는 version 문자열만 보지 않는다. source.reference, dist.reference, 설치 시점의 CI 로그, 내부 cache에 저장된 zipball 또는 package artifact를 같이 대조한다.
대응
영향 패키지를 설치한 개발자 장비와 CI runner를 먼저 격리한다. vendor 디렉터리를 지우고 재설치하는 작업은 악성 파일 제거에는 도움이 되지만, 이미 노출된 secret 문제를 해결하지 못한다.
CI/CD secret, GitHub token, cloud access key, package registry token, SSH deploy key는 해당 기간에 Composer install 또는 update가 실행된 환경의 권한 범위에 맞춰 회전한다. self-hosted runner를 사용했다면 runner image, workspace cache, Composer cache, build artifact도 같이 폐기하거나 재검증한다.
내부 mirror나 artifact cache를 운영한다면 cache가 악성 tag 해석 결과를 보관했는지 확인한다. 이후에는 tag 원본성 검증, immutable artifact 사용, lockfile reference 감사, CI egress 제한을 Composer 기반 공급망 통제에 포함한다.
참고 자료
- BleepingComputer: Laravel Lang packages hijacked to deploy credential-stealing malware
- StepSecurity: Laravel-Lang Supply Chain Attack
- Socket: Laravel Lang Compromised with RCE Backdoor Across 700+ Versions
- Laravel-Lang lang issue 8295
- Laravel-Lang http-statuses issue 277
- Laravel-Lang attributes issue 1085
- Laravel-Lang actions issue 1193