최신 웹 생태계에서 DOM(문서 객체 모델)은 대화형 및 동적 사용자 경험을 구현하는 데 중추적인 역할을 합니다. DOM은 웹 브라우저가 웹페이지를 로드할 때 생성하는 지도 또는 청사진이라고 생각하면 됩니다. 제목, 단락, 버튼, 이미지 등 표시되는 모든 요소는 이 계층 구조 내에서 노드로 표시됩니다. 개발자는 JavaScript를 사용하여 이 맵을 탐색하고, 요소를 변경하고, 새 요소를 추가하거나, 클릭 및 양식 제출과 같은 사용자 작업에 응답할 수 있습니다. 예를 들어 '자세히 보기' 버튼을 클릭하면 숨겨진 텍스트를 표시하도록 DOM을 수정하는 스크립트가 트리거될 수 있습니다. DOM은 대화형이며 지속적으로 업데이트되므로 정적 HTML 코드와 사용자가 경험하는 동적 동작 사이의 인터페이스 역할을 하며 우리가 당연하게 여기는 대화형 기능을 구동합니다.
그러나 이와 같은 상호 작용은 클라이언트 측 코드에 고유하게 연결된 취약점의 문을 열어줄 수 있습니다. 모의 침투 테스터나 기업 자산 방어를 담당하는 엔지니어 등 보안 전문가에게 DOM 취약점을 이해하는 것은 익스플로잇뿐만 아니라 예방을 위해서도 필수적입니다.

