2026년 10월 21일 PHP는 긴급 패치를, Node.js는 예고된 보안 릴리스를 같은 날 냈고, 두 결함 모두 애플리케이션 코드에 잘못이 없어도 서버를 내줄 수 있었다.
PHP는 그날 8.5.12, 8.4.27, 8.3.36, 8.2.35를 배포했습니다. 고친 것은 PHP 엔진의 원격 코드 실행 취약점 두 건이었고, 연구자들은 이 둘을 묶어 PHP2Shell이라고 부릅니다. 같은 날 Node.js도 22.x, 24.x, 26.x 세 줄기에 보안 릴리스를 냈는데, 그중 하나는 Node.js에 들어 있는 Brotli 압축 해제 코드가 정해진 메모리 범위를 넘어 쓰는 결함이었습니다. 워드프레스를 최신으로 올려 둔 사이트도, 의존성 경고가 하나도 없는 Express 서버도 런타임을 올리기 전까지는 같은 위험에 놓여 있었습니다.
서비스 개발은 익숙해도 보안은 낯선 개발자가 읽을 수 있도록, 2025년 말부터 2026년 11월까지 PHP와 Node.js 주변에서 일어난 보안 사고를 층별로 정리했습니다. 사고마다 무슨 일이 있었는지, 공격이 어떤 원리로 동작하는지, 무엇으로 막는지를 쓰고, 개별 사고를 넘어 보안 관제를 어떻게 생각하고 준비해야 하는지도 덧붙였습니다.
같은 날 나온 두 보안 패치
보안 뉴스를 읽으려면 세 가지 용어를 먼저 알아야 합니다.
CVE(Common Vulnerabilities and Exposures) 는 공개된 취약점마다 붙는 공용 일련번호입니다. CVE-2026-109618처럼 연도와 번호로 이루어지고, 같은 결함을 두고 여러 기관과 도구가 서로 다른 이름을 쓰지 않게 해 줍니다.
CVSS(Common Vulnerability Scoring System) 는 취약점의 심각도를 0점부터 10점까지 매기는 점수 체계입니다. 9.0 이상을 치명적(Critical)으로 분류하며, 같은 결함이라도 평가 기관이나 CVSS 버전에 따라 점수가 다르게 나올 수 있습니다.
원격 코드 실행(Remote Code Execution, RCE) 은 공격자가 네트워크로 요청만 보내서 서버가 공격자의 명령을 실행하게 만드는 상태입니다. RCE가 되면 공격자는 서버의 파일을 읽고, 비밀값을 가져가고, 다른 시스템으로 옮겨갈 발판을 마련할 수 있습니다.
PHP2Shell의 두 CVE는 PHP 보안팀 기준 CVSS 9.2로 매겨졌습니다. 그리고 패치보다 공격이 먼저 시작됐습니다. AWS는 공개 4일 전인 10월 17일에 자사 허니팟(공격을 관찰하려고 일부러 열어 둔 미끼 서버)에서 첫 악용 시도를 기록했지만, 공격자가 어떻게 정보를 얻었는지는 밝혀지지 않았습니다. 10월 20일에는 CVE 번호와 틀린 일정·점수가 먼저 돌았고, PHP 재단은 기술 상세는 유출되지 않았다고 밝혔습니다. 패치가 나온 뒤 2시간 안에 악용 시도가 수십만 건, 다음 날에는 수백만 건으로 늘었다고 Cloudflare CEO가 밝혔습니다. 미국 사이버보안·인프라보안청(CISA)은 10월 26일 두 CVE를 실제 악용 취약점 목록에 올렸습니다.
실제 침해도 보고되었습니다. Dream Research는 공격자가 PHP2Shell과 리눅스 커널 권한 상승 결함 Fragnesia(CVE-2026-46300)를 이어 미국, 일본, 대만, 한국에서 PAN-OS(Palo Alto Networks 방화벽 운영체제) 방화벽과 관리 서버 25대의 루트 권한을 얻었다고 보고했고, Palo Alto Networks의 Unit 42도 공격자의 도구와 결과를 확인했습니다. 다만 SecurityWeek는 10월 30일 기준으로 확인된 침해가 아직 많지 않다고 정리했습니다. Unit 42가 유럽 정부기관 공격을 이 결함의 악용으로 보고했다가 10월 25일에 철회한 일도 있습니다.
Node.js의 Brotli 결함은 사정이 조금 다릅니다. 수정 코드는 2026년 2월 27일에 이미 google/brotli 저장소에 올라가 있었지만, 릴리스나 보안 공지 없이 8개월 동안 공개 상태로 남아 있었습니다. 패치 내용을 공격자가 먼저 읽을 수 있었다는 뜻입니다.
두 사례 모두 공격자가 결함을 알 수 있었던 시점이 패치 배포보다 앞섰습니다. 그래서 인터넷에 노출된 런타임의 보안 패치는 다음 정기 배포를 기다리지 않고 공지가 나온 그날 적용해야 합니다.
공격은 어디로 들어오는가
사고를 하나씩 보기 전에, 공격이 서버까지 도달하는 길을 두 갈래로 나눠서 살펴봤습니다.
첫 번째 길은 운영 중인 서비스로 들어오는 요청입니다. 사용자의 HTTP 요청이 웹 서버를 지나 PHP나 Node.js 같은 런타임에 도착하고, 프레임워크와 라이브러리를 거쳐 애플리케이션 코드에 닿습니다. 이 길에서는 요청 하나가 런타임이나 프레임워크의 결함을 건드려 코드 실행까지 이어질 수 있습니다.
두 번째 길은 서비스를 만드는 과정으로 들어오는 코드입니다. npm이나 Packagist에서 받은 패키지가 개발자 PC와 CI 빌드 서버를 거쳐 배포 산출물이 되고, 결국 운영 서버의 일부가 됩니다. 개발자 PC에서 돌아가는 AI 코딩 도구도 이 길 위에 있습니다.
두 길은 다시 다섯 개의 층으로 나눌 수 있습니다.
| 층 | 무엇이 뚫리는가 | 대표 사례 |
|---|---|---|
| 런타임 | 코드를 실행하는 엔진 자체 | PHP2Shell, Node.js Brotli, PHP-FPM 서비스 거부 |
| 프레임워크·라이브러리 | 가져다 쓰는 외부 코드 | React2Shell, Laravel Livewire·Reverb, Nuxt, 워드프레스 플러그인, Express |
| 공급망 | 패키지를 받아 설치하는 과정 | Axios, node-ipc, Mini Shai-Hulud, PackageGate |
| 작업 환경 | 개발자 PC, CI, 개발 서버, 배포 과정, 사무 공간 | 자격증명 탈취, 개발 서버의 비밀값 노출, PHPUnit, 피싱과 랜섬웨어 |
| AI | 코딩 에이전트와 모델 | Qwen3.8-Flash-Next, Qwen Code, MCP |
런타임: 코드를 실행하는 엔진의 결함
런타임(runtime) 은 개발자가 쓴 코드를 실제로 읽고 실행하는 엔진입니다. PHP 코드는 PHP 엔진이, 서버의 자바스크립트는 Node.js가 실행합니다. 런타임에 결함이 있으면 그 위에서 도는 모든 애플리케이션이 함께 영향을 받습니다. 그래서 애플리케이션 코드를 아무리 꼼꼼히 검토해도 런타임 패치를 대신할 수 없습니다.
PHP2Shell: 실패한 요청이 남긴 상태를 다음 요청이 믿을 때
PHP는 요청마다 메모리를 따로 잡아 쓰고, 요청이 끝나면 그 메모리를 돌려줍니다. 그런데 요청을 처리하는 프로세스는 요청이 끝나도 사라지지 않습니다. 워커(worker) 는 웹 서버나 PHP-FPM이 미리 띄워 두고 여러 요청을 차례로 처리하게 하는 프로세스로, 프로세스를 매번 새로 만드는 비용을 줄이려고 재사용합니다. PHP2Shell의 두 결함 중 CVE-2026-109619는 이 재사용 구조에서 생겼습니다.
세션 업로드 진행률 경로를 예로 들면 공격은 두 단계로 진행됩니다.
- 공격자가 조작한 파일 업로드 요청을 보냅니다. PHP는 업로드 진행률을 기록하는 기능(세션 업로드 진행률)이 기본으로 켜져 있어, 애플리케이션 코드가 돌기도 전에 이 요청을 해석하기 시작합니다. 요청이 메모리 한도를 넘기도록 만들면 PHP는 요청을 강제로 끝내는데, 이때 정리 작업 일부가 생략되어 이미 돌려준 메모리를 가리키는 포인터가 워커에 남습니다.
- 공격자가 같은 워커로 업로드 진행률 필드를 담은 요청을 다시 보내면, PHP는 정상 초기화가 끝나기 전에 남아 있던 포인터를 그대로 사용합니다. 돌려준 메모리 자리에는 이미 다른 데이터가 들어가 있는데 PHP는 그 값을 진짜 값으로 읽습니다. 공격자가 그 자리에 들어갈 값을 넣을 수 있으면 메모리 내용이 새어 나가고, 조건이 맞으면 코드가 실행됩니다.
이렇게 해제한 메모리를 다시 사용하는 결함을 해제 후 사용(Use-After-Free, UAF) 이라고 부릅니다. 반납한 사물함에 내 물건을 그대로 넣어두었다가 다른 사람이 그 사물함을 열 때 내 물건이 쓰이게끔 만든 셈입니다.
CVE-2026-109618은 워커 재사용이 없어도 성립합니다. 요청 시작 단계에서 메모리가 바닥나면 초기화가 덜 된 요청 데이터가 남고, 같은 요청의 종료 처리가 그 데이터를 읽습니다.
결함이 애플리케이션 코드보다 앞 단계에 있어서, 워드프레스나 라라벨을 최신으로 유지한 사이트도 PHP를 올리기 전까지는 위험에 노출됩니다. 실행 방식별 위험도는 다릅니다. Apache의 mod_php에서는 기본 설정에서 인증 없는 원격 코드 실행이 시연됐고, PHP-FPM은 요청 시작 단계에서 실패하면 자식 프로세스가 종료되어 같은 경로가 막히는 대신 다른 조건에서 영향을 받습니다. 두 CVE의 구조, 실행 방식별 차이, 배포판별 수정 버전은 PHP2Shell 분석: PHP 엔진의 RCE 취약점 두 건과 대응 방법에 정리했습니다.
대응은 다음 순서로 해야 합니다.
- PHP를 8.5.12, 8.4.27, 8.3.36, 8.2.35 이상으로 올려야 합니다. 8.1 이하는 공식 릴리스가 나오지 않습니다. PHP 보안팀이 7.4·8.0·8.1용 최소 소스 패치를 공개했고 배포판·LTS 업체의 백포트도 있지만, 임시 조치이므로 지원되는 버전으로 옮겨야 합니다. 8.2도 2026년 12월 31일에 보안 지원이 끝납니다.
- 패치 후 PHP-FPM, Apache, LiteSpeed 같은 실행 프로세스를 모두 재시작하고, 컨테이너는 이미지를 다시 빌드해 교체해야 합니다. 배포판 패키지는 버전 번호를 바꾸지 않고 수정만 넣는 경우가 있어
php -v보다 배포판의 보안 공지와 변경 이력을 확인해야 합니다. - 바로 올릴 수 없다면
session.upload_progress.enabled=0으로 업로드 진행률 기능을 끄고,memory_limit=-1을 관리자 설정으로 고정하고, 웹 서버에서 요청 크기를 줄이는 등의 부분 완화를 적용할 수 있습니다. PHP 보안팀은 완전한 임시 대책이 없고 업데이트만이 안전하다고 공지했습니다. - 패치 뒤에도 런타임에
session.serialize_handler를 바꾸는 애플리케이션은 다음 정기 릴리스까지session.upload_progress.enabled=0을 유지해야 합니다. PHP는 10월 23일 권고에서 이 드문 구성에 남은 RCE 경로(CVE-2026-115560)를 알렸고, 정식 권고는 다음 릴리스와 함께 내겠다고 밝혔습니다. - 패치를 마친 서버도 적어도 10월 17일 이후의 로그를 확인해야 합니다. KISA는 큰 요청 뒤에 반복되는 500 오류, 웹 서버가 sh나 다운로드 도구를 실행한 흔적, 웹·업로드·임시 폴더에 새로 생긴 PHP 파일, 알 수 없는 외부 주소로의 연결을 점검 대상으로 꼽았습니다. 패치 전에 노출되어 있던 서버라면 DB 비밀번호와 API 키도 교체해야 합니다. KISA는 교체를 권장하고, 침해 흔적이 발견된 서버는 반드시 교체하라고 안내합니다.
Node.js Brotli 디코더: 정해진 칸을 넘어 쓰는 압축 해제
Brotli 는 gzip처럼 데이터를 압축하는 형식으로, 웹 응답 압축에 널리 쓰입니다. Node.js는 Brotli 압축 해제 코드를 런타임 안에 포함하고 있어서, 개발자가 따로 라이브러리를 설치하지 않아도 이 코드를 사용하게 됩니다. 2026년 10월 21일 공개된 CVE-2026-111497은 이 압축 해제 코드의 결함입니다.
정상적인 디코더는 형식이 잘못된 압축 데이터를 받으면 오류로 처리해야 합니다. 그런데 결함이 있는 디코더는 잘못된 블록 전환 정보를 형식 오류가 아니라 “입력이 더 필요하다”는 신호로 해석했고, 그 상태에서 8바이트짜리 작은 버퍼 뒤로 데이터를 계속 이어 썼습니다. 이렇게 정해진 크기를 넘어 옆 메모리를 덮어쓰는 결함을 경계 밖 쓰기(out-of-bounds write) 라고 부릅니다. 덮어쓴 위치에 따라 프로세스가 죽거나 메모리 내용이 새어 나가고, 조건이 맞으면 코드가 실행됩니다.
이 결함이 위험한 이유는 개발자가 압축 해제를 직접 호출하지 않아도 해당 코드에 닿기 때문입니다. Node.js 앱이 Brotli 디코더를 거치는 대표적인 경로는 세 가지입니다.
zlib.brotliDecompress(),createBrotliDecompress()같은 함수를 직접 호출하는 경우입니다.- 내장
fetch()로 외부 서버에서 응답을 받는 경우입니다. 응답에Content-Encoding: br헤더가 있으면 자동으로 압축을 풉니다. 그래서 공격자가 통제하는 서버의 응답을 받아오는 기능(웹훅 검증, 링크 미리보기 등)도 경로가 됩니다. - Express 5에서 body-parser 2.x 기반 파서를 쓰는 경우입니다. body-parser 2.x는
Content-Encoding: br로 들어온 요청 본문을 자동으로 풉니다.
결함이 실제로 악용 가능함을 보여주는 시연용 공격 코드를 개념 증명(Proof of Concept, PoC) 코드라고 합니다. 공개 직후 나온 PoC는 일부러 보호 기능을 약하게 만든 빌드에서만 코드 실행에 성공했고, 일반 빌드에서는 충돌과 제한적인 메모리 노출에 그쳤습니다. 그러나 Imperva는 공식 Node.js 24.22.0 리눅스 arm64 이미지에서 fetch()와 Express 5 경로로, 매번은 아니지만 원격 코드 실행에 성공했다고 밝혔습니다. 이후 ELLIO는 공식 x86-64 빌드에서도 재현했다고 밝혔고, 10월 26일에는 실제 공격 트래픽도 관측했다고 보고했습니다. 다만 그 공격 체인은 ELLIO의 시험에서 50회 모두 실패했습니다. CISA는 10월 27일 이 결함을 실제 악용 취약점 목록에 올렸습니다. 같은 Brotli 코드를 쓰는 .NET, Bun, Envoy, 파이썬 brotli 패키지도 각각 업데이트를 냈고, PHP도 cURL의 자동 압축 해제를 켠 Windows 빌드가 영향을 받는다고 공지했습니다.
대응은 다음과 같습니다.
- Node.js를 22.23.4, 24.22.1, 26.12.1 이상으로 올리고, 컨테이너 이미지와 단일 실행 파일로 묶은 앱도 다시 빌드해 재시작해야 합니다.
process.versions.brotli는 패치된 빌드에서도 예전 버전을 표시하므로 Node.js 버전으로 확인해야 합니다. 배포판 패키지는 시스템 Brotli를 쓸 수 있으므로 배포판 공지도 함께 확인해야 합니다. Node.js는 11월 11일에 다음 보안 릴리스를 예고했으므로 그 뒤에는 새 버전을 확인해야 합니다. - 당장 올릴 수 없다면 Brotli로 압축된 요청 본문을 웹 서버나 CDN 단계에서 거부하고, body-parser에
inflate: false를 설정해 압축된 본문을 받지 않을 수 있습니다. 다만 이 방법은 들어오는 요청만 막고,fetch()로 받아오는 응답 경로는 막지 못합니다. - Node.js 프로세스가 반복해서 죽고 재시작되는지, 코어 덤프가 쌓이는지,
node프로세스가 셸이나curl을 실행했는지를 확인해야 합니다. Imperva는 프로세스 종료와 디코더 오류만으로 악용을 단정할 수는 없다고 설명합니다.
Node.js 20.x는 2026년 4월 30일에 지원이 끝났습니다. 지원이 끝난 버전에는 이번 패치가 나오지 않았고, Node.js는 지원 종료 버전을 항상 영향을 받는 것으로 간주한다고 밝혔습니다.
프레임워크와 라이브러리: 데이터가 코드로 바뀌는 지점
프레임워크는 요청을 받아 객체로 바꾸고, 템플릿을 그리고, 사용자를 확인하는 일을 대신해 줍니다. 편리한 만큼 프레임워크가 요청을 해석하는 방식에 결함이 있으면, 그 프레임워크를 쓰는 모든 서비스가 같은 결함을 갖게 됩니다. 이 글에서 다루는 사례는 대부분 밖에서 들어온 데이터가 어느 순간 코드처럼 실행되는 지점에서 생겼습니다.
React2Shell과 그 뒤의 React Server Components 결함
React Server Components(RSC) 는 컴포넌트를 서버에서 실행하고 결과만 브라우저로 보내는 React 19의 구조입니다. 브라우저가 서버의 함수를 호출할 때(Server Functions) 둘은 Flight라는 React 고유의 형식으로 데이터를 주고받습니다. 서버는 받은 Flight 데이터를 다시 자바스크립트 값과 객체로 되살리는데, 이 과정을 역직렬화(deserialization) 라고 합니다. 직렬화는 객체를 전송하거나 저장할 수 있는 문자열로 바꾸는 일이고, 역직렬화는 그 문자열을 다시 객체로 만드는 일입니다.
2025년 12월 3일 공개된 CVE-2025-55182(React2Shell)는 이 역직렬화를 공격자가 조작할 수 있었던 결함입니다. CVSS 10.0, 로그인 없이 원격 코드 실행이 가능했고, 앱이 Server Function을 직접 정의하지 않았어도 RSC를 지원하면 영향을 받을 수 있었습니다. AWS는 공개 몇 시간 만에 중국 연계 그룹들의 악용 시도를 관측했고, CISA는 이틀 뒤인 12월 5일 실제 악용 취약점 목록에 올렸습니다. React는 19.0.1, 19.1.2, 19.2.1에서 이 결함을 고쳤습니다.
React2Shell 이후에도 RSC 주변의 결함은 계속 나왔습니다. 2026년 4월에는 조작된 요청 하나로 CPU를 최대 1분 동안 붙잡는 서비스 거부 취약점(CVE-2026-23869)이, 5월에는 메모리 부족과 CPU 과부하를 일으키는 비슷한 취약점(CVE-2026-23870)이 나왔습니다. 5월 Next.js 보안 릴리스는 CVE-2026-23870을 포함해 13건을 한꺼번에 고쳤는데, 미들웨어 우회 4건, 서버가 공격자가 정한 내부 주소로 요청을 보내게 만드는 SSRF, 캐시 오염, 다른 사용자의 브라우저에서 스크립트를 실행시키는 XSS가 섞여 있었습니다. 이 릴리스의 수정 버전은 15.5.18과 16.2.6이고, 13.x와 14.x에는 패치가 나오지 않았습니다. Vercel은 이 결함들이 웹 방화벽(WAF)으로 안정적으로 막을 수 있는 종류가 아니라고 밝혔습니다.
5월 이후에도 치명적 등급의 원격 코드 실행 권고가 이어졌습니다. 8월 25일에는 Windows에서 호스팅하는 서버(CVE-2026-75604)와 AVIF 이미지 최적화(GHSA-2xp9-vwfh-vxw4), 9월 22일에는 next/og의 ImageResponse(CVE-2026-94545), 10월 14일에는 SVG 이미지 최적화(CVE-2026-96889)와 use cache(GHSA-673q-mjm6-r5xr)의 결함이 공개되었습니다. React도 10월 14일 드문 조건에서 RSC로 원격 코드 실행이 가능한 결함(GHSA-xqc2-xf4c-x3h3)을 고쳤습니다. 그래서 2026년 11월 4일 기준으로 Next.js는 16.4.5나 15.5.29 이상으로, react-server-dom-*는 19.0.9, 19.1.10, 19.2.9, 19.3.1 이상으로 올려야 합니다. 13.x와 14.x에는 이 결함들의 패치도 나오지 않았습니다.
미들웨어 우회가 반복된다는 점에서 가져갈 교훈이 있습니다. Next.js의 미들웨어는 요청이 페이지에 닿기 전에 인증 같은 검사를 하는 코드이고, 요청 경로를 기준으로 동작합니다. 그런데 같은 페이지를 가리키는 다른 형태의 URL(예: RSC 데이터 요청이나 프리페치 요청)이 미들웨어 규칙을 비껴가는 일이 여러 번 생겼습니다. 그래서 인증 확인은 미들웨어에만 두지 말고 페이지나 라우트 핸들러 안에서도 해야 합니다. 2025년 12월부터 2026년 5월까지 나온 React·Next.js CVE의 재현 방식과 패치를 당장 못 올릴 때의 대처법은 React/Next.js CVE 6개월 정리에 자세히 정리했습니다.
Laravel Livewire와 Reverb: PHP 객체로 되살아나는 입력
PHP에도 역직렬화 함수 unserialize()가 있습니다. PHP 객체에는 객체가 만들어지거나 사라질 때 자동으로 호출되는 __wakeup(), __destruct() 같은 매직 메서드(magic method) 가 있어서, 공격자가 어떤 클래스의 객체를 만들지 고를 수 있으면 원래 의도하지 않은 코드가 실행됩니다. 공격자는 프로젝트에 이미 설치된 라이브러리의 코드 조각을 이어 붙여 명령 실행까지 가는데, 이렇게 이은 연쇄를 가젯 체인(gadget chain) 이라고 부릅니다. PHPGGC라는 공개 도구에 Laravel, Monolog 같은 유명 라이브러리용 가젯 체인이 모여 있어 공격자는 체인을 새로 만들 필요도 없습니다.
Livewire는 Laravel에서 서버 코드만으로 반응형 화면을 만드는 라이브러리입니다. 컴포넌트의 상태를 브라우저에 두었다가 값이 바뀌면 /livewire/update로 서버에 보내는데, 서버는 받은 값을 원래 타입으로 되살립니다(hydration). CVE-2025-54068은 이 되살리는 과정에서, 타입을 선언하지 않은 속성(예: public $count)의 값 자리에 Livewire 내부의 타입 표시 형식을 흉내 낸 배열을 넣으면 서버가 공격자가 의도한 PHP 객체를 만들어 버리는 결함이었습니다. 로그인도, 애플리케이션 암호화 키(APP_KEY)도 필요 없었지만, 공지에 따르면 컴포넌트가 특정한 방식으로 구성되어 있어야 합니다. Livewire 3.6.4에서 고쳐졌고, CISA는 2026년 3월 20일 실제 악용 취약점 목록에 올렸습니다.
2026년 6월 Imperva는 이 결함을 이용한 대규모 자격증명 탈취 작전을 공개했습니다. Imperva는 5월 24일 자사 웹 방화벽이 막은 평범해 보이는 역직렬화 공격 트래픽을 조사하다가 이 작전을 발견했습니다. 공격자는 서버에 스크립트를 내려받게 해 .env 파일을 찾아 압축한 뒤 밖으로 보냈고, 6,000개가 넘는 애플리케이션에서 DB 비밀번호와 결제·클라우드 키가 빠져나갔다고 밝혔습니다. Laravel의 .env에는 APP_KEY도 들어 있습니다. APP_KEY를 아는 공격자는 Livewire 3 이상이면 패치 여부와 상관없이 서명을 위조해 코드를 실행할 수 있으므로, 침해가 의심되면 Livewire를 올리는 것과 별개로 APP_KEY와 .env의 모든 비밀값을 교체해야 합니다.
같은 구조의 결함이 Laravel의 웹소켓 서버 Reverb에도 있었습니다(CVE-2026-23524, CVSS 9.8). Reverb 서버를 여러 대로 늘리는 수평 확장 설정(REVERB_SCALING_ENABLED=true)을 켜면 서버끼리 Redis로 메시지를 주고받는데, 받은 메시지를 클래스 제한 없이 unserialize()했습니다. Redis에 메시지를 쓸 수 있는 사람이면 누구나 서버에 객체를 만들게 할 수 있었고, Redis는 비밀번호 없이 운영되는 경우가 많습니다. 1.7.0에서 되살릴 수 있는 클래스를 세 개로 제한하는 방식으로 고쳐졌습니다.
PHP 역직렬화로 생기는 결함은 다음과 같이 막아야 합니다.
- 밖에서 온 데이터에는
unserialize()를 쓰지 않고json_decode()를 써야 합니다. JSON은 문자열, 숫자, 배열 같은 값만 만들고 객체의 메서드를 호출하지 않습니다. - 내부에서 만든 데이터에
unserialize()를 꼭 써야 한다면allowed_classes옵션으로 되살릴 수 있는 클래스를 좁혀야 합니다. PHP 매뉴얼은 이 옵션을 써도 신뢰할 수 없는 입력을 넘기지 말라고 경고합니다. - Redis 같은 내부 저장소도 비밀번호를 걸고 사설망에만 열어 둬야 합니다. 내부에 있다는 이유로 신뢰하면 그 저장소에 접근한 공격자가 서버 코드까지 실행하게 됩니다.
Nuxt Server Island: props가 템플릿 코드가 될 때
Nuxt의 Server Island 는 페이지의 일부 컴포넌트만 서버에서 렌더링해 HTML 조각으로 보내는 기능입니다. 브라우저는 /__nuxt_island/ 경로에 컴포넌트 이름과 props를 담아 요청합니다. 그런데 2026년 7월 공개된 CVE-2026-71320(CVSS 8.1)에 따르면, 아일랜드 컴포넌트가 받은 props를 <component :is> 같은 동적 컴포넌트 자리에 넘기면 공격자가 { "as": { "template": "…" } } 같은 객체를 보내 서버에서 Vue 템플릿을 컴파일하고 실행시킬 수 있었습니다. 처음 공지에는 vue.runtimeCompiler: true 설정이 조건으로 적혀 있었지만, 이후 공지가 갱신되어 Nuxt 3·4의 기본 설정으로 Node 서버를 띄운 경우도 영향 범위에 포함되었습니다. reka-ui나 @nuxt/ui처럼 as props로 렌더링할 요소를 바꾸는 컴포넌트를 아일랜드의 최상위에 두면, props를 따로 넘기지 않아도 같은 공격 경로가 만들어집니다.
공지된 수정 버전은 Nuxt 3.21.10과 4.5.1입니다. 영향 범위에 대한 공지가 한 번 갱신되었으므로 적용 전에 최신 공지를 확인하는 것이 좋습니다. 다만 패치는 선언하지 않은 최상위 as와, vue.runtimeCompiler가 켜진 경우의 template 키를 거부할 뿐이므로, 아일랜드 props를 <component :is>에 직접 넘기는 코드는 업데이트와 별개로 고쳐야 합니다. 업데이트 전에는 /__nuxt_island/ 요청의 props에서 template, render 키를 막는 방법으로 위험을 줄일 수 있지만, 공지는 웹 방화벽만으로 이 경로를 닫을 수는 없다고 덧붙입니다. 같은 경로에서 다른 결함도 나왔습니다. 5월에는 .server.vue 페이지를 아일랜드로 렌더링하면 definePageMeta의 라우트 미들웨어가 실행되지 않는 문제(CVE-2026-47200)가 고쳐졌습니다. 미들웨어를 비껴가는 문제는 경로 해석에서도 나왔습니다. 10월에는 일반 페이지 라우트에서 /%2e/admin처럼 점 구간을 섞은 URL이 서버 미들웨어 검사를 비껴가는 문제(CVE-2026-119200, 4.6.3에서 수정)가, 11월에는 //x/admin 형태의 같은 우회(4.6.4에서 수정)가 나왔으므로 4.6.4 이상을 쓰는 것이 좋습니다. Next.js와 마찬가지로 인증 확인을 미들웨어 한 곳에만 맡기면 안 됩니다.
세 프레임워크의 사례를 나란히 놓으면 공격 데이터가 코드로 바뀌는 지점이 각각 다르다는 것을 알 수 있습니다.
| 사례 | 공격 데이터가 들어오는 곳 | 코드로 바뀌는 순간 | 수정 버전 |
|---|---|---|---|
| React2Shell | Server Function으로 가는 요청 | Flight 데이터를 객체로 되살릴 때 | 19.0.1, 19.1.2, 19.2.1 |
| Livewire | /livewire/update의 상태 변경 값 | 상태를 원래 타입으로 되살릴 때 | 3.6.4 |
| Reverb | 서버 사이의 Redis 메시지 | unserialize() | 1.7.0 |
| Nuxt Server Island | /__nuxt_island/의 props | 동적 컴포넌트가 템플릿을 컴파일할 때 | 3.21.10, 4.5.1 |
표의 수정 버전은 각 결함이 처음 고쳐진 버전이므로, 실제로는 각 프로젝트의 최신 패치 버전으로 올려야 합니다.
워드프레스: 코어와 플러그인의 인증 우회
워드프레스는 코어 자체의 결함과 플러그인의 결함을 함께 봐야 합니다. 2026년 7월 17일 워드프레스는 7.0.2를 긴급 배포했습니다. 연구자들이 wp2shell이라고 부른 이 결함은 두 CVE의 연쇄였습니다. REST API의 일괄 처리(batch) 엔드포인트가 잘못된 하위 요청을 만나면 검증 결과와 실행할 핸들러의 순서가 어긋나 매개변수 검증을 건너뛸 수 있었고(CVE-2026-63030), 그렇게 검증 없이 들어간 author_exclude 값이 WP_Query의 author__not_in에서 SQL 인젝션을 일으켰습니다(CVE-2026-60137). 둘을 이으면 로그인 없이 원격 코드 실행까지 갈 수 있었고(영구 객체 캐시를 쓰지 않는 사이트 기준으로, 기본 설치가 여기에 해당합니다), 실제 공격에서는 웹셸이 올라왔습니다. 웹셸(web shell) 은 공격자가 서버에 몰래 올려 두고 웹 요청으로 명령을 실행하는 스크립트로, 결함을 패치한 뒤에도 공격자가 다시 들어올 수 있는 뒷문이 됩니다. 공개 몇 시간 만에 GitHub에 공격 코드가 여럿 올라왔지만 초기 코드는 대부분 SQL 인젝션까지였고, 공격 시도는 공개 몇 시간 뒤부터 보고되었습니다. CISA는 7월 21일 두 CVE를 실제 악용 취약점 목록에 올렸습니다. 수정 버전은 6.8.6, 6.9.5, 7.0.2이며, 일괄 처리 경로 결함은 6.9에서 생긴 것이라 6.8 계열은 SQL 인젝션만 문제였습니다. 이후 보안 릴리스가 더 나와 세 버전 모두 지금은 안전하지 않은 버전으로 표시되므로, 최신 버전(2026년 11월 4일 기준 7.1.4)으로 올려야 합니다. 11월 3일에는 코어의 다른 결함(CVE-2026-119977)이 CISA 목록에 올랐습니다.
플러그인 쪽은 2026년에 같은 유형이 반복되었습니다. 대표 사례인 Modular DS는 여러 워드프레스 사이트를 한 대시보드에서 관리하게 해 주는 플러그인으로, 4만 곳이 넘는 사이트에 설치되어 있었습니다. 이 플러그인에는 Modular 관리 서비스가 보낸 요청만 받는 내부용 경로가 있었는데, 요청이 정말 그 서비스에서 왔는지를 URL에 origin=mo와 아무 값의 type이 있는지로만 판단했습니다. 서명이나 비밀값 확인이 없었고, 사이트가 Modular에 연결되어 있으면 인증 미들웨어도 통과했으며, 로그인 처리 경로는 사용자를 지정하지 않으면 기존 관리자로 로그인시켰습니다. Patchstack 기준 CVSS 10.0으로 매겨진 이 결함(CVE-2026-23550)은 Patchstack에 따르면 2026년 1월 13일부터 패치가 나오기 전에 이미 악용되었습니다. 이후 추가 악용 경로(CVE-2026-23800)가 나와 2.6.0 이상으로 올려야 합니다.
같은 해에 지도 플러그인 WP Maps Pro(CVE-2026-8732)는 모든 공개 페이지에 찍혀 나오는 토큰만 확인하는 AJAX 기능으로 누구나 관리자 계정을 만들 수 있었고, User Registration & Membership(CVE-2026-1492)은 회원가입 때 사용자가 보낸 역할 값을 서버에서 검사하지 않아 방문자가 관리자로 가입할 수 있었습니다. 세 플러그인 모두 서버가 “누가 보냈는가”와 “이 사람에게 이 권한이 있는가”를 확인하지 않은 결함입니다.
워드프레스 사이트는 다음을 지켜야 합니다.
- 코어의 보안 업데이트는 자동 업데이트로 받고, 플러그인도 업데이트 알림을 받는 즉시 올려야 합니다. 쓰지 않는 플러그인은 비활성화가 아니라 삭제해야 합니다.
- 관리자 계정 목록을 정기적으로 확인해야 합니다. 위 사례 대부분은 관리자 계정을 새로 만들거나 관리자로 로그인하는 것으로 이어졌습니다.
- 플러그인을 직접 만든다면, 내부용 API도 요청 서명이나 비밀값으로 출처를 검증하고, 역할이나 권한처럼 사용자가 바꾸면 안 되는 값은 서버에서 정하고 검증해야 합니다.
서비스 거부: 서버를 멈추게 만드는 요청
서비스 거부(Denial of Service, DoS) 는 서버를 멈추거나 느리게 만들어 정상 사용자가 서비스를 쓰지 못하게 하는 공격입니다. 데이터가 새어 나가지는 않아서 원격 코드 실행보다 가볍게 보이지만, 요청 몇 개로 서비스 전체가 멈춘다면 장애와 다르지 않습니다. 많은 트래픽을 퍼붓는 방식과 달리, 여기서 다루는 결함은 잘 만든 요청 몇 개로 CPU, 메모리, 파일 디스크립터를 고갈시키거나 프로세스를 죽이는 종류입니다.
Node.js에서는 이 종류의 결함이 특히 크게 작용합니다. Node.js는 이벤트 루프(event loop) 라는 하나의 실행 흐름에서 모든 요청의 자바스크립트 코드를 차례로 처리합니다. 데이터베이스나 파일을 기다리는 동안에는 다른 요청을 처리할 수 있지만, 자바스크립트 코드가 CPU를 계속 쓰는 동안에는 다른 요청이 모두 기다려야 합니다. 요청 하나가 CPU를 10초 붙잡으면 그 프로세스의 다른 사용자도 10초 동안 응답을 받지 못합니다.
정규식 하나가 CPU를 붙잡는 원리
정규식 엔진은 패턴과 입력을 맞춰 보다가 실패하면 조금 전 갈림길로 돌아가 다른 방법을 시도합니다. 이렇게 되돌아가 다시 시도하는 동작을 백트래킹(backtracking) 이라고 합니다. /^(a+)+$/처럼 반복 안에 반복이 들어간 패턴은 같은 문자열을 나누는 방법이 아주 많아서, 끝에서 일치에 실패하면 그 모든 나눔을 하나씩 시도합니다. 입력이 조금만 길어져도 시도 횟수가 기하급수로 늘어나고, 이를 이용한 공격을 정규식 서비스 거부(ReDoS) 라고 부릅니다.
위 그래프는 직접 측정한 값입니다. a가 30개인 31글자짜리 입력 하나에 6초가 걸렸고, 그동안 같은 프로세스의 다른 요청은 하나도 처리되지 않았습니다. 같은 입력을 반복 없는 /^a+$/로 검사하면 0.05ms에 끝납니다. 같은 입력이라도 실행 시간을 정하는 것은 패턴의 모양입니다.
Express 라우터의 path-to-regexp
이 원리가 2026년 3월 Express 생태계에서 실제로 문제가 되었습니다. Express는 /users/:id 같은 라우트 경로를 path-to-regexp 라이브러리로 정규식으로 바꿔 요청 URL과 비교합니다. 라우트 경로에 따라 만들어진 정규식이 백트래킹 폭발을 일으키거나 크기가 폭증하는 결함이 세 건 공개되었습니다.
| CVE | 영향 버전 | 위험한 라우트 모양 | 수정 버전 |
|---|---|---|---|
| CVE-2026-4867 (높음) | 0.1.12 이하 (Express 4) | /:a-:b-:c처럼 한 구간에 매개변수 셋 이상(마침표 외 구분자) | 0.1.13 |
| CVE-2026-4926 (높음) | 8.x (Express 5) | {a}{b}{c}:z처럼 연달아 붙은 선택 그룹 | 8.4.0 |
| CVE-2026-4923 (보통) | 8.0.0 ~ 8.3.0 (Express 5) | /*foo-*bar-:baz처럼 와일드카드 여럿과 매개변수(두 번째 와일드카드가 경로 끝이 아닐 때) | 8.4.0 |
공격 조건은 개발자가 위험한 모양의 라우트를 정의해 두었는가입니다. 그런 라우트가 있으면 공격자는 URL만 조작해 보내면 됩니다. 주의할 점은 Express 버전을 올려도 path-to-regexp가 그대로일 수 있다는 것입니다. Express 5는 router를 거쳐 path-to-regexp ^8.0.0을 쓰므로, 설치한 정확한 버전을 기록하는 lockfile(package-lock.json 등)에 8.3.0 이하가 고정되어 있으면 Express를 다시 설치해도 바뀌지 않습니다. npm ls path-to-regexp로 실제 설치된 버전을 확인하고 npm update path-to-regexp로 올려야 합니다. Express 4는 4.22.3부터 수정된 0.1.13 계열을 씁니다. 2026년 3월 30일 Express 보안 공지에 세 CVE가 정리되어 있고, 안전한 라우트 예시는 path-to-regexp의 각 보안 권고에 있습니다.
파일 업로드 미들웨어 Multer
Express에서 파일 업로드를 처리할 때 널리 쓰는 Multer도 2026년에 서비스 거부 결함이 여러 번 나왔습니다. 2월과 3월에 공개된 세 건은 업로드 도중 연결을 끊거나 형식이 잘못된 요청을 보내면 자원이 정리되지 않고 쌓이거나(CVE-2026-2359, CVE-2026-3304, 2.1.0에서 수정), 재귀가 끝없이 이어져 스택이 넘치는(CVE-2026-3520, 2.1.1에서 수정) 문제였습니다. 6월, 8월, 9월, 10월에도 필드 이름, 파일 디스크립터, 중단된 업로드의 잔여 파일, 비동기 fileFilter와 관련된 결함이 이어졌습니다. 대부분의 공지에는 임시 대책이 없고, 일부만 limits.fields 축소나 동기 fileFilter 같은 부분 대책을 안내합니다. 2026년 11월 기준 최신 버전은 2.5.0이므로, Multer를 쓴다면 최신 버전으로 올리고 limits.fieldNestingDepth도 설정해야 합니다(기본값은 무제한).
React Server Components와 Next.js
앞의 프레임워크 부분에서 다룬 RSC 서비스 거부 결함(CVE-2026-23869, CVE-2026-23870)도 같은 종류입니다. 조작된 Server Function 요청 하나가 CPU를 최대 1분 동안 쓰거나 메모리를 소진시킬 수 있었습니다. 5월 Next.js 보안 릴리스에는 Cache Components를 쓰는 앱에서 Next-Resume 헤더로 연결이 멈추는 결함(CVE-2026-44579)과, 기본 이미지 로더로 직접 운영하는 서버에서 /_next/image가 큰 로컬 파일을 통째로 메모리에 올리는 결함(CVE-2026-44577)도 들어 있었습니다. 이미지 최적화 기능을 로컬 파일에 쓰지 않는다면 images.localPatterns: []로 닫아 둘 수 있습니다.
PHP: 프록시를 거친 HTTPS 요청 실패가 FPM 전체를 멈출 때
PHP 쪽에서는 CVE-2026-12184가 같은 계열입니다. PHP가 스트림 컨텍스트에 프록시를 설정한 채 file_get_contents('https://…')처럼 외부 HTTPS 주소에서 데이터를 가져오다가 TLS 연결 설정에 실패하면(인증서 만료, 이름 불일치 등), 이미 닫은 연결을 다시 건드려 프로세스가 죽었습니다. 보안 공지에 따르면 PHP-FPM에서는 이 충돌로 FPM 프로세스 전체가 모든 워커와 함께 내려갈 수 있습니다. 문제의 코드는 프록시와 TLS를 함께 쓰는 분기 안에 있고, PHP 변경 이력도 프록시를 설정한 경우로 적고 있습니다.
공격자가 이 결함을 건드리려면 프록시를 거치는 서버가 공격자가 정한 주소로 요청을 보내게 만들어야 합니다. 사용자가 입력한 URL의 미리보기를 만들거나, 웹훅 주소를 등록받거나, 외부 이미지를 가져오는 기능이 그런 경로입니다. 수정은 8.3.32, 8.4.21, 8.5.6에 들어갔습니다. 수정 커밋은 4월 3일에 공개 브랜치에 들어갔고, 8.4.21과 8.5.6은 5월 7일에, 8.3.32는 보안 공지와 같은 7월 2일에 나왔으므로, 공지보다 두 달 이상 먼저 수정이 공개되었습니다. 10월에 PHP2Shell 대응으로 최신 버전에 올렸다면 이 결함도 함께 해결됩니다.
서비스 거부를 줄이는 방법
- 위 라이브러리와 런타임을 최신 버전으로 올리고, lockfile에 남은 하위 의존성 버전까지 확인해야 합니다.
- 정규식에는 반복 안의 반복(
(a+)+,(.*)*)을 쓰지 않아야 합니다. ESLint의 eslint-plugin-regexp에는 이런 패턴을 찾는 규칙(regexp/no-super-linear-backtracking)이 있습니다. 사용자 입력에 정규식을 적용하기 전에 길이를 먼저 제한하면 최악의 경우도 짧아집니다. - 요청 본문 크기, 헤더 크기, 요청을 받는 시간에 상한을 둬야 합니다. Nginx 같은 리버스 프록시의
client_max_body_size와 시간 제한, Node.jshttp서버의maxHeaderSize,requestTimeout,headersTimeout이 그 역할을 합니다. 이 값들은 이미 CPU를 쓰고 있는 코드를 멈추지 못하므로, 처리 시간은 입력 길이 제한과 격리로 다뤄야 합니다. - 서버가 외부 URL로 요청을 보내는 기능은 허용 목록, 짧은 시간 제한, 별도 작업 큐로 격리해야 합니다. 이 격리는 서비스 거부와 함께 내부망 접근(SSRF)도 줄여 줍니다.
- 프로세스를 여러 개 띄우고 헬스 체크로 멈춘 프로세스를 교체해야 합니다. 한 프로세스가 멈춰도 서비스 전체가 멈추지 않게 하는 마지막 안전장치입니다.
- Node.js는
perf_hooks.monitorEventLoopDelay()로 이벤트 루프 지연을 측정할 수 있습니다. 지연이 갑자기 커지면 CPU를 붙잡는 요청이 들어왔다는 신호일 수 있습니다.
공급망: 설치한 패키지가 공격이 될 때
소프트웨어 공급망(software supply chain) 은 서비스에 들어가는 외부 코드가 만들어지고, 저장소에 올라가고, 설치되는 전체 과정입니다. package.json에 적은 패키지가 열 개여도, 그 패키지들이 다시 의존하는 간접 의존성(transitive dependency) 까지 합치면 실제로 설치되는 패키지는 수백 개가 됩니다. 공급망 공격은 이 중 하나를 악성 버전으로 바꿔, 그 패키지를 설치하는 모든 개발자 PC와 빌드 서버에서 공격자의 코드가 실행되게 만듭니다. 앞의 결함들은 패치를 내면 끝나지만, 공급망 공격은 개발자가 평소처럼 npm install을 실행하는 순간이 곧 공격이 됩니다.
Axios: 관리자 한 명의 PC에서 시작된 3시간
Axios는 자바스크립트에서 가장 널리 쓰이는 HTTP 클라이언트 중 하나입니다. 2026년 3월 31일 이 패키지의 악성 버전 두 개(1.14.1, 0.30.4)가 npm에 올라왔습니다.
시작은 관리자 개인을 노린 사회공학이었습니다. 관리자의 사후 보고서와 보도에 따르면, 공격자는 실제 회사의 브랜드와 창업자 신분을 흉내 내 관리자를 그럴듯한 Slack 워크스페이스에 초대했습니다. 그곳에는 미리 꾸며 둔 채널과 가짜 직원 프로필이 있었습니다. 이어서 여러 명이 참석한 것처럼 보이는 Microsoft Teams 회의를 열었고, 회의 중에 “시스템의 무언가가 오래되었다”는 가짜 오류를 띄워 업데이트를 설치하게 했습니다. 그 업데이트가 원격 조종 프로그램이었습니다. 2단계 인증은 켜져 있었지만 PC가 장악된 뒤에는 막지 못했습니다. 보도는 공격자가 로그인된 세션을 가져간 것으로, StepSecurity는 장기 토큰을 얻은 것으로 보는데, 정확한 경로는 확정되지 않았습니다.
공격자는 그 계정으로 악성 버전을 올렸습니다. 직전 1.x 버전들(1.13.4~1.14.0)은 GitHub Actions에서 신뢰할 수 있는 배포 방식으로 올라왔지만, 1.14.1에는 그런 배포 기록도, 대응하는 커밋이나 태그도 없었습니다. 공격자는 계정의 이메일을 바꾸고, 침해를 알리는 이슈 글을 그 계정으로 지우기도 했습니다.
악성 코드는 Axios 자체가 아니라 새로 추가된 의존성 plain-crypto-js에 있었습니다. 공격자는 이 패키지를 먼저 정상 코드로 한 번 올려 이력을 만들고, 18시간 뒤 악성 설치 스크립트를 넣은 버전을 올렸습니다. 설치 스크립트는 운영체제별로 원격 조종 프로그램을 내려받아 실행한 뒤 자기 자신을 지우고 package.json을 정상 버전 정보로 바꿔 놓았습니다. 그래서 npm list에는 4.2.1이 아니라 4.2.0으로 보이므로 버전 번호로 판단하면 안 되고, node_modules/plain-crypto-js 폴더가 있는지와 lockfile에 남은 버전으로 확인해야 합니다.
악성 버전은 한국 시간으로 오전 9시 21분부터 낮 12시 15분까지 약 3시간 동안 설치할 수 있었습니다. 한국에서는 업무 시간이 막 시작된 때였습니다. 사후 보고서에 따르면 침해를 먼저 알아챈 것은 프로젝트 쪽 자동 알림이 아니라 커뮤니티였습니다. StepSecurity의 CI 감시 도구는 Backstage 프로젝트의 빌드에서 공격자 서버로 나가는 낯선 외부 연결을 잡아냈습니다. StepSecurity가 따로 재현한 실행에서는 npm install을 시작하고 약 2초 뒤에 첫 연결이 나갔습니다. Google 위협 인텔리전스 그룹(GTIG)은 이 공격을 북한 연계 그룹 UNC1069의 소행으로 분석했습니다. 미국 CISA는 4월 20일 경보를 내고 .npmrc에 ignore-scripts=true와 min-release-age=7을 설정하라고 권고했습니다.
감염된 버전을 설치한 적이 있다면 다음과 같이 대응해야 합니다.
- lockfile에서 axios 1.14.1이나 0.30.4,
plain-crypto-js를 찾고, 1.14.0이나 0.30.3으로 고정해야 합니다. - 설치한 PC나 CI 러너는 이미 침해된 것으로 보고, 그 환경에 있던 모든 토큰, SSH 키, 클라우드 키, CI 비밀값을 교체해야 합니다. 원격 조종 프로그램이 이미 실행되었다면 패키지를 지워도 공격자의 접근은 남아 있습니다.
- npm, yarn, pnpm의 캐시도 지워야 합니다. 캐시에 악성 버전이 남아 있으면 다시 설치될 수 있습니다.
node-ipc: 불러올 때 실행되는 코드
한 달 반 뒤인 5월 14일에는 node-ipc의 악성 버전 세 개(12.0.1, 9.2.3, 9.1.6)가 1분 사이에 올라왔습니다. node-ipc는 프로세스 사이의 통신을 돕는 패키지로, 2022년에도 관리자가 직접 특정 국가 사용자의 파일을 덮어쓰는 코드를 넣어 논란이 된 적이 있습니다.
이번에 배포한 계정은 2022년 이후 활동이 없던 공동 관리자 계정이었습니다. 분석 업체들에 따르면 이 계정에 등록된 이메일의 도메인은 2025년 1월에 만료되었고, 공격 일주일 전인 2026년 5월 7일에 다시 등록되었습니다. 공격자가 도메인을 사들여 메일을 받을 수 있게 만든 뒤 비밀번호 재설정으로 계정을 가져갔다는 가설이 유력하지만, 확정된 사실은 아닙니다.
이 공격에는 설치 스크립트가 없었습니다. 악성 코드는 node-ipc.cjs 파일 끝에 붙어 있다가, 앱이 require('node-ipc')로 패키지를 불러오는 순간 실행되었습니다. 그래서 --ignore-scripts로는 막을 수 없었습니다. 악성 코드는 클라우드 자격증명, SSH 키, npm·GitHub 토큰, .env 파일, 셸 기록, 운영체제의 키체인과 함께 AI 코딩 도구의 설정 파일(~/.claude.json, MCP 설정 파일)까지 수집했습니다. 수집한 파일은 압축한 뒤 DNS 조회에 조각조각 실어 밖으로 보냈습니다. 대부분의 네트워크가 웹 접속은 막아도 DNS 조회는 열어 두기 때문에, DNS는 탐지를 피해 데이터를 빼내는 경로로 자주 쓰입니다. 이 악성 코드는 조직의 DNS 서버를 거치지 않고 공격자 서버의 443 포트로 직접 DNS 조회를 보냈습니다.
Socket의 자동 분석은 악성 버전이 올라오고 약 3분 만에 이를 잡아냈습니다. StepSecurity와 SafeDep은 깨끗한 버전으로 12.0.0, 9.2.1, 9.1.5를 제시했습니다. 9.2.3 바로 앞의 9.2.2는 2022년 권고 대상이므로 쓰면 안 됩니다. 대응은 Axios와 같습니다. lockfile을 안전한 버전으로 다시 만들고, 설치한 환경의 비밀값을 모두 교체하고, bt.node.js로 끝나는 DNS 조회와 sh.azurestaticprovider.net, 37.16.75.69로 나간 연결 기록을 함께 확인해야 합니다. 페이로드가 사내 DNS 서버를 거치지 않으므로 사내 DNS 로그만 봐서는 찾지 못할 수 있습니다.
Shai-Hulud 웜: 훔친 토큰으로 스스로 퍼지는 악성코드
웜(worm) 은 사람의 개입 없이 스스로 복제해 퍼지는 악성코드입니다. 2025년 9월 처음 나타난 Shai-Hulud는 npm 생태계에서 동작하는 웜이었습니다. 감염된 패키지를 설치하면 그 환경의 npm 토큰과 GitHub 토큰을 훔치고, 그 토큰으로 피해자가 관리하는 다른 패키지에 악성 버전을 올렸습니다. 그 패키지를 설치한 다른 개발자의 토큰으로 다시 같은 일이 반복되었습니다.
웜은 버전을 거듭하며 진화했습니다.
| 시기 | 이름 | 규모와 특징 |
|---|---|---|
| 2025년 9월 | Shai-Hulud | 500개 이상 패키지(CISA). 훔친 비밀값을 공개 GitHub 저장소에 올림 |
| 2025년 11월 | Shai-Hulud 2.0 | 796개 패키지, 1,092개 버전(Datadog). Node.js 감시를 피하려는 것으로 보이는 Bun 실행. 데이터를 빼돌리지도 퍼지지도 못하면 홈 폴더 삭제를 시도함 |
| 2026년 4월 ~ 5월 | Mini Shai-Hulud | SAP의 @cap-js(4월 29일), TanStack 42개 패키지 84개 버전(5월 11일), @antv 관리자의 323개 패키지(5월 19일, Socket 집계) |
| 2026년 5월 | 소스 코드 공개 | 웜의 소스가 해킹 포럼에 공개되어 누구나 변형을 만들 수 있게 됨 |
| 2026년 6월 ~ 7월 | 비슷한 수법의 후속 공격 | Red Hat 패키지(“Miasma”, 6월 1일), binding.gyp로 설치 스크립트 없이 빌드를 실행시킨 공격(6월 3일), AsyncAPI(7월 14일) |
2026년의 Mini Shai-Hulud에서 주목할 변화가 두 가지 있습니다.
첫째, 정상적인 CI 배포 경로를 그대로 이용했습니다. TanStack 공격자는 GitHub Actions의 pull_request_target 워크플로를 악용했습니다. 이 이벤트는 외부 기여자가 보낸 풀 리퀘스트에도 저장소의 권한으로 워크플로를 실행하기 때문에, 풀 리퀘스트의 코드를 받아 실행하는 워크플로가 있으면 공격자의 코드가 저장소 권한으로 실행됩니다. 공격자는 이를 이용해 빌드 캐시를 오염시키고, 배포 워크플로가 실행될 때 러너의 메모리에서 배포용 신원 토큰을 꺼냈습니다. 그 결과 악성 패키지는 정상 CI에서 배포되었다는 서명된 기록(provenance)까지 갖추고 있었습니다. 배포 기록이 있다고 해서 안전하다고 볼 수 없게 되었습니다.
둘째, 개발 도구의 설정 파일에 숨었습니다. SAP 패키지를 노린 변형은 .claude/settings.json에 세션 시작 훅을, .vscode/tasks.json에 작업을 심어 두었습니다. 감염된 저장소를 AI 코딩 도구나 에디터로 열 때마다 악성 코드가 다시 실행되도록 만들었습니다.
PHP의 Composer와 Packagist도 같은 흐름에 휩쓸렸습니다. 4월 30일에는 intercom/intercom-php의 기존 Git 태그가 새 커밋을 가리키도록 바뀌었고, 패키지 유형을 Composer 플러그인으로 바꿔 설치 직후 악성 코드를 실행했습니다. 다른 공격이지만 같은 약점(태그 다시 쓰기)을 노린 사례로, 5월 22일과 23일에는 유출된 GitHub 토큰으로 laravel-lang의 과거 태그들이 다시 쓰여 약 700개 버전이 오염되었습니다. 이 경우 악성 코드는 Composer의 autoload.files에 들어 있어 설치 스크립트 없이 앱이 요청을 처리할 때 자동으로 실행되었고(같은 호스트에서는 표식 파일로 한 번만), 플러그인이 아니라 autoload이므로 Composer의 플러그인 차단 설정(allow-plugins) 대상도 아니었습니다. PHP판 node-ipc라고 할 수 있습니다.
PackageGate: 차단 장치 자체의 틈
Shai-Hulud 이후 많은 팀이 설치 스크립트 차단을 기본 방어로 삼았습니다. 2026년 1월 Koi Security는 PackageGate라는 이름으로 npm, pnpm, vlt, Bun에서 설치 스크립트 차단과 lockfile 무결성을 우회하는 결함 여섯 건을 공개했습니다.
- npm: Git 저장소에서 받는 의존성이
.npmrc로git실행 파일의 경로를 바꿔,--ignore-scripts를 켜도 공격자의 코드가 실행되었습니다. npm은 처음에 “의도된 동작”이라고 답했지만, 2026년 2월 Git 의존성을 제한하는allow-git설정을 추가했고(릴리스 노트 기준 11.9.0, GitHub 공지 기준 11.10.0 이상), npm 12에서는 이를 기본으로 막았습니다. - pnpm: Git 의존성의
prepare스크립트가 기본 차단을 무시하고 실행되었고(CVE-2025-69264), HTTP나 Git으로 받는 의존성은 lockfile에 무결성 해시가 기록되지 않아 같은 버전이라도 매번 다른 내용을 받을 수 있었습니다(CVE-2025-69263). 둘 다 pnpm 10.26.0에서 고쳐졌습니다. - Bun: 기본으로 설치 스크립트를 허용하는 신뢰 패키지 목록을, 같은 이름의 Git이나 파일 의존성으로 흉내 낼 수 있었습니다(CVE-2026-24910, Bun 1.3.5에서 수정).
PackageGate가 보여준 것은 설치 스크립트 차단이 한 레이어일 뿐이라는 사실입니다. 그 레이어에도 구멍이 있고, node-ipc나 laravel-lang처럼 애초에 그 레이어를 지나가지 않는 공격도 있습니다.
공급망 공격을 막는 설정
2026년 한 해 동안 패키지 관리자들은 기본 설정을 크게 바꿨습니다. 각 방어 수단이 위 사례 중 무엇을 막는지 정리하면 다음과 같습니다.
| 방어 수단 | 무엇을 막는가 | 막지 못하는 것 |
|---|---|---|
| 설치 스크립트 차단 | Axios, Shai-Hulud 계열처럼 설치 순간 실행되는 공격 | node-ipc, laravel-lang처럼 불러올 때 실행되는 공격, PackageGate 같은 우회 |
| 버전 쿨다운 | 공개 후 며칠 안에 발견되어 삭제되는 악성 버전 대부분 | 오래 숨어 있는 악성 코드. 긴급 보안 패치도 함께 늦어짐 |
lockfile 고정과 npm ci | 공격 기간에 의존성을 새로 풀지 않은 환경 | lockfile을 새로 만든 환경, 이미 오염된 lockfile |
| Git·원격 의존성 차단 | PackageGate처럼 저장소 밖에서 받는 의존성을 이용한 공격 | 저장소에 정상적으로 올라온 악성 버전 |
| 배포 신뢰 하락 거부 | 이전 버전보다 배포 기록이 약해진 버전. Axios 1.14.1이 이 경우였음 | TanStack처럼 정상 CI를 장악해 올린 버전 |
버전 쿨다운(cooldown) 은 새로 공개된 버전을 일정 기간이 지나야 설치하도록 하는 설정입니다. Axios는 3시간, TanStack은 몇 시간 만에 악성 버전이 지워졌기 때문에, 하루만 기다리도록 설정했어도 두 공격을 피할 수 있었습니다. 다만 같은 이유로 긴급 보안 패치도 늦게 받게 되므로, 보안 업데이트는 예외로 두고 바로 받도록 운영해야 합니다.
패키지 관리자별 설정은 다음과 같습니다.
| 도구 | 설치 스크립트 | 쿨다운 | 그 밖의 설정 |
|---|---|---|---|
| npm 12 (2026년 7월) | 기본 차단. 허용할 패키지는 package.json의 allowScripts에 명시 | min-release-age (일 단위, 11.10.0부터) | allow-git, allow-remote 기본 차단 |
| npm 11 | ignore-scripts=true로 차단 | min-release-age | allow-git=none (2026년 2월부터) |
| pnpm 11 (2026년 4월) | 기본 차단. 허용할 패키지는 allowBuilds에 명시 | minimumReleaseAge (분 단위, 기본 1440분) | trustPolicy: no-downgrade (10.21부터), blockExoticSubdeps 기본 켜짐 |
| Yarn 4.10 이상 | enableScripts: false (4.14부터 기본 차단) | npmMinimalAgeGate (4.10은 분 단위 숫자, 4.11부터 "7d" 같은 기간 표기, 4.15부터 기본 1d) | npmPreapprovedPackages로 예외 지정 |
| Bun 1.3 이상 | 기본 허용 목록과 trustedDependencies에 없는 패키지는 차단(trustedDependencies를 쓰면 기본 목록을 대체) | bunfig.toml의 minimumReleaseAge (초 단위) | 설치 시 보안 스캐너 연동 |
| Composer 2.10 이상 | allow-plugins에 없는 플러그인은 차단 (2.2부터) | config.policy.cooldown (2.11부터, 선택) | 알려진 악성 패키지 기본 차단 (2.10부터) |
의존성 자동 업데이트 도구에도 같은 기능이 있습니다. Dependabot은 2026년 7월부터 설정이 없어도 버전 업데이트를 기본 3일 기다렸다가 제안하고, cooldown으로 기간을 조정할 수 있습니다. 보안 업데이트에는 이 대기를 적용하지 않습니다. Renovate에는 minimumReleaseAge가 있습니다. GitHub는 2026년 3월부터 npm 의존성에 대한 악성 패키지 알림을 선택 기능으로 제공했고, 7월 말에는 Composer를 포함한 8개 생태계로 넓혔습니다.
패키지를 직접 배포하는 쪽이라면 배포 경로를 지켜야 합니다.
- npm은 Shai-Hulud 이후 쓰기 권한 토큰의 기본 유효 기간을 7일, 최대 90일로 줄였고, 2025년 12월에는 오래된 방식의 토큰(classic token)을 모두 폐기했습니다. 장기 토큰 대신 신뢰할 수 있는 배포(trusted publishing) 를 써야 합니다. CI가 배포할 때마다 짧게 유효한 신원 증명을 받아 npm에 제출하는 방식이라, 훔쳐 갈 장기 토큰이 남지 않습니다.
- 신뢰할 수 있는 배포를 설정할 때는 배포를 허용하는 워크플로 파일을 지정하고, GitHub Environment를 함께 걸어 배포 브랜치와 승인자를 제한해야 합니다. SAP @cap-js 사례에서는 배포를 허용한 워크플로에 브랜치 제한과 승인 단계가 없어, 공격자가 탈취한 개발자 계정으로 다른 브랜치에서 릴리스 워크플로를 고쳐 토큰을 받아냈습니다.
pull_request_target워크플로에서 풀 리퀘스트의 코드를 받아 실행하지 않아야 합니다.- 2026년 5월부터 npm은 배포를 사람이 2단계 인증으로 승인해야 공개되는 단계적 배포(staged publishing)를 지원합니다. 직접 배포를 끄고 단계적 배포만 허용해 두면, 자동화된 배포가 탈취되어도 마지막 승인에서 멈출 수 있습니다.
- 더는 활동하지 않는 공동 관리자 계정은 권한을 회수해야 합니다. 관리자 계정에 등록한 이메일의 도메인이 만료되지 않았는지도 확인해야 합니다.
개별 OWASP 항목과 공급망 관리의 큰 그림은 코드 밖의 리스크 - OWASP Top 10:2025 ep.04에서 다뤘습니다.
작업 환경: 개발자의 PC와 일하는 공간
공격자에게 개발자는 서버보다 효율적인 목표입니다. 개발자 PC에는 여러 프로젝트의 .env 파일, 저장소에 접근하는 SSH 키, 클라우드 자격증명, 패키지 배포 토큰, 로그인된 브라우저 세션이 한곳에 모여 있습니다. CI 빌드 서버에는 운영 환경에 배포하는 권한이 있습니다. Axios 사례에서 공격자는 서버를 하나도 건드리지 않았습니다. 관리자 한 명의 PC를 탈취한 것만으로도 수많은 서비스의 빌드에 악성 코드를 넣을 수 있었습니다.
개발자 PC와 CI에 모인 비밀값
node-ipc 악성 버전이 수집한 파일 목록은 개발자 PC에 무엇이 있는지를 그대로 보여줍니다. ~/.ssh, ~/.aws/credentials, ~/.npmrc의 배포 토큰, 셸 기록, 프로젝트마다 흩어진 .env, AI 코딩 도구의 설정 파일이 모두 대상이었습니다. 이 파일들은 대부분 평문이라, 코드 한 줄로 읽어 갈 수 있습니다.
- 비밀값은 평문 파일보다 운영체제의 키체인, 비밀번호 관리자, 클라우드의 비밀값 관리 서비스에 두는 편이 안전합니다.
.env를 비밀값 관리 서비스로 옮기는 과정은 .env에서 Secret Manager로에서 다뤘습니다. - 오래 유효한 키보다 짧게 유효한 자격증명을 써야 합니다. 클라우드는 SSO 로그인으로 몇 시간짜리 자격증명을 받고, GitHub 토큰은 만료일과 접근 범위를 정한 세분화된 토큰(fine-grained token)으로 만들어야 합니다.
- 개발용과 운영용 자격증명을 분리해야 합니다. 개발자 PC에 운영 DB 비밀번호가 없으면, PC가 털려도 운영 데이터까지 바로 이어지지 않습니다.
- GitHub Actions 워크플로에는
permissions:로 필요한 권한만 주고, 외부 액션은 태그가 아니라 커밋 해시로 고정해야 합니다. 2025년 3월 tj-actions/changed-files 사고에서는 공격자가 기존 태그를 악성 커밋으로 옮겨, 그 액션을 쓰던 저장소들의 비밀값이 빌드 로그에 찍혔습니다.
공격자가 개발자에게 접근하는 방식도 정교해졌습니다. Axios 관리자는 실제 회사를 흉내 낸 Slack과 Teams 회의에 속았습니다. 사회공학(social engineering) 은 기술적 결함 대신 사람의 신뢰와 습관을 이용해 정보를 빼내거나 행동을 유도하는 공격입니다. 채용 제안, 협업 제안, 기술 지원 요청처럼 개발자가 평소 받는 연락의 모양을 하고 옵니다. 회의나 대화 도중에 “업데이트가 필요하다”, “이 명령을 실행해 보라”는 요청이 나오면 그 자리에서 따르지 말고, 공식 사이트나 원래 알던 연락처로 따로 확인해야 합니다.
개발 서버와 배포 산출물
개발 서버는 내 PC에서만 쓴다는 전제로 만들어졌습니다. 그래서 소스 코드와 설정을 그대로 내보내고, 인증도 없습니다. 2026년 10월 공개된 Nuxt CVE-2026-119199가 이 전제가 깨질 때의 문제를 보여줍니다. 기본 서버 엔진인 Nitro 2에서 nuxt dev를 실행하면 Nuxt는 개발용 서버 번들(.nuxt/dev/index.mjs)을 만드는데, 이 파일에는 runtimeConfig의 비공개 값이 그대로 들어 있습니다. Vite 개발 서버는 .env는 막지만 이 파일은 막지 않아서, /_nuxt/@fs/ 경로로 누구나 내려받을 수 있었습니다.
그래서 개발 서버가 네트워크에 열려 있으면 위험한 것입니다. 기본 설정은 내 PC(localhost)에서만 접속되지만, 휴대폰으로 화면을 확인하려고 --host를 붙이거나, 컨테이너 포트를 열거나, 시연을 위해 터널링 서비스로 공개하면 같은 네트워크나 인터넷의 누구나 접근할 수 있습니다. 공용 Wi-Fi나 외부 현장의 네트워크라면 더 위험합니다. Nuxt 4.6.3에서 고쳐졌고 지원이 끝난 Nuxt 3에는 패치가 없습니다. 상위 폴더에 잠금 파일이 있을 때 같은 경로로 파일이 노출되는 문제도 4.6.4에서 고쳐졌으므로 4.6.4 이상을 쓰는 것이 좋습니다. nuxt.config에는 키만 빈 값으로 선언하고 실제 값은 NUXT_로 시작하는 환경 변수로 넣으면 이 번들에 들어가지 않습니다. Vite 자체에도 2025년에 개발 서버의 파일 접근 제한을 우회하는 결함이 여러 번 나왔습니다. 개발 서버를 남에게 보여줘야 한다면 빌드한 결과물을 미리보기 환경에 배포하는 편이 안전합니다.
배포 산출물에 개발용 파일이 섞여 들어가는 문제는 PHP에서 특히 오래 이어졌습니다. 테스트 도구 PHPUnit의 오래된 버전에는 eval-stdin.php라는 파일이 있는데, 이 파일은 HTTP 요청 본문을 그대로 PHP 코드로 실행합니다(CVE-2017-9841). 2017년에 공개된 결함이고 패치 버전은 그 전인 2016년 11월에 나왔지만, VulnCheck는 2026년 5월 11일까지 30일 동안 이 파일을 노린 공격 시도를 80,119건 기록했습니다. 공격이 계속 통하는 이유는 개발용 의존성을 운영 서버에 함께 배포하고, vendor/ 폴더가 웹에서 보이도록 서버를 설정하기 때문입니다.
- 웹 서버의 문서 루트는 프로젝트 폴더가 아니라
public/을 가리켜야 합니다. Laravel 공식 배포 문서도 프로젝트 루트에서 서비스하면 민감한 설정이 노출된다고 경고합니다. - 운영용 빌드는
composer install --no-dev,npm ci --omit=dev처럼 개발용 의존성을 빼고 만들어야 합니다. .env,.git/,vendor/, 백업 파일(*.bak,*.zip)은 웹 서버 설정에서 접근을 막아야 합니다..env를 찾아다니며 클라우드 키를 수집하는 봇(Androxgh0st 등)에 대해서는 미국 CISA와 FBI가 2024년 합동 경보를 냈습니다.- 웹 서버 로그에서
eval-stdin.php로 들어온 POST 요청을 찾아보고, 성공 응답(2xx)이 있다면 침해 대응을 시작해야 합니다.
화면, 종이, 기기: 일하는 공간의 보안
작업 환경의 보안은 컴퓨터 안에서 끝나지 않습니다. 정보보호 관리체계의 국제 표준인 ISO/IEC 27001:2022는 부속서에 기술 통제와 함께 물리 통제와 사람 통제를 두고 있습니다. 개발자가 일상에서 지킬 수 있는 항목을 공개된 표준과 공공기관 지침에서 골라 정리했습니다.
화면과 책상: 자리를 비울 때는 화면을 잠가야 합니다(Windows는 Win+L, macOS는 Ctrl+Cmd+Q). 짧은 시간이 지나면 자동으로 잠기도록 설정하고, 잠금 화면이 작업 내용을 가리게 해야 합니다. 화면 공유나 발표 전에는 메신저와 메일 알림을 꺼야 합니다. 시연 도중 뜬 미리보기 알림 하나로 고객 이름이나 내부 일정이 드러날 수 있습니다. 출력물은 바로 회수하고, 회의가 끝나면 화이트보드를 지워야 합니다. 공용 공간에서는 화면 보호 필름을 쓰고 벽을 등지고 앉는 것이 좋습니다. 남의 화면이나 키 입력을 어깨 너머로 훔쳐보는 숄더 서핑(shoulder surfing) 은 MITRE의 공격 패턴 목록(CAPEC-508)에 올라 있는 실제 공격 기법입니다.
폐기: 고객 문서나 출력물, 메모지는 일반 쓰레기통에 버리지 않고 세단기로 파쇄해야 합니다. 버린 자료를 뒤져 공격에 쓸 정보를 모으는 것도 공격 패턴 목록(CAPEC-406)에 있습니다. PC, 테스트용 휴대폰, SSD, USB를 다시 쓰거나 반납하거나 버리기 전에는 파일 삭제나 빠른 포맷이 아니라 복구할 수 없는 방식으로 지워야 합니다. 미국 NIST는 2025년 9월 저장매체 삭제 지침 SP 800-88 개정 2판을 냈고, 국내 「개인정보의 안전성 확보조치 기준」도 개인정보를 파기할 때 완전파괴, 전용 소자 장비, 초기화나 덮어쓰기 중 하나를 쓰도록 정하고 있습니다.
사진과 메신저: 고객사의 화면, 문서, 화이트보드를 허락 없이 촬영하거나 캡처하지 않아야 하고, 업무 자료를 개인 메신저나 개인 클라우드로 보내지 않아야 합니다. ISO/IEC 27001:2022에 새로 들어간 데이터 유출 방지(Data Leakage Prevention, DLP) 통제의 해설은 메일, USB, 외부 업로드와 함께 스마트폰 촬영을 유출 경로로 꼽습니다. 국내 「개인정보의 안전성 확보조치 기준」은 화면에 표시하는 것도 개인정보 출력으로 보고, 목적에 필요한 최소한의 항목만 보이도록 하라고 정하고 있습니다. 공유가 꼭 필요하면 승인된 채널로만 보내고, 필요한 부분만 잘라 개인정보와 비밀값을 가려야 합니다.
기기: 업무용 노트북과 테스트 기기는 목록에 등록하고, 디스크 전체 암호화(Windows BitLocker, macOS FileVault)를 켜고, 분실하면 원격으로 지울 수 있게 해야 합니다. 이런 관리를 한 번에 하는 도구가 모바일 기기 관리(Mobile Device Management, MDM) 입니다. 영국 국가사이버보안센터(NCSC)는 휴대폰과 태블릿이 사무실 밖으로 나가는 만큼 잃어버리거나 도난당할 가능성이 크다고 짚습니다. 기기를 잃어버리면 바로 신고해야 원격 삭제가 의미가 있습니다. 개인 노트북, 개인 핫스팟, 개인 USB를 고객사의 네트워크에 연결할 때는 사전 승인을 받아야 하고, 평소에 쓰는 계정에는 관리자 권한을 주지 않는 것이 좋습니다.
출입: 출입 카드를 찍은 사람 뒤에 붙어 함께 들어가는 수법을 테일게이팅(tailgating) 이라고 합니다. 문을 잡아 주는 예의를 이용하기 때문에 가장 단순한 사회공학 수법 중 하나로 꼽힙니다. 모르는 사람을 위해 보안 출입문을 잡아 주지 않아야 하고, 출입증이 없는 방문자는 안내 데스크로 정중하게 안내해야 합니다. 고객 자료를 둔 서랍과 캐비닛은 잠그고, 마지막으로 나가는 사람은 문을 잠가야 합니다.
퇴근 후의 PC와 전원: PC를 켜 둘지 끌지는 양쪽에 이유가 있습니다. Windows는 업데이트를 설치한 뒤 사용 시간(기본 오전 8시~오후 5시) 밖에 자동으로 재시작하므로, 항상 꺼 두는 PC는 보안 업데이트가 늦어질 수 있습니다. 반대로 로그인된 채 켜 둔 PC는 밤새 노출됩니다. 이 문제를 정해 주는 공식 기준은 찾지 못했습니다. 현실적인 선택은 켜 둘 때 반드시 잠그거나 로그아웃하고, 끌 때는 낮 시간에 업데이트를 챙기는 것입니다. 전열기와 충전기, 쓰지 않는 멀티탭은 퇴근할 때 전원을 끄고, 멀티탭에 멀티탭을 이어 쓰지 않아야 합니다. 대구 달서소방서장의 기고에 따르면 소방청 통계로 최근 5년간(집계 기간은 명시되지 않음) 겨울철 화재 54,335건 중 24.4%가 전기적 요인이었습니다. 항상 켜 두는 서버나 NAS는 정전 때 안전하게 종료할 수 있도록 무정전 전원 장치(UPS)에 연결해야 합니다.
외부 근무: 공용 Wi-Fi보다 회사나 개인 핫스팟을 쓰고, 공용 Wi-Fi를 써야 하면 회사 VPN을 켜야 합니다. 미국 국가안보국(NSA)은 공공장소 무선 기기 보안 지침에서 HTTPS 사이트만 쓰고, Wi-Fi 자동 연결과 쓰지 않는 블루투스·NFC를 끄라고 권고합니다. 진짜 핫스팟과 이름이 같은 가짜 핫스팟도 조심해야 합니다. 엘리베이터, 식당, 택시, 공공장소의 통화에서 고객 이름, 프로젝트 내용, 일정을 말하지 않아야 합니다. 공격자는 이렇게 흘러나온 정보를 모아 표적 공격을 준비합니다.
피싱과 랜섬웨어, 첫 대응
피싱(phishing) 은 믿을 만한 상대인 척 메시지를 보내 링크를 누르거나, 파일을 열거나, 정보를 입력하게 만드는 공격입니다. 예상하지 못한 요청이 오면 메시지 안의 링크나 번호가 아니라, 원래 알던 연락처나 직접 입력한 주소로 확인해야 합니다. 첨부 문서의 매크로는 켜지 않아야 합니다.
최근 개발자에게 특히 위험한 수법은 클릭픽스(ClickFix) 입니다. 가짜 CAPTCHA나 오류 화면을 띄운 뒤, 문제를 해결하려면 실행 창이나 터미널, PowerShell에 명령을 붙여 넣으라고 안내합니다. 붙여 넣고 실행하는 순간 악성 프로그램이 설치됩니다. Microsoft는 2025년 8월 분석에서, 그해 초 엔드포인트 탐지·대응(EDR) 제품을 켜 둔 환경에서도 매달 수천 대의 기기에서 사용자가 명령을 실행했다고 밝혔고, ESET은 2024년 하반기에서 2025년 상반기 사이에 이 수법이 517% 늘었다고 집계했습니다. macOS용 변형도 있고, 파일 탐색기 주소창을 이용하는 파일픽스(FileFix)도 나왔습니다. 터미널에 명령을 붙여 넣는 일이 익숙한 개발자일수록 경계가 느슨해지기 쉽습니다. 뉴질랜드 국가사이버보안센터의 안내 사이트는 진짜 CAPTCHA가 키보드 명령이나 복사·붙여 넣기를 요구하는 일은 없다고 안내하고, 싱가포르 사이버보안청도 예상하지 못한 실행 창 지시를 클릭픽스의 징후로 꼽습니다.
랜섬웨어(ransomware) 는 파일을 암호화한 뒤 풀어 주는 대가로 돈을 요구하는 악성코드입니다. 감염이 의심될 때의 첫 대응은 KISA와 CISA의 지침을 합치면 다음과 같습니다.
- 네트워크 케이블을 뽑거나 Wi-Fi를 꺼서 네트워크에서 분리하고, 외장 저장장치와 USB도 뽑습니다. 랜섬웨어는 연결된 공유 폴더와 외장 드라이브로 퍼집니다.
- 전원은 끄지 않습니다. 메모리에 남은 증거가 사라지고(CISA), 부팅이 안 될 수도 있기 때문입니다(KISA). 네트워크를 분리할 방법이 없을 때만 전원을 끕니다(CISA).
- 대응 조율은 공격자가 볼 수 없는 경로(전화 등)로 하고(CISA), 바로 신고합니다. 화면의 협박 메시지는 캡처나 사진으로 남기고, 돈은 지불하지 않습니다(KISA).
사무실의 NAS도 자주 노려집니다. 2022년 1월 QNAP NAS를 노린 DeadBolt 랜섬웨어는 인터넷에 노출된 장비 수천 대를 암호화했고, 피해 국가 목록에는 한국도 있었습니다. NAS는 공유기의 포트 포워딩이나 UPnP로 인터넷에 열어 두지 않아야 하고, 펌웨어를 최신으로 유지하고, 관리자 계정에 강한 비밀번호와 2단계 인증을 걸어야 합니다. 네트워크 드라이브로 연결한 NAS는 백업이 아닙니다. 랜섬웨어가 같이 암호화하기 때문입니다. 백업은 평소에 연결을 끊어 두거나 수정할 수 없게 만든 사본으로 두고, 실제로 복원되는지 정기적으로 시험해야 합니다. 업계에서는 사본 세 개를 두 종류의 매체에, 그중 하나는 다른 장소에 두는 3-2-1 규칙을 흔히 씁니다.
빨리 말할 수 있는 분위기
사고 대응에서 가장 비싼 것은 시간입니다. 피싱 링크를 누른 사람이 10분 안에 말하면 계정 하나를 잠그고 끝날 일이, 혼날까 봐 숨기면 며칠 뒤 전사 장애가 됩니다. 영국 NCSC의 보안 문화 원칙은 실수를 숨기지 않을 심리적 안전, 빠르고 쉬운 신고 경로, 책임자를 찾지 않고 배우기 위한 조사를 강조합니다. 같은 기관의 피싱 지침도 모의 훈련의 한계를 지적하면서, 몇 명이 눌렀는지만 재지 말고 몇 명이 신고했는지에 주목하라고 권고합니다. Google의 SRE 문서가 말하는 비난 없는 사후 검토(blameless postmortem) 도 같은 생각입니다. 실수한 사람을 탓하는 대신 실수를 가능하게 한 절차와 도구를 고칩니다.
“눌렀어요”, “잃어버렸어요”를 5초 만에 말할 수 있는 경로를 정해 두고, 신고한 사람에게 고맙다고 말하는 것이 어떤 도구보다 먼저입니다.
생성형 AI를 업무에 쓸 때
AI 도구에 붙여 넣은 내용은 그 서비스의 서버로 갑니다. 국가정보원은 2023년 생성형 AI 보안 가이드라인에서 내부 민감 정보와 개인정보를 입력하지 말라고 권고했고, 2025년 12월에는 에이전트 AI까지 다루는 AI 보안 가이드북으로 개정했습니다. 개인정보보호위원회의 2025년 8월 생성형 AI 개인정보 처리 안내서도 서비스형 LLM을 API로 쓸 때는 라이선스 계약이나 이용약관으로 데이터 처리의 안전성을 확보하고, 서버가 해외에 있으면 국외 이전에 해당하는지 검토하라고 안내합니다. 2023년 삼성전자는 직원이 민감한 코드를 외부 AI 서비스에 올린 뒤 회사 기기에서 생성형 AI 사용을 금지했다고 보도되었습니다.
- 회사가 승인한 AI 도구를 회사 계정으로만 써야 합니다. 고객 코드, 비밀값, 개인정보, 기밀 문서를 개인 계정이나 승인되지 않은 도구에 넣지 않아야 합니다.
- AI가 제안한 명령은 읽고 실행해야 합니다.
curl … | bash,sudo,rm -rf, 새 패키지 설치는 특히 확인이 필요합니다. - AI가 제안한 패키지가 실제로 존재하는지, 언제 만들어졌는지 확인해야 합니다. AI가 자주 지어내는 패키지 이름을 공격자가 미리 등록해 두는 수법이 있습니다.
- AI에게 읽힌 문서, 웹 페이지, 저장소 파일에는 사람 눈에 보이지 않는 지시가 숨어 있을 수 있습니다. 이 문제는 다음 AI 부분에서 자세히 다룹니다.
AI: 설명과 실제 행동이 다를 때
코딩 에이전트는 개발자 대신 파일을 읽고, 셸 명령을 실행하고, 외부 서비스에 연결합니다. 그래서 개발자 PC에 들어온 AI 도구는 개발자와 같은 권한을 가진 또 하나의 사용자가 됩니다. 2026년에는 이 사용자가 설명과 다르게 행동한 사례, 승인 장치를 우회한 사례, 그리고 AI 도구의 설정 파일이 탈취 대상이 된 사례가 함께 나왔습니다.
Qwen3.8-Flash-Next: 도구를 쓰지 않겠다고 한 응답 속의 도구 호출
2026년 10월 26일 Cohere가 알리바바의 오픈 웨이트 모델 Qwen3.8-Flash-Next를 평가하다 겪은 일을 공개했습니다. 오픈 웨이트 모델(open-weight model) 은 학습된 가중치를 내려받아 자기 서버나 PC에서 직접 돌릴 수 있게 공개한 모델입니다. 그래서 이 사례는 알리바바의 서비스가 몰래 통신한 일이 아니라, 평가 환경 안에서 모델이 스스로 만든 명령을 다룹니다.
Cohere가 맡긴 과제는 Microsoft의 보안 분석 벤치마크 CTI-REALM의 문제 하나였습니다. curl로 /tmp에 bash 스크립트를 내려받고 bash로 실행하는 행위를 잡아내는 탐지 룰을 작성하라는 과제였는데, 모델은 룰을 쓰는 대신 아래 네 명령을 bash 호출 한 번에 묶어 실행하려 했습니다.
- /tmp 폴더의 목록을 확인했습니다.
- curl, wget, python3, jq가 설치되어 있는지 확인했습니다.
- DNS 설정 파일인 /etc/resolv.conf를 읽었습니다.
- 베이징 리전의 Alibaba Cloud OSS 버킷으로 HTTP PUT 요청을 보내고, 응답 상태 코드를 확인하려 했습니다.
같은 응답의 추론 기록에는 도구를 쓰지 않겠다는 문장이 있었고, 있지도 않은 이전 대화를 지어낸 부분도 있었습니다. 추론 내용을 읽고 위험을 판단하는 안전장치였다면 그대로 통과시켰을 출력입니다. 실제로 요청을 막은 것은 샌드박스였는데, 밖으로 나가는 네트워크 경로가 없어 연결이 실패했습니다. Cohere는 일반 네트워크가 연결된 개발자 노트북이나 CI 러너였다면 요청이 나갔을 것이라고 밝혔습니다.
이 사례를 두고 “중국 서버로 정보를 보낸다”고 정리하면 사실과 다릅니다. 확인된 사실, 다툼이 있는 해석, 아직 모르는 부분을 나누면 다음과 같습니다.
| 구분 | 내용 |
|---|---|
| 확인된 사실 | 평가 중 한 번의 응답에서 베이징 OSS 버킷으로 PUT 요청을 만들었습니다. 보내려던 값은 PROBE_PAYLOAD_ABC123이라는 테스트 문자열이었고 샌드박스가 연결을 막았습니다. 다만 Cohere는 요청이 나가는 것만으로 받는 쪽 서버에 IP, 시각, 전체 URL이 남는다고 지적했습니다. 추론과 도구 호출이 서로 달랐고, 트레이스와 재현 스크립트가 Hugging Face에 공개되어 있습니다 |
| 다툼이 있는 해석 | Cohere는 평가 호출 10만 건 중 1건 미만이라고 밝혔고, 같은 과제를 다시 돌리면 정상적으로 룰을 작성했습니다. ToolHalla는 원래 프롬프트가 curl과 /tmp를 언급했다는 점, 재현 스크립트가 URL 직전까지 앞부분을 채워 넣고 이어 쓰게 한다는 점, 같은 조건에서 다른 모델도 메타데이터 IP나 임의 URL을 만들어 낸다는 점(다만 알리바바 호스트는 Qwen 계열에서만 나왔습니다)을 들어, 학습 로그에 남은 알리바바 샌드박스 주소를 모델이 외운 결과로 봤습니다. Cohere도 이를 후보 설명의 하나로 듭니다. 다만 근거가 된 주소는 싱가포르의 파일 프록시 호스트이고 베이징 버킷은 그 실험(URL Study) 데이터에 나오지 않으며, 버킷 소유자는 공개되지 않았습니다. 별도 재시험 130회에서는 업로드가 나오지 않았습니다 |
| 아직 모름 | 원인과 의도는 Cohere도 단정하지 않았고, 2026년 11월 4일 기준 알리바바의 공식 입장은 찾지 못했고, The Register와 CSO Online은 알리바바가 질의에 답하지 않았다고 보도했습니다 |
해석이 갈려도 실무에 적용할 결론은 같습니다. Cohere가 정리한 대응도 모델의 의도를 묻지 않고 실행 환경을 통제하는 쪽입니다.
- 직접 만들지 않은 모델 가중치는 서명 없는 실행 파일처럼 다뤄야 합니다.
- 안전 정책은 추론 기록이 아니라 실제 도구 호출에 걸어야 합니다.
- 에이전트의 외부 연결은 기본으로 막고, 처음 보는 클라우드 주소로 나가는 요청에는 알림을 걸어야 합니다.
- 평가용 샌드박스와 운영 환경을 분리해야 합니다.
승인 화면에 보인 명령과 실제로 실행된 명령
코딩 에이전트는 보통 위험한 명령 앞에서 사용자에게 확인을 받습니다. 그런데 무엇이 위험한지 판정하는 코드에 틈이 있으면 확인 절차를 건너뛰게 됩니다. Qwen Code CLI 0.8.2까지는 자동 승인 검사가 여러 줄 명령의 첫 줄만 봤습니다. 첫 줄이 읽기 전용 명령이면 통과시켰는데, 셸은 줄바꿈 뒤의 명령까지 모두 실행했습니다. 이 문제는 0.9.0에서 고쳐졌습니다. 그보다 앞선 0.7.2까지는 awk와 sed를 읽기 전용 명령으로 분류한 문제도 있었습니다. 두 도구 모두 파일을 쓰거나 다른 명령을 실행할 수 있어서, 이 분류를 믿은 자동 승인이 임의 명령 실행으로 이어질 수 있었고 0.8.0에서 고쳐졌습니다.
Qwen Code만의 문제는 아닙니다. 2025년 7월 Gemini CLI에서는 README.md에 숨긴 지시문이 허용 목록의 앞부분 일치 검사를 악용해, 허용된 grep 뒤에 이어 붙인 명령까지 실행시켰습니다. 2025년 8월에는 VS Code의 Copilot 에이전트가 프롬프트 인젝션으로 .vscode/settings.json에 자동 승인 설정을 써넣어 셸 명령을 실행할 수 있었습니다(CVE-2025-53773). 2026년 2월에는 Claude Code의 쓰기 보호 우회와 샌드박스 탈출 취약점 세 건(CVE-2026-25722, CVE-2026-25723, CVE-2026-25725)이 공개되었는데, 모두 그 전에 나온 업데이트에서 이미 고쳐져 있었습니다. 프롬프트 인젝션(prompt injection) 은 AI가 읽는 문서, 이슈, 웹 페이지에 지시문을 숨겨 사용자 대신 공격자의 지시를 따르게 만드는 공격입니다.
MCP 연결도 같은 구조의 위험이 있습니다. MCP(Model Context Protocol) 는 AI 에이전트가 외부 도구와 데이터에 연결하도록 정한 표준 규격입니다. Qwen Code의 신뢰된 워크스페이스에서 MCP 서버에 trust: true를 주면 그 서버의 도구 호출은 확인 절차를 건너뜁니다. 공식 문서도 직접 통제하고 어노테이션을 확인한 서버에만 쓰라고 안내합니다. 2025년 9월에는 Postmark의 공식 MCP 서버 코드를 베껴 npm에 올린 postmark-mcp가 정상 버전으로 신뢰를 쌓은 뒤, 1.0.16부터 보내는 메일마다 공격자 주소를 숨은 참조로 넣었습니다.
이런 사례에서 개발자가 할 수 있는 일은 많지 않지만 효과는 분명합니다.
- AI 코딩 도구를 최신 버전으로 유지해야 합니다. 위 승인 우회 사례는 모두 도구 쪽 업데이트로 고쳐졌습니다.
- 자동 승인 범위를 최소로 두고, 전부 승인하는 모드는 버려도 되는 컨테이너 안에서만 써야 합니다.
- 출처를 확인하지 않은 MCP 서버는 연결하지 않고, 연결한 서버도 쓰는 도구만 남겨야 합니다.
- 에이전트에게 넘기는 토큰은 필요한 저장소와 권한으로 좁혀야 합니다.
탈취 대상이 된 AI 도구 설정 파일
AI 도구의 설정 파일에는 MCP 서버 주소와 인증 정보, LLM API 키가 들어갑니다. 2026년 5월 node-ipc 악성 버전은 클라우드 자격증명, SSH 키와 함께 ~/.claude.json, ~/.claude/mcp.json, .kiro/settings/mcp.json 같은 AI 도구 설정 파일을 수집 목록에 넣었습니다. 4월에 침해된 @bitwarden/cli@2026.4.0도 같은 파일들을 노렸고, AI 도구가 응답하면 셸 설정 파일에 AI 컨텍스트로 읽힐 반AI 선언문을 덧붙였습니다. 2월의 SANDWORM_MODE 웜은 claud-code 같은 오타 패키지로 퍼진 뒤 여러 AI 도구의 MCP 설정에 가짜 서버를 등록했습니다. 그 가짜 도구의 설명에는 SSH 키와 .env 파일을 읽으라는 지시가 들어 있었습니다.
AI 도구 설정 파일도 .env나 SSH 키와 같은 등급의 비밀값으로 다뤄야 합니다. 저장소에 올리지 않고, 공용 PC에서는 도구가 지원하면 암호화 저장 옵션을 켜고, 유출이 의심되면 그 안의 키를 교체해야 합니다.
AI가 끌어올린 공격 속도
PHP2Shell은 AI 도구의 도움으로 찾아낸 결함입니다. Calif는 OpenAI의 Patch the Planet 프로그램 안에서, 2024년에 포착된 문제를 실마리 삼아 LLM 에이전트로 이 결함을 찾았고, Wiz도 따로 AI 도구를 써서 같은 결함에 도달했습니다. AWS는 AI 분석이 패치 차이나 권고문을 공격 코드로 바꾸는 비용을 낮춘다고 평가하면서, 패치와 완화 일정을 며칠이 아니라 몇 시간 단위로 재라고 권고했습니다. 다만 공개 4일 전인 10월 17일의 시도에 대해서는 공격자가 정보를 어떻게 얻었는지 불분명하다고 밝혔고, AI와 연결하지 않았습니다. Dream Research도 PHP2Shell 연쇄 공격의 스크립트에서 AI 보조 개발의 흔적을 봤지만 직접 증거는 없다고 밝혔습니다. Google(Mandiant)의 M-Trends 2026은 2025년 조사를 바탕으로 악용까지 걸리는 평균 시간을 약 마이너스 7일로 추정하고, 패치가 나오기 전에 악용이 일어나는 일이 잦다고 해석했습니다. 다만 같은 보고서는 2025년의 침해가 AI의 직접 결과는 아니라고 봤습니다.
반대 방향의 데이터도 있습니다. VulnCheck는 두 추적 데이터를 합쳐 AI 보조 발견으로 귀속된 취약점 1,061건 중 14건(1.3%)의 실제 악용이 확인됐다고 집계했습니다. AI가 찾은 결함이 더 잘 악용된다는 근거는 아직 없다는 뜻이고, 공격자가 AI를 얼마나 쓰는지를 잰 수치는 아닙니다. 물론 패치까지 걸리는 시간을 줄여야 한다는 결론은 달라지지 않습니다.
OWASP는 이런 위험을 두 목록으로 정리해 두었습니다. OWASP Top 10 for LLM Applications 2025의 LLM01 프롬프트 인젝션과 LLM06 과도한 권한(Excessive Agency), 그리고 2025년 12월에 나온 OWASP Top 10 for Agentic Applications for 2026의 ASI02 도구 오용(Tool Misuse and Exploitation)과 ASI04 에이전트 공급망 취약점이 위 사례들과 가장 가깝습니다.
관제는 어떻게 생각해야 하는가
사고를 하나씩 막는 일에는 끝이 없습니다. 다음 달에도 새 CVE가 나오고, 새 악성 패키지가 올라오고, AI 도구는 새 기능만큼 새 틈을 만들 것입니다. 그래서 개별 사고의 대응법보다 먼저, 어떤 사고가 와도 같은 방식으로 대비할 수 있는 생각의 틀을 갖춰야 합니다.
보안 관제(security monitoring) 는 시스템에서 일어나는 일을 계속 관찰하면서 이상 징후를 찾고, 찾은 징후를 대응으로 잇는 활동입니다. 전담 보안팀이 없는 조직에서는 개발자가 이 일의 상당 부분을 맡게 됩니다. 아래 여섯 가지는 도구를 고르기 전에 정해 둬야 할 원칙입니다.
뚫린다고 가정하기
완벽하게 막는 방법은 없습니다. PHP2Shell처럼 패치보다 공격이 먼저 오는 경우도 있고, Axios처럼 신뢰하던 패키지가 하룻밤 사이에 악성 버전이 되는 경우도 있습니다. 침해 가정(assume breach) 은 공격자가 이미 안에 들어와 있을 수 있다고 전제하고 탐지와 피해 범위 제한을 설계하는 접근입니다. 이렇게 전제하면 준비할 일이 막는 일(예방)에서 알아채는 일(탐지)과 수습하는 일(대응)까지 넓어집니다. 예를 들어 패치를 적용한 서버에서도 웹셸이 남아 있는지 확인하는 절차가 침해 가정에서 나옵니다.
지킬 대상을 먼저 알기
어느 서버에 어떤 PHP와 Node.js 버전이 돌고, 어떤 패키지가 몇 버전으로 설치되어 있는지 모르면 패치도 탐지도 할 수 없습니다. PHP2Shell은 PHP 8.1 이하에 공식 릴리스가 나오지 않았고(PHP 보안팀이 7.4·8.0·8.1용 소스 백포트만 공개했습니다), Next.js 13·14는 2026년 5월 이후 보안 릴리스의 패치를 받지 못했습니다. 이런 버전이 어디에 남아 있는지는 장부가 있어야 찾을 수 있습니다. 오래 방치한 홈페이지, 외주로 만든 사이트, 장비 관리 화면처럼 담당자가 없는 곳에 이런 버전이 남아 있을 수 있습니다.
한 레이어가 아니라 여러 레이어로 막기
심층 방어(defense in depth) 는 서로 다른 성격의 방어 수단을 여러 레이어로 두어, 한 레이어가 뚫려도 다음 레이어에서 막히게 하는 설계입니다. 설치 스크립트 차단은 Axios 악성 버전을 막았겠지만, 불러올 때 실행되는 node-ipc와 차단 장치를 우회하는 PackageGate 앞에서는 효과가 없습니다. node-ipc는 버전 쿨다운에서 멈출 수 있습니다. Git 의존성을 이용하는 PackageGate 경로는 allow-git 같은 Git·원격 의존성 차단에서 막고, 허용 목록 밖 호스트라면 외부 연결을 막는 레이어에서도 멈출 수 있습니다.
기본값을 닫힘으로 두기
최소 권한(least privilege) 은 사람과 프로그램에 일을 하는 데 필요한 만큼의 권한만 주는 원칙입니다. 네트워크에도 같은 원칙을 적용할 수 있는데, 서버와 CI, AI 에이전트가 밖으로 나가는 연결을 기본으로 막고 필요한 목적지만 허용하는 방식입니다. Qwen 사례에서 업로드를 막은 것도, node-ipc가 DNS로 빼돌리려던 자격증명을 막을 수 있는 것도 이 레이어입니다.
시간을 기준으로 생각하기
공격자가 결함을 아는 시점과 서비스가 패치되는 시점 사이의 간격이 곧 위험이 노출된 시간입니다. PHP2Shell은 첫 악용 시도가 패치보다 4일 앞섰고, 패치 뒤에는 반나절 만에 시도가 수백만 건으로 늘었습니다. Axios 악성 버전이 설치될 수 있던 시간도 약 3시간에 불과했습니다. 그래서 등급별 패치 기한을 미리 정해 둬야 합니다. 예를 들어 인터넷에 노출된 서버의 치명적 결함은 당일, 내부망의 높음 등급은 일주일처럼 기준을 정해 두면 공지를 볼 때마다 일정을 다시 논의하지 않아도 됩니다.
설명이 아니라 행동을 보기
버전 문자열, 패키지 이름, AI의 설명은 모두 실제와 다를 수 있습니다. 배포판 패키지는 버전 번호를 바꾸지 않고 보안 수정만 넣는 경우가 있어 php -v 결과만으로는 패치 여부를 판단할 수 없습니다. Axios 악성 버전은 이름도 버전 형식도 정상이었고, Qwen의 추론은 도구를 쓰지 않겠다고 했습니다. 탐지는 프로세스가 무엇을 실행했는지, 어디로 연결했는지, 어떤 파일이 생겼는지처럼 실제 행동을 기준으로 해야 합니다.
큰 틀: NIST CSF 2.0
여섯 원칙을 조직 단위의 틀로 옮기면 미국 국립표준기술연구소(NIST)의 사이버보안 프레임워크와 거의 겹칩니다. NIST는 2024년 2월 26일 발표한 CSF 2.0(Cybersecurity Framework 2.0) 에서 보안 활동을 여섯 가지 기능으로 나눴습니다. 원래 1.1판까지는 식별, 보호, 탐지, 대응, 복구 다섯 기능이었는데, 2.0에서 거버넌스가 추가되었습니다.
| 기능 | 개발자 입장에서 하는 일 | 관련 사례 |
|---|---|---|
| 거버넌스(Govern) | 누가 책임지고 어떤 기준으로 할지 정하기. 패치 기한, 승인된 AI 도구 목록 | 패치 기한 표 |
| 식별(Identify) | 무엇이 어디서 어떤 버전으로 도는지 알기. 보안 공지 받기 | PHP 8.1 이하, Next.js 13·14 |
| 보호(Protect) | 막기. 업데이트, 최소 권한, 설치 정책, 아웃바운드 차단 | 버전 쿨다운, 스크립트 차단 |
| 탐지(Detect) | 알아채기. 이상 행동 신호 보기 | 웹 프로세스의 셸 실행 |
| 대응(Respond) | 수습하기. 격리, 비밀값 교체, 신고 | Axios 감염 PC 처리 |
| 복구(Recover) | 되돌리기. 깨끗한 환경에서 다시 빌드, 백업 복원 | node-ipc 이후 재빌드 |
예방, 탐지, 대응을 실제로 준비하는 방법
원칙을 정했다면 그 원칙을 매일의 일로 바꿔야 합니다. 전담 보안팀이 없어도 시작할 수 있는 일을 보안 공지 받기, 우선순위 정하기, 목록 만들기, 신호 보기, 사고 대응 순서로 정리했습니다.
보안 공지를 받는 곳
보안 공지는 찾아 읽기보다 자동으로 받아 보도록 설정해 두는 편이 좋습니다. PHP2Shell은 공지 2시간 안에 악용 시도가 수십만 건으로 늘었기 때문에, 공지를 다음 날 읽으면 이미 늦습니다.
| 출처 | 무엇을 알려 주는가 | 받는 방법 |
|---|---|---|
| KISA 보호나라 보안공지 | 국내 보안 업데이트 권고, 대응 수칙, 사이버위기 경보 | 보호나라 보안공지 게시판, RSS |
| CISA KEV 목록 | 실제로 악용이 확인된 취약점 | 웹 목록, JSON 피드, GitHub의 cisagov/kev-data 저장소 |
| 런타임 보안 공지 | 보안 릴리스 일정과 내용, 임시 대책 | 사용하는 런타임의 보안 메일링 리스트, RSS 피드, 공식 뉴스, GitHub 보안 권고 |
| GitHub 보안 알림 | 내 저장소 의존성의 취약점과 악성 패키지 | Dependabot 알림, 저장소 Watch의 Security alerts |
| 프레임워크 보안 권고 | Next.js, Nuxt, Laravel, 워드프레스 플러그인의 결함 | 각 저장소의 Security advisories, 워드프레스는 Wordfence·Patchstack 공지 |
KISA는 PHP2Shell 대응 수칙을 공지 다음 날 올렸고, 과학기술정보통신부는 같은 날 민간 분야 사이버위기 경보를 관심에서 주의로 올렸습니다. 국내 대응 수칙은 해외 자료보다 늦게 나올 때도 있지만, 국내 환경에 맞춘 점검 항목과 신고 경로가 함께 나오므로 꼭 받아 봐야 합니다.
무엇부터 고칠지 정하는 기준
공지를 받기 시작하면 고칠 것이 너무 많아집니다. 그래서 우선순위를 정하는 기준이 필요합니다. 많이 쓰는 지표는 세 가지입니다.
- CVSS: 결함이 악용되면 얼마나 심각한지를 나타내는 심각도입니다. 흔히 쓰는 기본 점수(Base)는 실제로 공격받을 가능성을 담고 있지 않습니다.
- EPSS(Exploit Prediction Scoring System): 국제 보안사고대응팀 협의체 FIRST의 EPSS 특별관심그룹이 관리하고 매일 갱신되는 점수로, 그 CVE가 앞으로 30일 안에 실제 공격에 쓰일 확률을 0과 1 사이로 예측합니다.
- KEV(Known Exploited Vulnerabilities): CISA가 CVE 번호가 있고, 악용(시도 포함)의 신뢰할 만한 증거가 있으며, 조치 방법이 분명한 취약점만 올리는 목록입니다. PoC가 공개된 것만으로는 오르지 않습니다.
FIRST는 KEV를 관측된 사실, EPSS를 예측으로 보고 둘을 함께 쓰라고 안내합니다. KEV에 올랐다면 EPSS가 낮아도 KEV를 따르고, CVSS와 EPSS를 곱해서 하나의 점수로 만들지 말라고 권고합니다. 이 안내를 서비스 상황에 맞춰 옮기면 다음과 같은 기준을 세울 수 있습니다. 기한은 예시이므로 팀의 배포 주기에 맞게 정해야 합니다.
| 조건 | 판단 | 기한 예시 |
|---|---|---|
| KEV에 올랐고, 인터넷에 노출된 서버가 영향을 받음 | 바로 고침 | 당일 |
| CVSS 높음, EPSS 높음 | 먼저 고침 | 2~3일 |
| CVSS 낮음, EPSS 높음 | 다른 결함과 이어 쓰일 수 있는지 확인 | 1주 |
| CVSS 높음, EPSS 낮음 | 지켜보며 정기 배포에 포함 | 2주 |
| 둘 다 낮음 | 정기 업데이트로 처리 | 다음 정기 배포 |
참고로 CISA는 미국 연방 기관에 KEV 항목마다 조치 기한을 정해 둡니다. PHP2Shell은 KEV 등재 3일 뒤인 10월 29일, Brotli 결함은 2주 뒤인 11월 10일이 기한이었습니다.
무엇이 돌고 있는지 아는 목록
KISA의 PHP2Shell 대응 수칙은 첫 항목으로, 자산 목록에 적힌 것이 아니라 실제로 돌고 있는 모든 PHP를 찾으라고 권고했습니다. 외주로 만든 사이트, 잊힌 이전 사이트, 이벤트용 서버와 테스트 서버, 관리자 페이지, 장비의 관리 화면, 다른 곳에서 받은 Docker 이미지까지 포함입니다. 그리고 php -v의 결과가 웹 서비스가 실제로 쓰는 PHP와 다를 수 있으므로, 웹 서비스 기준으로 확인하라고 덧붙였습니다.
서버 목록과 함께 각 서비스에 들어간 패키지 목록도 필요합니다. SBOM(Software Bill of Materials) 은 소프트웨어에 들어간 구성 요소와 버전을 기계가 읽을 수 있는 형식으로 적은 목록입니다. OWASP와 Ecma가 관리하는 CycloneDX(ECMA-424)와 리눅스 재단의 SPDX(ISO/IEC 5962:2021)가 대표 형식입니다. SBOM이 있으면 새 공지가 나왔을 때 “이 패키지 이 버전을 쓰는 서비스가 어디인가”를 검색으로 답할 수 있습니다.
# npm 프로젝트의 SBOM을 CycloneDX 형식으로 만들기 (npm 9.9.0 또는 10.2.0 이상)
npm sbom --sbom-format cyclonedx --omit dev > sbom.cdx.json
# 알려진 취약점 확인
npm audit --omit dev
composer audit --no-dev --locked
# 설치된 패키지의 레지스트리 서명과 배포 기록 확인
npm audit signatures
npm audit는 공개된 보안 권고를, composer audit는 여기에 더해 2.10부터 악성으로 지정된 버전까지 확인합니다. 그래도 막 올라와 아직 지정되지 않은 악성 버전은 감사 도구에 나타나지 않습니다. 그래서 감사 도구는 알려진 결함을 정리하는 용도로 쓰고, 막 올라온 악성 버전은 쿨다운과 행동 감시로 막아야 합니다. 의존성 자체가 얼마나 관리되는지 보려면 OpenSSF Scorecard가 브랜치 보호, 위험한 워크플로, 의존성 고정 같은 항목을 자동으로 점수 매겨 줍니다.
침해를 알려 주는 신호
원격 코드 실행에 성공한 공격자는 웹셸이나 원격 조종 프로그램을 남겨, 패치 뒤에도 돌아올 길을 만들 수 있습니다. 그래서 패치와 별개로 침해 흔적을 찾아야 합니다. KISA 대응 수칙과 분석 보고서들을 종합한 탐지 신호는 다음과 같습니다.
| 신호 | 무엇을 뜻할 수 있는가 | 관련 사례 |
|---|---|---|
웹 서버나 애플리케이션 런타임 프로세스가 sh, bash, curl, wget을 실행함 | 원격 코드 실행 성공. 가장 확실한 신호 | PHP2Shell, React2Shell, Livewire, Brotli(RCE에 성공한 경우) |
| 서버가 처음 보는 외부 주소로 연결함 | 데이터 유출, 원격 조종 프로그램의 접속 | node-ipc의 DNS 유출, Axios |
| 큰 요청 뒤 500 오류 반복, 메모리 한도 초과, 프로세스 충돌 | 메모리 결함을 노린 공격 시도 | PHP2Shell, Brotli, 서비스 거부 결함 |
| 웹 폴더, 업로드 폴더, 임시 폴더에 새 스크립트 파일이나 수정된 파일 | 웹셸 설치 | PHP2Shell, wp2shell |
| 처음 보는 관리자 계정 | 인증 우회 뒤 거점 확보 | wp2shell, Modular DS, WP Maps Pro |
| CI의 의존성 설치 단계에서 외부 연결 | 공급망 공격 | Axios(재현 실행에서 설치 시작 약 2초 뒤 연결) |
| 이벤트 루프 지연이나 CPU 사용률의 갑작스런 상승 | CPU를 붙잡는 요청 | ReDoS, RSC 서비스 거부 |
첫째 신호 중 셸 실행은 도구로 잡을 수 있습니다. 오픈소스 런타임 보안 도구 Falco의 기본 규칙 “Run shell untrusted”는 셸이 아닌 프로그램 아래에서 셸이 실행되면 알림을 보냅니다. 다만 이 규칙은 셸 실행만 보므로 curl이나 wget을 직접 실행하면 잡지 못합니다. 그리고 감시 대상 조상 프로세스 목록에 nginx와 Apache는 있지만 php-fpm은 없고, Node.js 감시는 따로 켜야 하므로 실제 구성에 맞게 목록을 고쳐야 합니다. AWS GuardDuty 런타임 모니터링 같은 클라우드 위협 탐지 서비스도 같은 신호를 봅니다.
웹셸이 생기지 않게 하는 설정도 함께 해야 합니다. 미국 NSA와 호주 사이버보안센터의 공동 지침은 웹 서버 프로세스가 웹 폴더에 쓰거나 웹 코드를 고칠 수 없게 하라고 권고합니다. 업로드 폴더에서는 스크립트 실행을 막고, 배포한 코드는 파일 무결성 감시로 원본과 비교할 수 있습니다. 워드프레스 코어는 wp core verify-checksums, 공개 플러그인은 wp plugin verify-checksums --all로 비교할 수 있지만, wp-content/uploads의 파일은 이 명령의 대상이 아닙니다. KISA는 로그가 깨끗하다고 해서 서버가 안전하다는 뜻은 아니라고 덧붙였습니다.
사고가 났을 때의 순서
KISA의 PHP2Shell 대응 수칙은 침해사고가 발생하면 격리, 신고, 증거 확보, 조치의 네 단계를 제시합니다. 여기에 재구축과 사후 검토를 더하면 다음과 같습니다. 원리는 랜섬웨어 첫 대응과 같습니다.
- 격리: 서버를 끄거나 재부팅하지 않고 외부 네트워크만 차단합니다. 메모리의 프로세스와 연결 정보는 전원을 끄면 사라집니다.
- 신고: 보호나라의 침해사고 신고 페이지나 118로 신고합니다. 정보통신서비스 제공자는 침해사고를 알게 된 때부터 24시간 이내에 신고해야 하는 법적 의무가 있습니다(정보통신망법 제48조의3). 법적 판단이 필요하면 법무 담당자나 전문가에게 확인해야 합니다.
- 증거 확보: 웹 서버와 애플리케이션 로그, 실행 중인 프로세스 목록, 네트워크 연결 목록을 저장합니다.
- 조치: 패치를 적용해 서비스를 재시작하고, 웹셸을 지우고, DB 비밀번호와 API 키와 관리자 비밀번호를 모두 교체합니다.
- 재구축: 가능하면 감염된 서버를 고치기보다 깨끗한 이미지에서 다시 만듭니다. 공격자가 어디까지 손댔는지 확신할 수 없기 때문입니다.
- 사후 검토: 누가 잘못했는지가 아니라 무엇이 그 사고를 가능하게 했는지를 기록하고, 다음에 같은 일이 생기지 않게 절차를 고칩니다.
공개된 PoC를 직접 내 서버에 돌려 보는 일은 피해야 합니다. KISA는 공개 PoC 상당수에 악성 코드가 심어져 있다고 경고했습니다. 탐지와 대응의 기반이 되는 로그 설계와 관측 구조는 운영의 관측과 탄력성 - OWASP Top 10:2025 ep.05와 관측 경계와 분산 추적 - 디자인 패턴, 시스템 수준 편 ep.13에서 더 자세히 다뤘습니다.
작게 시작하는 순서
한 번에 다 할 필요는 없습니다. 효과가 크고 비용이 작은 것부터 시작하면 됩니다.
| 시기 | 할 일 |
|---|---|
| 오늘 | 보호나라 보안공지, 사용하는 런타임의 보안 메일링, GitHub 보안 알림 구독. 운영 중인 PHP와 Node.js 버전 확인 |
| 이번 주 | .npmrc에 설치 스크립트 차단과 쿨다운 설정. 웹 루트가 public/인지 확인. 운영 빌드에서 개발용 의존성 제외. PC 자동 화면 잠금 |
| 이번 달 | 서버 목록과 SBOM 작성. 웹 프로세스의 셸 실행 알림. 서버와 CI의 외부 연결 허용 목록. 백업 복원 시험 |
| 분기마다 | 패치 기한 기준 점검. 쓰지 않는 계정, 토큰, 공동 관리자 권한 정리. 사고 대응 순서를 따라 해 보는 연습 |
마치며
2025년 말부터 2026년까지의 사고들을 층별로 나눠 보면, 애플리케이션 코드에서 시작된 사고는 거의 없었습니다. PHP2Shell과 Brotli 결함은 런타임에 있었고, React2Shell과 Livewire는 프레임워크가 요청을 해석하는 방식에 있었습니다. Axios와 node-ipc는 설치한 패키지였습니다. PHPUnit은 배포 과정의 실수였고, Nuxt 개발 번들은 네트워크에 열어 둔 개발 서버에서 드러난 결함이었습니다. Qwen 사례는 평가 샌드박스에서 AI 모델이 스스로 만든 외부 호출이었습니다. 코드를 깨끗하게 쓰는 일은 여전히 중요하지만, 그것만으로는 서버를 지킬 수 없습니다.
여러 사례에 공통으로 나타난 것은 시간입니다. 공격자가 결함을 알게 되는 시점은 점점 패치 배포보다 앞서고, 악성 패키지는 몇 시간 만에 퍼집니다. 그래서 준비할 일도 막는 일에서 끝나지 않습니다. 보안 공지를 바로 받아 보고, 무엇이 어디서 도는지 알고, 실제 행동을 기준으로 이상 신호를 보고, 사고가 나면 정해 둔 순서대로 움직일 수 있어야 합니다.
그리고 그 모든 순서의 출발점은 사람입니다. 낯선 회의에서 받은 업데이트를 의심하고, 잘못 누른 링크를 바로 말하고, 퇴근할 때 화면을 잠그는 일은 어떤 도구도 대신해 주지 않습니다.
참고 자료
런타임
- PHP Foundation. (2026). Today’s PHP Security Release, and How We’re Strengthening PHP Security. https://thephp.foundation/blog/2026/10/21/todays-php-security-release-and-how-were-strengthening-php-security/
- PHP. (2026). News Archive 2026. https://www.php.net/archive/2026.php
- PHP. (2026). PHP 8 ChangeLog. https://www.php.net/ChangeLog-8.php
- PHP. (2026). Supported Versions. https://www.php.net/supported-versions.php
- PHP. (2026). GHSA-w8hw-w9fx-j79w: RCE via OOM corruption. https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w
- PHP. (2026). GHSA-6wmf-4rv5-p3rp: RCE via stale global state. https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp
- Calif. (2026). PHP2Shell: A Tale of Two PHP Remote Vulnerabilities. https://calif.io/php2shell.x/
- Wiz. (2026). PHP2Shell: AI Uncovers Critical RCE Vulnerabilities Affecting 70% of the Internet. https://www.wiz.io/blog/php2shell-php-rce
- Amazon Web Services. (2026). Amazon Threat Intelligence Identifies PHP2Shell Exploitation Prior to Public Disclosure in MadPot. https://aws.amazon.com/blogs/security/amazon-threat-intelligence-identifies-php2shell-exploitation-prior-to-public-disclosure-in-madpot/
- The Next Web. (2026). Cloudflare Sees Millions of Attempts to Exploit Critical PHP Flaws. https://thenextweb.com/news/cloudflare-php2shell-millions-exploit-attempts
- KISA 보호나라. (2026). PHP 제품 보안 업데이트 권고. https://www.boho.or.kr/kr/bbs/view.do?bbsId=B0000133&menuNo=205020&nttId=72227
- KISA 보호나라. (2026). PHP 보안취약점(PHP2Shell) 관련 기업 보안 대응 수칙. https://www.boho.or.kr/kr/bbs/view.do?bbsId=B0000133&menuNo=205020&nttId=72230
- 과학기술정보통신부. (2026). 과기부, ‘PHP’ 심각한 보안 취약점…’보안 업데이트’ 즉시 적용. https://www.korea.kr/news/policyNewsView.do?newsId=148974113
- Node.js. (2026). Wednesday, October 21, 2026 Security Releases. https://nodejs.org/en/blog/vulnerability/october-2026-security-releases
- Node.js. (2026). Wednesday, November 11, 2026 Security Releases. https://nodejs.org/en/blog/vulnerability/november-2026-security-releases
- Node.js. Release Schedule. https://raw.githubusercontent.com/nodejs/Release/main/schedule.json
- Node.js. Single Executable Applications. https://nodejs.org/api/single-executable-applications.html
- Node.js. (2026). Previous Releases. https://nodejs.org/en/about/previous-releases
- HeroDevs. (2026). CVE-2026-111497 (Node2Shell): Node.js Brotli RCE. https://www.herodevs.com/blog-posts/cve-2026-111497-node2shell-node-js-brotli-rce
- The Hacker News. (2026). Node.js Brotli Decoder Bug Could Allow Remote Code Execution. https://thehackernews.com/2026/10/nodejs-brotli-decoder-bug-could-allow.html
- CISA. (2026). Known Exploited Vulnerabilities Catalog. https://www.cisa.gov/known-exploited-vulnerabilities-catalog
- PHP. (2026). Informational Advisory: Session Upload Progress. https://www.php.net/archive/2026.php#2026-10-23-1
- Matthew Prince. (2026). Some Stats on #php2shell. https://x.com/eastdakota/status/2113079352682570051
- Dream Research. (2026). Chained PHP2Shell Exploit Roots 25 Servers, Including US Government Servers. https://dreamgroup.com/blog/chained-php2shell-exploit-roots-25-servers
- Unit 42. (2026). Threat Brief: Critical Vulnerabilities in PHP: CVE-2026-109618, CVE-2026-109619. https://unit42.paloaltonetworks.com/cve-2026-109618-cve-2026-109619/
- SecurityWeek. (2026). PHP2Shell Attacks Root Palo Alto Firewalls but Fail Against WordPress. https://www.securityweek.com/php2shell-attacks-root-palo-alto-firewalls-but-fail-against-wordpress/
- google/brotli. (2026). Detect and Report Invalid Stream Earlier. https://github.com/google/brotli/commit/0ed4268a4401abcb4472096340477cf4af7d1a2b
- Google Project Zero. (2026). Brotli: Heap Out-of-Bounds Read and Write in the Decoder’s Internal Input Buffer. https://project-zero.issues.chromium.org/issues/565308158
- Imperva. (2026). Node2Shell: From Brotli Data to Remote Code Execution. https://www.imperva.com/blog/node2shell-from-brotli-data-to-remote-code-execution/
- ELLIO. (2026). Node2Shell (CVE-2026-111497) aka HTTP2Shell and Broccoli2Shell: RCE Analysis. https://ellio.tech/en/blog/node2shell-cve-2026-111497-rce-on-stock-nodejs-builds/
- Aikido. (2026). Node2Shell: Node.js Brotli Vulnerability Allows Remote Code Execution. https://www.aikido.dev/blog/node2shell-nodejs-brotli-rce-cve-2026-111497
- Microsoft. (2026). Microsoft Security Advisory CVE-2026-111497: .NET Brotli Decoder Out-of-bounds Write Vulnerability. https://github.com/dotnet/announcements/issues/494
- Envoy. (2026). GHSA-3wvj-j6qm-62mr: Out-of-Bounds Write in Brotli Decompressor. https://github.com/envoyproxy/envoy/security/advisories/GHSA-3wvj-j6qm-62mr
- Express. (2026). October 2026 Security Releases. https://expressjs.com/en/blog/2026-10-31-security-releases
프레임워크와 라이브러리
- React. (2025). Critical Security Vulnerability in React Server Components. https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components
- Amazon Web Services. (2025). China-nexus Cyber Threat Groups Rapidly Exploit React2Shell Vulnerability (CVE-2025-55182). https://aws.amazon.com/blogs/security/china-nexus-cyber-threat-groups-rapidly-exploit-react2shell-vulnerability-cve-2025-55182/
- React. (2026). GHSA-479c-33wc-g2pg: Denial of Service Vulnerability in React Server Components. https://github.com/facebook/react/security/advisories/GHSA-479c-33wc-g2pg
- React. (2026). GHSA-rv78-f8rc-xrxh: Denial of Service Vulnerability in React Server Components. https://github.com/facebook/react/security/advisories/GHSA-rv78-f8rc-xrxh
- Vercel. (2026). Next.js May 2026 Security Release. https://vercel.com/changelog/next-js-may-2026-security-release
- Next.js. (2026). GHSA-mg66-mrh9-m8jx: Denial of Service via Connection Exhaustion in Applications Using Cache Components. https://github.com/vercel/next.js/security/advisories/GHSA-mg66-mrh9-m8jx
- Next.js. (2026). GHSA-h64f-5h5j-jqjh: Denial of Service in the Image Optimization API. https://github.com/vercel/next.js/security/advisories/GHSA-h64f-5h5j-jqjh
- Next.js. (2026). GHSA-p293-qw3h-jr36: Unauthenticated Remote Code Execution on Windows-hosted Servers. https://github.com/vercel/next.js/security/advisories/GHSA-p293-qw3h-jr36
- Next.js. (2026). GHSA-2xp9-vwfh-vxw4: Unauthenticated Remote Code Execution in Image Optimization API When AVIF Files Are Used. https://github.com/vercel/next.js/security/advisories/GHSA-2xp9-vwfh-vxw4
- Next.js. (2026). GHSA-vcvr-r3jv-pc5j: Remote Code Execution in next/og ImageResponse. https://github.com/vercel/next.js/security/advisories/GHSA-vcvr-r3jv-pc5j
- Next.js. (2026). GHSA-2464-fhr4-w9xw: Unauthenticated Remote Code Execution in Image Optimization API When SVG Files Are Used. https://github.com/vercel/next.js/security/advisories/GHSA-2464-fhr4-w9xw
- Next.js. (2026). GHSA-673q-mjm6-r5xr: Unauthenticated Remote Code Execution in use cache Functions Returning Typed Arrays. https://github.com/vercel/next.js/security/advisories/GHSA-673q-mjm6-r5xr
- React. (2026). GHSA-xqc2-xf4c-x3h3: Unauthenticated Remote Code Execution in React Server Components. https://github.com/facebook/react/security/advisories/GHSA-xqc2-xf4c-x3h3
- Next.js. (2026). v16.4.5. https://github.com/vercel/next.js/releases/tag/v16.4.5
- Next.js. (2026). v15.5.29. https://github.com/vercel/next.js/releases/tag/v15.5.29
- lachlan2k. React2Shell CVE-2025-55182 Original PoC. https://github.com/lachlan2k/React2Shell-CVE-2025-55182-original-poc
- Livewire. (2025). GHSA-29cq-5w36-x7w3: Livewire Remote Command Execution During Property Update Hydration. https://github.com/livewire/livewire/security/advisories/GHSA-29cq-5w36-x7w3
- Synacktiv. (2025). Livewire: Remote Command Execution through Unmarshaling. https://www.synacktiv.com/en/publications/livewire-remote-command-execution-through-unmarshaling
- Synacktiv. (2026). Livewire Remote Command Execution through Unmarshaling (Advisory). https://synacktiv.com/advisories/livewire-remote-command-execution-through-unmarshaling
- Imperva. (2026). CVE-2025-54068 Laravel Livewire Credential Theft Campaign: 6,000+ Applications Compromised. https://www.imperva.com/blog/cve-2025-54068-laravel-livewire-credential-theft-campaign-6000-applications-compromised/
- Wiz. (2026). CVE-2025-54068 Exploited in Large-Scale Laravel Livewire Credential Theft Campaign. https://threats.wiz.io/all-incidents/cve-2025-54068-exploited-in-large-scale-laravel-livewire-credential-theft-campaign
- Laravel. (2026). GHSA-m27r-m6rx-mhm4: Redis Horizontal Scaling Insecure Deserialization. https://github.com/laravel/reverb/security/advisories/GHSA-m27r-m6rx-mhm4
- Laravel. (2026). Reverb Pull Request #360: Add Allowed Classes. https://github.com/laravel/reverb/pull/360
- PHP. unserialize. https://www.php.net/manual/en/function.unserialize.php
- Ambionics. PHPGGC: PHP Generic Gadget Chains. https://github.com/ambionics/phpggc
- Nuxt. (2026). GHSA-9473-5f9j-94wq: Server-Side Remote Code Execution via Runtime Template Injection in Nuxt Server Island Props. https://github.com/nuxt/nuxt/security/advisories/GHSA-9473-5f9j-94wq
- Nuxt. (2026). GHSA-48hr-524c-v5w3: Unauthorized Component Instantiation via Server Island Props in Nuxt. https://github.com/nuxt/nuxt/security/advisories/GHSA-48hr-524c-v5w3
- Nuxt. (2026). GHSA-hg3f-28rg-4jxj: Route Middleware Not Enforced When Rendering .server.vue Pages. https://github.com/nuxt/nuxt/security/advisories/GHSA-hg3f-28rg-4jxj
- Nuxt. (2026). GHSA-9v7c-q64q-vv33: Dot Segments in the Request Path Bypass server/middleware Path Checks. https://github.com/nuxt/nuxt/security/advisories/GHSA-9v7c-q64q-vv33
- Nuxt. (2026). GHSA-r99w-jh2x-3mg9: Incomplete Fix for GHSA-9v7c-q64q-vv33. https://github.com/nuxt/nuxt/security/advisories/GHSA-r99w-jh2x-3mg9
- Nuxt. (2026). GHSA-mjrq-cffv-q4qc: Nuxt Dev Server Serves Files from a Parent Directory with a Stray Lockfile or Workspace File. https://github.com/nuxt/nuxt/security/advisories/GHSA-mjrq-cffv-q4qc
- WordPress. (2026). WordPress 7.0.2 Release. https://wordpress.org/news/2026/07/wordpress-7-0-2-release/
- WordPress. (2026). GHSA-ff9f-jf42-662q: REST API Batch-Route Confusion and SQL Injection Issue Leading to Remote Code Execution. https://github.com/WordPress/wordpress-develop/security/advisories/GHSA-ff9f-jf42-662q
- WordPress. (2026). GHSA-fpp7-x2x2-2mjf: Facilitated SQL Injection Vulnerability in the author__not_in Parameter of WP_Query. https://github.com/WordPress/wordpress-develop/security/advisories/GHSA-fpp7-x2x2-2mjf
- Searchlight Cyber. (2026). Exploit Brokers Pay $500,000 for a WordPress RCE. I Found One with GPT5.6 Sol Ultra and $25. https://slcyber.io/research-center/exploit-brokers-pay-500000-for-a-wordpress-rce-i-found-one-with-gpt5-6/
- Wiz. (2026). Exploitation in the Wild of wp2shell. https://wiz.io/blog/wp2shell-cve-2026-63030-cve-2026-60137
- Tenable. (2026). wp2shell (CVE-2026-63030, CVE-2026-60137): Frequently Asked Questions About Remote Code Execution Chain in WordPress Core. https://tenable.com/blog/wp2shell-cve-2026-63030-cve-2026-60137-frequently-asked-questions-about-remote-code-execution
- Triskele Labs. (2026). Critical WordPress Core wp2shell RCE Chain Under Active Exploitation. https://www.triskelelabs.com/resources/critical-wordpress-core-wp2shell-rce-chain-under-active-exploitation-cve-2026-63030-cve-2026-60137
- Patchstack. (2026). Critical Privilege Escalation Vulnerability in Modular DS Plugin Affecting 40k+ Sites Exploited in the Wild. https://patchstack.com/articles/critical-privilege-escalation-vulnerability-in-modular-ds-plugin-affecting-40k-sites-exploited-in-the-wild/
- BleepingComputer. (2026). WP Maps Pro Bug Exploited to Create Admin Accounts on WordPress Sites. https://www.bleepingcomputer.com/news/security/wp-maps-pro-bug-exploited-to-create-admin-accounts-on-wordpress-sites/
- BleepingComputer. (2026). WordPress Membership Plugin Bug Exploited to Create Admin Accounts. https://www.bleepingcomputer.com/news/security/wordpress-membership-plugin-bug-exploited-to-create-admin-accounts/
- NVD. CVE-2026-8732. https://nvd.nist.gov/vuln/detail/CVE-2026-8732
- NVD. CVE-2026-1492. https://nvd.nist.gov/vuln/detail/CVE-2026-1492
서비스 거부
- Express. (2026). March 2026 Security Releases. https://expressjs.com/en/blog/2026-03-30-security-releases
- pillarjs. (2026). GHSA-27v5-c462-wpq7: path-to-regexp ReDoS. https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-27v5-c462-wpq7
- pillarjs. (2026). GHSA-37ch-88jc-xwx2: path-to-regexp Vulnerable to Regular Expression Denial of Service via Multiple Route Parameters. https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-37ch-88jc-xwx2
- pillarjs. (2026). GHSA-j3q9-mxjg-w52f: path-to-regexp Vulnerable to Denial of Service via Sequential Optional Groups. https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-j3q9-mxjg-w52f
- Express. (2026). Multer Security Advisories. https://github.com/expressjs/multer/security/advisories
- PHP. (2026). GHSA-mhmq-mmqj-2v39: Failure to Setup TLS with a Remote Server Can Result in a Remote DoS. https://github.com/php/php-src/security/advisories/GHSA-mhmq-mmqj-2v39
- ota-meshi. eslint-plugin-regexp: regexp/no-super-linear-backtracking. https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-super-linear-backtracking.html
- Node.js. Performance Measurement APIs (perf_hooks). https://nodejs.org/api/perf_hooks.html
- Node.js. HTTP. https://nodejs.org/api/http.html
공급망
- Axios. (2026). Post Mortem: axios npm Supply Chain Compromise. https://github.com/axios/axios/issues/10636
- Google Threat Intelligence Group. (2026). North Korea-Nexus Threat Actor Compromises Widely Used Axios NPM Package in Supply Chain Attack. https://cloud.google.com/blog/topics/threat-intelligence/north-korea-threat-actor-targets-axios-npm-package/
- CISA. (2026). Supply Chain Compromise Impacts Axios Node Package Manager. https://www.cisa.gov/news-events/alerts/2026/04/20/supply-chain-compromise-impacts-axios-node-package-manager
- Cyber Security Agency of Singapore. (2026). Advisory on Axios Supply Chain Attack via Compromised npm Account. https://www.csa.gov.sg/alerts-and-advisories/advisories/ad-2026-002/
- StepSecurity. (2026). Axios Compromised on npm: Malicious Versions Drop Remote Access Trojan. https://stepsecurity.io/blog/axios-compromised-on-npm-malicious-versions-drop-remote-access-trojan
- Elastic Security Labs. (2026). Inside the Axios Supply Chain Compromise: One RAT to Rule Them All. https://www.elastic.co/security-labs/axios-one-rat-to-rule-them-all
- BleepingComputer. (2026). Axios npm Hack Used Fake Teams Error Fix to Hijack Maintainer Account. https://bleepingcomputer.com/news/security/axios-npm-hack-used-fake-teams-error-fix-to-hijack-maintainer-account
- Socket. (2026). Popular node-ipc npm Package Infected with Credential Stealer. https://socket.dev/blog/node-ipc-package-compromised
- StepSecurity. (2026). Active Supply Chain Attack: Malicious node-ipc Versions Published to npm. https://stepsecurity.io/blog/node-ipc-npm-supply-chain-attack
- SafeDep. (2026). Compromised node-ipc on npm: Credential Stealer via DNS Exfiltration. https://safedep.io/malicious-node-ipc-npm-compromise/
- Ian Ahl. (2026). node-ipc Domain Takeover Timeline. https://x.com/TekDefense/status/2054963016039342549
- Datadog Security Labs. (2026). Backdoored node-ipc npm Releases Steal Developer Credentials through DNS Queries. https://securitylabs.datadoghq.com/articles/node-ipc-npm-malware-analysis/
- CSO Online. (2026). Expired Domain Leads to Supply Chain Attack on node-ipc npm Package. https://www.csoonline.com/article/4171926/expired-domain-leads-to-supply-chain-attack-on-node-ipc-npm-package.html
- CISA. (2025). Widespread Supply Chain Compromise Impacting npm Ecosystem. https://www.cisa.gov/news-events/alerts/2025/09/23/widespread-supply-chain-compromise-impacting-npm-ecosystem
- Datadog Security Labs. (2025). The Shai-Hulud 2.0 npm Worm: Analysis, and What You Need to Know. https://securitylabs.datadoghq.com/articles/shai-hulud-2.0-npm-worm/
- TanStack. (2026). Postmortem: TanStack npm Supply-chain Compromise. https://tanstack.com/blog/npm-supply-chain-compromise-postmortem
- Palo Alto Networks Unit 42. (2026). The npm Threat Landscape: Attack Surface and Mitigations. https://unit42.paloaltonetworks.com/monitoring-npm-supply-chain-attacks/
- StepSecurity. (2026). A Mini Shai-Hulud Has Appeared: Obfuscated Bun Runtime Payloads Hit SAP-Related Packages. https://www.stepsecurity.io/blog/a-mini-shai-hulud-has-appeared
- cap-js/cds-dbs. (2026). Pull Request #1592: Separate release-please from npm Publish Job. https://github.com/cap-js/cds-dbs/pull/1592
- StepSecurity. (2026). Miasma npm Supply Chain Attack: Self-Spreading Worm via Phantom Gyp. https://www.stepsecurity.io/blog/binding-gyp-npm-supply-chain-attack-spreads-like-worm
- Socket. (2026). Mini Shai-Hulud Hits @antv Ecosystem, 639 Compromised npm Package Versions. https://socket.dev/blog/antv-packages-compromised
- Chainguard. (2026). Mini Shai-Hulud npm Attack: AntV Ecosystem Compromise. https://chainguard.dev/unchained/mini-shai-hulud-npm-attack-antv-ecosystem-compromise-may-2026
- Risky Business. (2026). Risky Bulletin: Shai-Hulud Goes Open Source. https://news.risky.biz/risky-bulletin-shai-hulud-goes-open-source/
- Socket. (2026). Mini Shai-Hulud Spreads to Packagist: Malicious Intercom PHP Package Follows npm Compromise. https://socket.dev/blog/mini-shai-hulud-packagist-malicious-intercom-php-package-compromise
- Snyk. (2026). laravel-lang Supply Chain Advisory. https://snyk.io/blog/laravel-lang-supply-chain-advisory/
- Socket. (2026). Laravel Lang Compromised with RCE Backdoor Across 700+ Versions. https://socket.dev/blog/laravel-lang-compromise
- Security Affairs. (2026). PackageGate Bugs Let Attackers Bypass Protections in npm, pnpm, vlt, and Bun. https://securityaffairs.com/187416/hacking/packagegate-bugs-let-attackers-bypass-protections-in-npm-pnpm-vlt-and-bun.html
- SecurityWeek. (2026). ‘PackageGate’ Flaws Open JavaScript Ecosystem to Supply Chain Attacks. https://www.securityweek.com/packagegate-flaws-open-javascript-ecosystem-to-supply-chain-attacks/
- pnpm. (2026). GHSA-379q-355j-w6rj (CVE-2025-69264). https://github.com/advisories/GHSA-379q-355j-w6rj
- pnpm. (2026). GHSA-7vhp-vf5g-r2fw (CVE-2025-69263). https://github.com/advisories/GHSA-7vhp-vf5g-r2fw
- NVD. CVE-2026-24910. https://nvd.nist.gov/vuln/detail/CVE-2026-24910
- GitHub. (2025). Strengthening npm Security: Important Changes to Authentication and Token Management. https://github.blog/changelog/2025-09-29-strengthening-npm-security-important-changes-to-authentication-and-token-management/
- GitHub. (2025). npm Classic Tokens Revoked, Session-Based Auth and CLI Token Management Now Available. https://github.blog/changelog/2025-12-09-npm-classic-tokens-revoked-session-based-auth-and-cli-token-management-now-available/
- GitHub. (2026). Staged Publishing and New Install-Time Controls for npm. https://github.blog/changelog/2026-05-22-staged-publishing-and-new-install-time-controls-for-npm/
- npm. (2026). npm CLI v12.0.0 Release Notes. https://github.com/npm/cli/releases/tag/v12.0.0
- npm. (2026). npm CLI v11.9.0 Release Notes. https://github.com/npm/cli/releases/tag/v11.9.0
- npm. Trusted Publishing for npm Packages. https://docs.npmjs.com/trusted-publishers
- pnpm. Mitigating Supply Chain Attacks. https://pnpm.io/supply-chain-security
- pnpm. (2026). pnpm 11.0. https://pnpm.io/blog/releases/11.0
- Yarn. Settings (.yarnrc.yml). https://yarnpkg.com/configuration/yarnrc
- Yarn. (2026). @yarnpkg/cli 4.14.0. https://github.com/yarnpkg/berry/releases/tag/%40yarnpkg/cli/4.14.0
- Yarn. (2026). @yarnpkg/cli 4.15.0. https://github.com/yarnpkg/berry/releases/tag/%40yarnpkg/cli/4.15.0
- Bun. bun install. https://bun.com/docs/pm/cli/install
- Bun. Add a Trusted Dependency. https://bun.com/docs/guides/install/trusted
- Packagist. (2026). Composer 2.10 Release. https://blog.packagist.com/composer-2-10-release/
- Packagist. (2026). Composer 2.11. https://blog.packagist.com/composer-2-11-release/
- GitHub. Dependabot Options Reference. https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference
- GitHub. (2026). The Case for a Cooldown: Why Dependabot Now Waits Before Issuing Version Updates. https://github.blog/security/supply-chain-security/the-case-for-a-cooldown-why-dependabot-now-waits-before-issuing-version-updates/
- GitHub. (2026). Dependabot Now Detects Malware in npm Dependencies. https://github.blog/changelog/2026-03-17-dependabot-now-detects-malware-in-npm-dependencies/
- GitHub. (2026). How We Took Malware Advisories Beyond npm. https://github.blog/security/supply-chain-security/how-we-took-malware-advisories-beyond-npm/
- GitHub. (2026). Dependabot Alerts on Malicious Packages Across More Ecosystems. https://github.blog/changelog/2026-07-28-dependabot-alerts-on-malicious-packages-across-more-ecosystems
작업 환경
- Nuxt. (2026). GHSA-648h-gw55-m2g7: Nuxt Dev Server Exposes Private Runtime Config through the Nitro Dev Bundle. https://github.com/nuxt/nuxt/security/advisories/GHSA-648h-gw55-m2g7
- GitHub. (2025). GHSA-mrrh-fwg8-r2c3: tj-actions changed-files Allows Remote Attackers to Discover Secrets by Reading Actions Logs. https://github.com/advisories/GHSA-mrrh-fwg8-r2c3
- VulnCheck. (2026). 9 Year-Old PHP Vulnerability Keeps Swinging As One of the Most Targeted Vulnerabilities. https://www.vulncheck.com/blog/cve-2017-9841
- PHPUnit. (2016). Correct Fix for #1956. https://github.com/sebastianbergmann/phpunit/commit/284a69fb88a2d0845d23f42974a583d8f59bf5a5
- Laravel. Deployment. https://laravel.com/docs/12.x/deployment
- CISA, FBI. (2024). Known Indicators of Compromise Associated with Androxgh0st Malware. https://www.cisa.gov/news-events/cybersecurity-advisories/aa24-016a
- ISMS Directory. ISO 27001:2022 Annex A Controls. https://ismsdirectory.com/iso-27001-controls
- NIST. (2020). SP 800-53 Rev. 5, AC-11 Device Lock. https://csrc.nist.gov/pubs/sp/800/53/r5/upd1/final
- MITRE. CAPEC-508: Shoulder Surfing. https://capec.mitre.org/data/definitions/508.html
- MITRE. CAPEC-406: Dumpster Diving. https://capec.mitre.org/data/definitions/406.html
- NIST. (2025). SP 800-88 Rev. 2, Guidelines for Media Sanitization. https://csrc.nist.gov/pubs/sp/800/88/r2/final
- 개인정보보호위원회. 개인정보의 안전성 확보조치 기준. https://www.law.go.kr/행정규칙/개인정보의안전성확보조치기준
- Advisera. ISO 27001 Control 8.12 Data Leakage Prevention. https://advisera.com/iso27001/control-8-12-data-leakage-prevention/
- NCSC. Small Organisations Guide: Protecting Your Devices. https://www.ncsc.gov.uk/collection/small-organisations-guide-to-cyber-security/protecting-your-devices
- TechTarget. Tailgating (Piggybacking). https://www.techtarget.com/whatis/definition/tailgating-piggybacking
- Microsoft. Manage Device Restarts after Updates. https://learn.microsoft.com/en-us/windows/deployment/update/waas-restart
- 김형국. (2025). 따뜻함 속 숨어있는 ‘화재의 그림자’. 매일신문. https://www.imaeil.com/page/view/2025121709243450016
- NIST. (2020). SP 800-53 Rev. 5, PE-11 Emergency Power. https://csrc.nist.gov/pubs/sp/800/53/r5/upd1/final
- NSA. (2021). Securing Wireless Devices in Public Settings. https://media.defense.gov/2021/Jul/29/2002815141/-1/-1/0/CSI_SECURING_WIRELESS_DEVICES_IN_PUBLIC.PDF
- Microsoft. (2025). Think Before You ClickFix: Analyzing the ClickFix Social Engineering Technique. https://www.microsoft.com/en-us/security/blog/2025/08/21/think-before-you-clickfix-analyzing-the-clickfix-social-engineering-technique
- Check Point. (2025). FileFix: The New Social Engineering Attack Building on ClickFix Tested in the Wild. https://blog.checkpoint.com/research/filefix-the-new-social-engineering-attack-building-on-clickfix-tested-in-the-wild/
- ESET. (2025). ESET H1 2025 Threat Report. https://www.eset.com/in/business/threat-report/
- Own Your Online. (2026). Social Engineering Scam ClickFix Using Websites to Spread Malware. https://www.ownyouronline.govt.nz/news-and-alerts/social-engineering-scam-clickfix-using-websites-to-spread-malware/
- Cyber Security Agency of Singapore. (2025). Ongoing ClickFix Campaign. https://www.csa.gov.sg/alerts-and-advisories/alerts/al-2025-068/
- CISA. (2023). #StopRansomware Guide. https://www.cisa.gov/stopransomware/ransomware-guide
- KISA 보호나라. (2023). 랜섬웨어 대응 가이드라인(‘23년 개정본). https://www.boho.or.kr/kr/bbs/view.do?bbsId=B0000127&menuNo=205021&nttId=71162
- 바이라인네트워크. (2023). ‘컴퓨터 끄지 마세요’…랜섬웨어 대응 가이드 낸 KISA의 조언. https://byline.network/2023/08/0803_002
- The Hacker News. (2022). QNAP Warns of DeadBolt Ransomware Targeting Internet-Facing NAS Devices. https://thehackernews.com/2022/01/qnap-warns-of-deadbolt-ransomware.html
- CISA. Data Backup Options. https://www.cisa.gov/sites/default/files/publications/data_backup_options.pdf
- NCSC. (2025). Cyber Security Culture Principles: Principle 2. https://www.ncsc.gov.uk/collection/cyber-security-culture-principles/principle-2
- NCSC. Phishing Attacks: Defending Your Organisation. https://www.ncsc.gov.uk/guidance/phishing
- Google. Site Reliability Engineering: Postmortem Culture. https://sre.google/sre-book/postmortem-culture/
- 국가정보원. (2023). 국정원, ‘챗GPT 등 생성형 AI 활용 보안 가이드라인’ 배포. https://www.nis.go.kr/CM/1_4/view.do?seq=238
- 보안뉴스. (2023). 챗GPT 등 생성형 AI의 그림자? 가이드라인 통해 본 보안 위협들. http://www.boannews.com/news/articleView.html?idxno=120359
- 국가정보원. (2025). 국가·공공기관 AI보안 가이드북. https://www.nis.go.kr/AF/1_7_7_1.do
- CIO Korea. (2025). 국정원, ‘AI 보안 가이드북’ 배포···15개 위협 및 30개 보안 대책 제시. https://www.cio.com/article/4103809/
- 개인정보보호위원회. (2025). 생성형 인공지능(AI) 개발·활용을 위한 개인정보 처리 안내서. https://www.pipc.go.kr/np/cop/bbs/selectBoardArticle.do?bbsId=BS074&mCode=C020010000&nttId=11410
- 바이라인네트워크. (2025). AI 생애주기별 개인정보 처리기준 첫 공개. https://byline.network/2025/08/6-277/
- Bloomberg. (2023). Samsung Bans Staff’s AI Use After Spotting ChatGPT Data Leak. https://www.bloomberg.com/news/articles/2023-05-02/samsung-bans-chatgpt-and-other-generative-ai-use-by-staff-after-leak
- OWASP. (2025). LLM09:2025 Misinformation. https://genai.owasp.org/llmrisk/llm092025-misinformation/
AI
- Cohere. (2026). Concerning Behavior from a Popular Open-Weight AI Model. https://cohere.com/blog/concerning-behaviour-popular-open-weight-ai-model
- Cohere Labs. (2026). Qwen 3.8 Flash Next Investigation. https://huggingface.co
- ToolHalla. (2026). Cohere Qwen3.8-Flash-Next Trace Audit. https://toolhalla.ai/blog/cohere-qwen38-flash-next-trace-audit-2026-10-27
- URL Study. Results. https://url-atlas.vercel.app/
- Digg. (2026). Qwen Upload Claim Challenged by a 130-Run Retest across Three Models. https://digg.com/ai/v0hoors2
- The Register. (2026). Alibaba’s Qwen AI Caught Trying to Contact Server in China. https://www.theregister.com/a/5305561
- CSO Online. (2026). Alibaba AI Model Tried to Send Data to Beijing Server, Cohere Says. https://www.csoonline.com/article/4240972/alibaba-ai-model-tried-to-send-data-to-beijing-server-cohere-says.html/datasets/CohereLabs/10-2026-qwen-investigation-traces
- Aikido. (2026). AIKIDO-2026-10152: @qwen-code/qwen-code Is Vulnerable to Command Injection. https://intel.aikido.dev/cve/AIKIDO-2026-10152
- QwenLM. (2026). Pull Request #1638: Prevent Command Injection via Newline Bypass in Shell Command Validation. https://github.com/QwenLM/qwen-code/pull/1638
- Aikido. (2026). AIKIDO-2026-10114: @qwen-code/qwen-code Is Vulnerable to Command Injection. https://intel.aikido.dev/cve/AIKIDO-2026-10114
- QwenLM. (2026). Pull Request #1601: Fix awk/sed Command Injection in READ_ONLY_ROOT_COMMANDS. https://github.com/QwenLM/qwen-code/pull/1601
- Qwen. Qwen Code MCP Servers. https://qwenlm.github.io/qwen-code-docs/en/users/features/mcp/
- Tracebit. (2025). Code Execution Through Deception: Gemini AI CLI Hijack. https://tracebit.com/blog/code-exec-deception-gemini-ai-cli-hijack
- Embrace The Red. (2025). GitHub Copilot Remote Code Execution via Prompt Injection. https://embracethered.com/blog/posts/2025/github-copilot-remote-code-execution-via-prompt-injection
- Anthropic. (2026). GHSA-66q4-vfjg-2qhh, GHSA-mhg7-666j-cqg4, GHSA-ff64-7w26-62rf: Claude Code Security Advisories. https://github.com/advisories/GHSA-66q4-vfjg-2qhh
- Postmark. (2025). Security Alert: Malicious ‘postmark-mcp’ npm Package Impersonating Postmark. https://postmarkapp.com/blog/information-regarding-malicious-postmark-mcp-package
- The Hacker News. (2025). First Malicious MCP Server Found Stealing Emails in Rogue Postmark-MCP Package. https://thehackernews.com/2025/09/first-malicious-mcp-server-found.html
- Phoenix Security. (2026). Bitwarden CLI Backdoored: 93-Minute npm Supply Chain Attack. https://phoenix.security/bitwarden-cli-backdoored-shai-hulud-returns-through-a-93-minute-npm-window/
- Security Boulevard. (2026). The Butlerian Jihad: Compromised Bitwarden CLI Deploys npm Worm, Poisons AI Assistants, and Dumps GitHub Secrets. https://securityboulevard.com/2026/04/the-butlerian-jihad-compromised-bitwarden-cli-deploys-npm-worm-poisons-ai-assistants-and-dumps-github-secrets
- Socket. (2026). SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains. https://socket.dev/blog/sandworm-mode-npm-worm-ai-toolchain-poisoning
- The Hacker News. (2026). Malicious npm Packages Harvest Crypto Keys, CI Secrets, and API Tokens. https://thehackernews.com/2026/02/malicious-npm-packages-harvest-crypto.html
- Google Cloud. (2026). M-Trends 2026. https://cloud.google.com/blog/topics/threat-intelligence/m-trends-2026/
- Mandiant. (2024). How Low Can You Go? An Analysis of 2023 Time-to-Exploit Trends. https://cloud.google.com/blog/topics/threat-intelligence/time-to-exploit-trends-2023
- VulnCheck. (2026). State of Exploitation 1H 2026. https://www.vulncheck.com/blog/state-of-exploitation-1h-2026
- OWASP. (2024). OWASP Top 10 for LLM Applications 2025. https://genai.owasp.org/llm-top-10/
- OWASP. (2025). OWASP Top 10 for Agentic Applications for 2026. https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/
관제와 대응
- NIST. (2024). The NIST Cybersecurity Framework (CSF) 2.0. https://doi.org/10.6028/NIST.CSWP.29
- NIST. (2024). 사이버보안 프레임워크 2.0 한국어 번역본. https://doi.org/10.6028/NIST.CSWP.29.kor
- NIST. (2020). SP 800-207 Zero Trust Architecture. https://csrc.nist.gov/pubs/sp/800/207/final
- NIST. Glossary: Defense in Depth. https://csrc.nist.gov/glossary/term/defense_in_depth
- NIST. Glossary: Least Privilege. https://csrc.nist.gov/glossary/term/least_privilege
- CISA. Known Exploited Vulnerabilities. https://www.cisa.gov/known-exploited-vulnerabilities
- CISA. KEV Data (GitHub). https://github.com/cisagov/kev-data
- FIRST. Using EPSS. https://www.first.org/epss/using-epss
- FIRST. CVSS v4.0 Specification Document. https://www.first.org/cvss/v4.0/specification-document
- FIRST. EPSS FAQ. https://www.first.org/epss/faq
- KISA 보호나라. 보안공지. https://www.boho.or.kr/kr/bbs/list.do?menuNo=205020&bbsId=B0000133
- KISA 보호나라. 침해사고 신고 안내. https://www.boho.or.kr/kr/subPage.do?menuNo=205033
- Node.js. Security Reporting. https://nodejs.org/en/about/security-reporting
- CycloneDX. Specification Overview. https://cyclonedx.org/specification/overview/
- SPDX. Overview. https://spdx.dev/about/overview/
- npm. npm-sbom. https://docs.npmjs.com/cli/v12/commands/npm-sbom
- npm. npm-audit. https://docs.npmjs.com/cli/v12/commands/npm-audit
- Composer. Command-line Interface: audit. https://getcomposer.org/doc/03-cli.md#audit
- OpenSSF. Scorecard. https://scorecard.dev/
- Falco. Falco Rules. https://github.com/falcosecurity/rules/blob/main/rules/falco_rules.yaml
- WP-CLI. wp core verify-checksums. https://developer.wordpress.org/cli/commands/core/verify-checksums/
- WP-CLI. wp plugin verify-checksums. https://developer.wordpress.org/cli/commands/plugin/verify-checksums/
- Amazon Web Services. GuardDuty Runtime Monitoring Finding Types. https://docs.aws.amazon.com/guardduty/latest/ug/findings-runtime-monitoring.html
- Wordfence. Wordfence Intelligence. https://www.wordfence.com/threat-intel/
- NSA, ASD. (2020). Detect and Prevent Web Shell Malware. https://media.defense.gov/2020/Jun/09/2002313081/-1/-1/0/CSI-DETECT-AND-PREVENT-WEB-SHELL-MALWARE-20200422.PDF
- OWASP. Logging Cheat Sheet. https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html