탐지 모델
Dalfox의 결과는 서로 독립적인 세 서브시스템에서 나옵니다. 같은 터미널에 비슷한 모양으로 출력되지만, 읽는 입력도 판단 방식도 다릅니다. 그래서 한쪽을 끄는 플래그가 다른 쪽에는 아무 영향을 주지 않습니다.
이 페이지는 그 구분이 출력만 봐서는 드러나지 않기 때문에 존재합니다. 이슈 #1238에서 @OSTARA711이 정리한 내용을 토대로 작성했습니다.
세 가지 서브시스템
1. 파라미터 마이닝 — 테스트할 이름 찾기
응답의 HTML 구조를 읽어 폼과 입력 요소의 id, name 속성에서 파라미터 이름 후보를 수집하고, 사전 워드리스트도 함께 사용합니다. 직접 파라미터를 지정하지 않았을 때 테스트할 목록을 넓히는 것이 유일한 역할입니다.
| 플래그 | 효과 |
|---|---|
--skip-mining |
모든 마이닝을 건너뜁니다 |
--skip-mining-dict |
사전 워드리스트만 |
--skip-mining-dom |
HTML id/name 수집만 |
이름과 달리 --skip-mining-dom은 DOM-XSS 탐지와 무관합니다. 여기서 "DOM"은 취약점 종류가 아니라 이름을 어디서 가져오는지를 가리킵니다.
2. AST 분석 — 자바스크립트 읽기
응답에 담긴 자바스크립트 소스를 추상 구문 트리로 파싱해, 위험한 소스(location.hash, location.search, document.referrer, postMessage 등)에서 온 데이터가 살균 없이 위험한 싱크(innerHTML, document.write, eval 등)에 도달하는지 추적합니다. [A] 결과를 만드는 것이 이 단계입니다.
이 패스는 항상 켜져 있고 --skip-ast-analysis가 제어합니다. 파라미터 단위로 동작하지 않습니다. 각 <script> 블록을 한 번 읽고 발견한 모든 소스→싱크 경로를 보고하므로, 명령줄에 넘기지 않은 입력이 결과에 등장할 수 있습니다. 서버로 전송조차 되지 않는 URL 프래그먼트도 여기에 포함됩니다. -p로 범위를 좁혀도 달라지지 않는데, -p는 어떤 파라미터를 요청할지를 정하는 옵션이고 이 서브시스템은 파라미터별 요청을 보내지 않기 때문입니다.
| 플래그 | 효과 |
|---|---|
--skip-ast-analysis |
소스→싱크 분석을 끕니다 ([A] 억제) |
--analyze-external-js |
동일 출처 <script src> 번들도 가져와 분석합니다 |
3. 반사 및 DOM 검증 — 페이로드 전송
전통적인 능동 파이프라인입니다. 파라미터에 페이로드를 주입해 요청을 보내고 돌아온 응답을 확인합니다. 응답 본문에 페이로드가 보이기만 하면 [R], 응답이 파싱되어 실제 DOM 요소로 만들어지면(dalfox의 class=dlx… 마커를 CSS 셀렉터로 매칭) [V]입니다.
증거 등급
| 태그 | 의미 | 생성 주체 |
|---|---|---|
[V] |
파싱된 응답에서 페이로드가 실제 요소로 발견됨, 또는 실행 가능한 스킴이 위험한 속성에 들어감 | 반사 + DOM 검증 |
[A] |
페이지 자바스크립트에서 살균되지 않은 소스→싱크 흐름을 정적으로 발견 | AST 분석 |
[R] |
페이로드가 응답 본문에 돌아왔으나 DOM 증거는 없음 | 반사 |
[I] |
정보성. 악용 가능한 XSS가 아님 (예: 알려진 취약 JS 라이브러리, CWE-1104) | 라이브러리 탐지 (--detect-outdated-libs) |
--only-poc로 필터링합니다 (예: --only-poc v,a).
[V]가 뜻하지 않는 것
[V]는 브라우저 실행이 아닙니다. Dalfox에는 헤드리스 브라우저도 CDP 클라이언트도 없습니다. 페이지를 렌더링하거나 alert()가 실제로 뜨는 것을 관찰하지 않습니다. [V]는 실제 HTTP 응답으로 만든 DOM 트리에서 페이로드를 찾았다는 뜻입니다. 여전히 정적 분석이며, [R]의 단순 문자열 매칭보다 강한 증거일 뿐입니다.
여기엔 순수 클라이언트 사이드 DOM-XSS에 대한 구체적인 결과가 따릅니다. 페이로드는 런타임에 자바스크립트가 페이지에 써 넣으므로 서버 응답에는 절대 나타나지 않고, DOM 검증이 찾을 대상 자체가 없습니다. location.hash → innerHTML만 취약한 정적 페이지라면 dalfox가 도달할 수 있는 최상위 등급은 [A]이며, --only-poc v는 아무것도 반환하지 않는 것이 정상입니다.
즉 [A]는 확인된 익스플로잇이 아니라 확인해 볼 단서입니다. 브라우저에서 devtools를 켜고 POC URL을 열어 검증하세요. dalfox는 모든 [A] 결과에 완성된 POC URL을 출력하며, URL에 담을 수 없는 소스(window.name, document.referrer, 쿠키, postMessage 등)에는 [manual POC: …] 재현 힌트를 붙입니다.
세 가지가 섞인 출력 읽기
INF found reflected 0 params
WRN XSS found 0 XSS (+3 A)
[POC][A][GET][DOM-XSS] https://target.app/?q=%3Cimg+src%3Dx+onerror%3D…
├── Issue: DOM-based XSS via URLSearchParams.get(q) to innerHTML (needs runtime confirmation)
└── Payload: q=<img src=x onerror=alert(1) class=dlx1944740c>
found reflected 0 params— 반사 엔진이 서버 측 반사를 찾지 못했다는 뜻입니다. 정적 사이트에서는 당연한 결과입니다.XSS found 0 XSS— 대표 숫자는[V]만 셉니다.(+3 A)가 아래에 출력될 나머지 등급을 알려줍니다.[A]블록은 위 두 줄과 무관하게 AST 분석에서 나옵니다.
DOM-XSS 대상에서 요약 줄만 읽고 멈추면 보고서의 모든 결과를 놓치게 됩니다.
목적별 플래그 선택
| 목적 | 플래그 |
|---|---|
| dalfox가 직접 확인한 결과만 보기 | --only-poc v |
| 운영 중인 대상에서 정적 분석 노이즈 억제 | --skip-ast-analysis |
| 이름 수집만 끄고 DOM-XSS 탐지는 유지 | --skip-mining-dom |
| 파라미터 하나만 테스트하되 모든 DOM 싱크는 확인 | -p q ([A]는 -p 범위를 따르지 않습니다) |