보안 컨텍스트에서의 DOM
보안 코딩에서는 DOM 내부에서 데이터가 어떻게 흐르는지 모니터링하는 것이 중요합니다. 공격자가 제어하는 소스(예: URL 매개변수(location.search
), 쿠키(document.cookie
) 또는 리퍼러 정보(document.referrer
) - 다음과 같이 안전하지 않은 싱크대에 주입하면 위험해질 수 있습니다. innerHTML
또는 eval()
. 소스에서 싱크까지의 사슬은 DOM 기반 취약점을 가능하게 합니다.
일반적인 DOM 취약점
취약점 유형 | 싱크 예제 | 설명 | 잠재적 영향 |
---|---|---|---|
DOM 기반 XSS | document.write()element.innerHTML | 공격자가 제어하는 데이터를 위생 처리하지 않고 HTML에 삽입하면 임의의 자바스크립트 실행이 가능합니다. | 쿠키 도용, 세션 하이재킹, 악성 콘텐츠 삽입. |
리디렉션 열기 | 창.위치 | 부적절한 URL 처리를 통해 공격자는 사용자를 악성 사이트로 리디렉션할 수 있습니다. | 피싱 공격, 멀웨어 배포, 브랜드 신뢰도 손상. |
쿠키 조작 | document.cookie | 공격자는 안전하지 않은 자바스크립트 코드를 통해 세션 쿠키를 덮어쓰거나 훔칠 수 있습니다. | 계정 탈취, 세션 하이재킹, 사칭. |
자바스크립트 주입 | eval() | 공격자가 제공한 문자열을 자바스크립트 코드로 실행합니다. | 전체 클라이언트 측 손상, 데이터 유출. |
문서 도메인 조작 | document.domain | 도메인을 변경하여 동일 출처 제한을 우회합니다. | 도메인 간 데이터 유출, 권한 에스컬레이션. |
웹소켓 URL 중독 | WebSocket() | 웹소켓 연결을 위한 악성 엔드포인트 제공. | 데이터 스트림 가로채기, 무단 작업. |
링크 조작 | element.src | 공격자는 리소스 링크를 수정하여 악성 코드를 로드하거나 데이터를 훔칩니다. | 멀웨어 삽입, 추적, 피싱 랜딩 페이지. |
웹 메시지 조작 | postMessage() | 대상 프레임/창을 조작하기 위해 조작된 메시지를 전송합니다. | 데이터 유출, 교차 출처 공격. |
Ajax 요청 헤더 조작 | 설정 요청 헤더() | 공격자는 클라이언트 측 코드에서 HTTP 요청 헤더를 제어합니다. | API 오용, CSRF 유사 익스플로잇. |
로컬 파일 경로 조작 | FileReader.readAsText() | 적절한 제한 없이 클라이언트 측 JS를 통해 로컬 파일을 읽습니다. | 민감한 로컬 데이터의 유출. |
클라이언트 측 SQL 주입 | ExecuteSql() | 비위생 처리된 데이터를 클라이언트 측 DB 쿼리에 전달합니다. | 데이터 도용, DB 조작. |
HTML5 스토리지 조작 | 세션스토리지.setItem() / localStorage.setItem() | 나중에 실행할 수 있도록 브라우저 저장소에 악성 페이로드를 저장합니다. | 지속적인 XSS, 무단 클라이언트 데이터 액세스. |
클라이언트 측 XPath 주입 | document.evaluate() | XPath 쿼리에 주입하면 공격자가 XML 데이터에 액세스할 수 있습니다. | 데이터 유출, 조작 XML 기반 앱 로직. |
클라이언트 측 JSON 주입 | JSON.parse() | 신뢰할 수 없는 소스에서 변조된 JSON을 구문 분석하면 임의의 객체 삽입이 가능합니다. | 데이터 덮어쓰기, 논리 조작. |
DOM 데이터 조작 | element.setAttribute() | 신뢰할 수 없는 데이터로 속성을 설정하면 악의적인 동작을 유발할 수 있습니다. | XSS, 클릭재킹, 로직 우회. |
서비스 거부(DoS) | RegExp() | 크기가 크거나 악의적인 정규식 패턴은 브라우저를 정지시킵니다. | 애플리케이션 다운타임, 성능 저하. |
DOM 취약점이 발견되는 방법
보안팀은 일반적으로 여러 가지 전략을 혼합하여 사용합니다.
- 활성 스캔Burp Suite 또는 OWASP ZAP과 같은 도구를 사용하여 테스터는 안전하지 않은 DOM 상호 작용을 시뮬레이션하고 관찰할 수 있습니다.
- 수동 검색 는 쇼단, 줌아이, PublicWWW와 같은 리소스나 웨이백 머신의 기록 스냅샷을 통해 DOM 계층에 숨겨진 민감한 데이터를 찾아내는 작업을 포함합니다.
- 자동화된 정규식 및 AI 분석, 는 알려진 자격 증명에 대한 패턴 매칭과 소스 → 싱크 흐름을 매핑하는 AI 기반 분석을 결합하여 탐지와 해결 사이의 시간을 획기적으로 단축합니다.
DOM 취약점 방어하기
강력한 방어는 신뢰할 수 있는 데이터만 DOM에 도달하도록 하기 위해 화이트리스트를 통한 체계적인 입력 유효성 검사에서 시작됩니다.
인코딩 전략은 상황에 맞게 조정해야 합니다: 페이지 출력을 위한 HTML 인코딩, 스크립트 삽입 지점을 위한 JavaScript 이스케이프, 링크 구성을 위한 URL 인코딩 등이 있습니다.
API 키가 프런트엔드 코드에 반드시 표시되어야 하는 경우 리퍼러 및 출처 확인, IP 제한 및 속도 제한을 사용하여 잠궈야 합니다.
팀은 배포 직전에 DOM 검토를 수행하여 비밀 및 안전하지 않은 코드를 제거하고, 보관된 스냅샷에서도 노출된 적이 있는 모든 자격 증명을 취소해야 합니다.

펜리전트로 DOM 보안 강화하기
기존에는 철저한 DOM 보안 감사를 실행하려면 검색을 위한 Nmap, 인젝션 테스트를 위한 Burp Suite, 익스플로잇을 위한 SQLmap 등 수많은 도구를 조합한 다음 각 발견 사항을 수동으로 검토하여 정확성을 확인해야 했습니다.
펜리전트는 테스터가 일반 영어로 목표를 설명할 수 있도록 하여 이러한 문제를 해결합니다. "이 웹사이트의 DOM 취약점을 검사해 주세요"와 같은 요청은 지능형 워크플로우를 트리거합니다. AI는 Nmap, Burp Suite를 비롯한 200개 이상의 보안 도구를 통합합니다, SQLmap등을 사용하여 잠재적인 소스 → 싱크 체인에 대한 타겟 스캔을 수행하고, 각 발견 사항을 검증하여 오탐을 제거하고, 심각도별로 순위를 매깁니다. 숙련된 보안 전문가와 초보자 모두 며칠이 걸리는 수작업 마라톤에서 몇 시간 또는 몇 분 만에 완료되는 간소화된 고도로 정확한 프로세스로 DOM 감사를 전환할 수 있습니다.