PoCs

공격 목록은 이전되지 않는다 — 이전되는 것은 신뢰 경계다

이 목록의 카드 여섯 장이 **이름 없이 이미 같은 수**를 뒀습니다 — **인가받았는가가 아니라 어디까지 닿는가.** **그 수가 공부할 단위**이고, **공격 목록은 그 방법의 커리큘럼이 아니라 산출물**입니다.

아직 만들지 않았습니다

이 페이지는 카드에 적힌 내용을 펼쳐 보여줄 뿐입니다 — 돌아가는 코드도, 열어볼 데모도 아직 없습니다. 무엇을 왜 만들려는지가 아래에 있습니다.

어떻게 보나

아직 범위 미정이고, **1차 결과물은 체크리스트가 아니라 그림**입니다. 이 저장소의 시스템 하나에 대해 **경계 안과 밖을 그리고**, **무언가가 넘어오는 모든 지점**을 표시합니다 — 요청, 스크립트, 라이브러리, 웹훅, 협력사, 콘솔을 쥔 사람. 넘어오는 지점마다 **두 가지**를 적습니다: **오늘 허용된 일**, 그리고 **오늘 오후에 적대적으로 돌아서면 할 수 있는 일.** **그다음에야** 공격 목록을 읽되, **교과과정이 아니라 그림에 대한 커버리지 시험**으로 씁니다. 각 항목은 **내가 그린 넘어오는 지점에 떨어지거나**(그러면 확인할 통제가 정해집니다) **떨어지지 못합니다**(그러면 이 시스템과 무관하거나 **경계를 하나 빠뜨린 것**입니다). **둘 다 가질 값어치가 있고, 목록을 먼저 공부한 사람에게는 둘 다 없습니다.**

기술 노트

각 항목이 실제로 무엇을 보여주고 어떻게 동작하는지 — 위 카드보다 자세한 기술 설명입니다.

공격 목록은 이전되지 않는다 — 이전되는 것은 신뢰 경계다준비 중

목적: **보안은 보통 목록으로 가르쳐지는데, 목록은 이 주제에 맞는 모양이 아닙니다.** 목록은 실재하고 알 값어치가 있지만 **사례의 카탈로그**이고, **사례는 낡습니다** — 한 시대를 지배한 취약점 부류가 다음 시대에는 **해결된 기본 설정값**입니다. 낡지 않는 것은 **모든 항목 아래 있는 질문**이고, 그건 언제나 같은 것의 변형입니다 — **누군가가 선이라고 믿었던 선을 무언가가 넘었다.** **마침 이 카탈로그가 그 증거를 갖고 있어서, 이 주장은 그냥 경구가 아닙니다.** 서로 무관한 이유로 쓰인 카드 여섯 장이 **똑같은 수**를 뒀습니다. `third-party-blast-radius` 는 **프론트엔드 둘레에 그린 경계가 그 프론트엔드가 불러오는 스크립트의 공급사를 제외하고 있었고**, 반사적으로 집는 통제들이 **엉뚱한 질문에 답한다**는 것을 찾았습니다 — **그 스크립트는 인가돼 있었으니까요.** `storage-collision-admin-takeover` 는 **같은 스토리지 슬롯을 각자 자기 것이라 믿은 두 모듈**을 찾았습니다. `pick-a-signer-not-a-brand` 는 **브랜드 하나가 네 개의 공급망**이고 **감사받는 건 그중 하나뿐**임을 찾았습니다. `what-encryption-does-not-hide` 는 **금액을 가려도 그래프가 남는다**는 것을. `huggingface-is-a-package-manager` 는 **로딩 옵션이 실행 허가**라는 것을. `demonstration-is-not-a-specification` 은 **어시스턴트에게 작업을 보여주는 것이 화면 전체를 보여주는 것**임을. **여섯 개의 다른 주제, 하나의 수, 그리고 그중 어느 것도 취약점 목록이 필요하지 않았습니다.** **평범하게 말하면, 방법은 순서가 있는 질문 둘입니다.** 첫째, **경계가 어디인가, 안은 무엇이고 밖은 무엇이며, 누가 정하는가.** 둘째, **무엇이 그것을 넘고, 넘은 그것은 넘은 뒤에 무엇을 할 수 있는가.** 실제 발견의 거의 전부가 **첫 질문을 대충 답한 뒤 둘째 질문을 꼼꼼히 답한 결과**이고, 대충 답한 것이 그토록 오래 살아남는 이유는 하나입니다 — **사람들이 실제로 돌리는 검사인 "인가됐는가"는 공격이 일어나는 바로 그 순간에 예 라고 답하기 때문입니다.** 공급사는 허용 목록에 있었고, 모듈은 의도적으로 배포됐고, 플래그는 그것이 필요했던 사람이 켰습니다. **이 카드의 정직한 한계는, 외워야 하는 것도 있다는 점입니다.** 아니라고 하면 반대 방향의 같은 오류입니다. **인가됨과 안전함이 갈라지는 자리는 작고 반복되는 집합**이고, **우연이 아니라 구조적이라서** 이름으로 알아둘 값어치가 있습니다: **데이터로 도착한 것을 코드로 실행하는 모든 것**, **남의 스토리지나 메모리 문맥에서 도는 모든 것**, **신뢰할 수 없는 입력을 역직렬화하는 모든 것**, **템플릿이나 표현식을 평가하는 모든 것**, 그리고 **호출자를 대신해 내 서버가 보내는 모든 요청**(내 서버는 경계 안에 있고 호출자는 밖에 있으니까). **이건 버그가 아니라 모양이고**, **경계 그림 + 이 짧은 목록**이 **긴 목록 하나보다 넓은 땅을 덮습니다.** **마지막으로, 편한 방식 대신 이렇게 공부할 이유.** **목록은 덮었다는 느낌을 주고 확인할 방법을 주지 않습니다.** **경계 그림은 반증 가능합니다** — 누군가 그것을 가리키며 **선이 틀린 자리에 있다**거나 **넘어오는 지점이 빠졌다**고 말할 수 있고, 그 논쟁은 **체크리스트를 비교하는 것과 달리 생산적입니다.** **보안 공부의 산출물은 남이 종이 위에서 공격해 볼 수 있는 물건이어야 하고**, 공격 이름 목록은 그 물건이 아닙니다.

