**Document Object Model (DOM)**은 브라우저가 HTML 문서를 관리하기 위해 사용하는 객체 모델이다. 웹 개발자는 DOM에 이벤트 핸들러를 추가하거나 DOM을 변경하는 방식으로 웹 페이지를 수정하는 것이 가능하다.
DOM은 자바스크립트에서 접근할 수 있도록 각종 API를 제공해 개발자에겐 굉장히 편리한 기능이다. 반면에, 이를 잘못 사용할 경우, XSS나 개발자가 의도한 동작과 다르게 동작시킬 수 있는 취약점이 발생할 수 있다.
**Document Object Model (DOM, 문서 객체 모델)**이란, 웹 페이지에 대한 프로그래밍 인터페이스이다. 웹 개발자가 작성한 웹 문서는 브라우저에서 파싱되어 DOM으로 표현된다. 자바스크립트가 웹 문서에 접근할 때에는 DOM을 통해 접근하게 되며, 일반적으로 DOM에서 제공하는 API를 이용한다.
DOM 내에서 웹 개발자가 작성한 HTML 문서는 트리 형태가 되어 노드로 표현된다. 그리고 해당 노드들은 자바스크립트에서 접근할 수 있게 된다.
아래는 자바스크립트에서 DOM에 존재하는 Element의 내용을 수정하고, 새로운 Element를 생성하는 예제 코드이다.
var elem = document.getElementById("name");
elem.innerText = "My name is dream";
var div_elem = document.createElement("div");
var text_node = document.createTextNode("Welcome to dreamhack");
div_elem.appendChild(text_node);
document.getElementById 함수를 이용해 미리 정의되어 있던 name이라는 id의 Element를 가져와 innerText를 변경해 실제 웹 문서의 내용을 변경할 수 있다.
또한, document.createElement 함수로 새로운 Element를 생성하는 것도 가능하며, document.createTextNode 함수를 이용해 텍스트 노드를 생성하고, Element에 추가하여 웹 문서에 새로운 내용을 추가할 수 있다.
DOM Clobbering은 id, name 등 HTML에서 이용되는 식별자 속성을 이용해 자바스크립트에서 접근 가능한 DOM 객체들의 속성 및 메소드 등을 변조하는 기법이다.
기존 브라우저는 스크립트 작성자의 편의를 위해 DOM 노드 (element 등)에서 자식 노드에 직접 접근할 수 있도록 해왔다. 웹 프로그래밍을 공부하다 보면 document.getElementById()를 사용하지 않고도 노드 id를 변수처럼 사용할 수 있음을 알게되는데, Window 전역 객체는 자바스크립트 Proxy와 유사한 형태로 구현되어 있어 정의되지 않은 속성은 DOM에서 찾게 된다.
예를 들어 DOM 내에 <a id="link1" href="<https://host>">host</a> element가 정의되어 있을 때, 자바스크립트에서 별도 변수 정의 없이 link1에 접근하면 해당 요소를 DOM에서 찾는다.
아래는 HTML에 link1이라는 id를 가진 a 태그가 존재할 때, 자바스크립트에서 바로 link1 노드에 접근하는 모습이다.

link1 변수

DOM Clobbering을 이용한 요소 접근 1