동작 방식: ### 카드 여섯 장, 하나의 수 | 카드 | 가정된 경계 | 실제로 넘어온 것 | |---|---|---| | `third-party-blast-radius` | "우리 프론트엔드" | **공급사 자신의 인프라에서 온 공급사 스크립트** — 그래서 SRI·CSP 둘 다 통과 | | `storage-collision-admin-takeover` | "각 모듈이 자기 상태를 소유한다" | **모듈 둘, 슬롯 하나, 의미 둘** | | `pick-a-signer-not-a-brand` | "그 기기" | 엔트로피 경로, 체인별 앱, **배송 위탁사** | | `what-encryption-does-not-hide` | "비밀은 금액이다" | **누가 누구에게 언제 보냈는가의 그래프** | | `huggingface-is-a-package-manager` | "모델을 불러온다" | **`trust_remote_code` 가 내 프로세스에서 저장소 코드를 실행** | | `demonstration-is-not-a-specification` | "작업을 본다" | **화면을 본다** | **이 중 어느 것도 취약점 목록을 뒤져서 찾은 것이 아니고**, 그게 논거입니다. **선이 어디인지, 그 너머에 무엇이 있는지 물어서** 찾았습니다. ### 질문 둘, 그리고 흔한 질문이 실패하는 이유 | 질문 | 무엇을 잡나 | 왜 부족한가 | |---|---|---| | **"인가됐는가?"** | 비인가 접근 | **공격 중에 예 라고 답합니다.** 공급사는 허용 목록에 있었고 플래그는 **의도적으로** 켜졌습니다 | | **"경계가 어디인가?"** | **너무 작게 그려진 경계** | 두 번째 질문이 있어야 행동 가능해짐 | | **"어디까지 닿는가?"** | **인가된 구성요소의 폭발 반경** | **발견을 만들어내는 것은 이 질문** | ### 그래도 외워야 하는 짧은 목록 경계 사고가 방법이지만, **이름으로 알아둘 만큼 자주 반복되는 모양**이 몇 개 있습니다 — 전부 **인가됨과 안전함이 갈라지는 자리**입니다: - **데이터로 도착해서 실행되는 코드** — `trust_remote_code`, 플러그인 로더, 동적 임포트 - **남의 문맥에서 도는 것** — delegatecall, 공유 스토리지, 주입된 스크립트 - **신뢰할 수 없는 입력의 역직렬화** — **객체 그래프가 곧 프로그램** - **템플릿·표현식 평가** — **인터프리터가 곧 취약점** - **호출자를 대신해 내 서버가 보내는 요청** — **내 서버는 경계 안, 호출자는 밖** **이건 버그가 아니라 모양이고**, 그래서 **특정 취약점 이름을 은퇴시키는 물갈이에도 살아남습니다.** ### 공부 순서 1. **내가 소유한 시스템 하나의 경계를 그립니다.** 안, 밖, 그리고 **넘어오는 모든 지점.** 2. **넘어오는 지점마다 오늘 적대적으로 돌아서면 할 수 있는 일을 씁니다.** **출처가 아니라 권한** — `third-party-blast-radius` 가 인벤토리 전체를 세우는 문장입니다. 3. **그다음 공격 목록을 커버리지 시험으로 읽습니다.** 지점에 떨어지는 항목은 **확인할 통제**를 알려주고, 떨어지지 못하는 항목은 **여기서 무관하거나 내가 경계를 빠뜨린 것**입니다. **순서의 이유는, 목록 먼저는 암기를 만들고 모델 먼저는 필터를 만들기 때문**입니다. 그리고 **아직 아무도 목록을 써 주지 않은 시스템에서도 작동하는 것은 둘 중 하나뿐입니다.**