DOM-based vulnerabilities

DOM-based vulnerabilities

in

DOM-based vulnerabilities

๐Ÿ”Ž What is DOM?

DOM(Document Object Model)์€ HTML, XML๊ณผ ๊ฐ™์€ ๋งˆํฌ์—… ์–ธ์–ด๋ฅผ ๊ฐ์ฒด ๋ชจ๋ธ(ํŠธ๋ฆฌ ๋…ธ๋“œ)๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ Javascript, Java์™€ ๊ฐ™์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋ฉฐ, ์›น ๋ธŒ๋ผ์šฐ์ €์— ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค ์ž…๋‹ˆ๋‹ค.

์›น ๋ธŒ๋ผ์šฐ์ € ๋™์ž‘ ์›๋ฆฌ

์ด๋ฏธ์ง€ 1

1. ์‚ฌ์šฉ์ž๊ฐ€ ์›นํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•˜๋ฉด ์„œ๋ฒ„๋Š” HTML, CSS, JavaScript๋“ฑ์˜ ๋ฌธ์„œ๋“ค์„ ๋ธŒ๋ผ์šฐ์ €๋กœ ์‘๋‹ตํ•œ๋‹ค.
2. ์ด๋•Œ ๋ Œ๋”๋ง ์—”์ง„์€ ์‘๋‹ต๋ฐ›์€ ๋ฌธ์„œ๋“ค์„ ํŒŒ์‹ฑํ•œ ๋’ค ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋‘ ๋ชจ๋ธ์ด ๋ฐ”๋กœ DOM(Document Object Model)๊ณผ CSSOM(Cascading Style Sheets Object Model)์ด๋‹ค. ๋ Œ๋”๋ง ์—”์ง„์€ HTML๊ณผ CSS๋ฅผ ํŒŒ์‹ฑํ•˜์—ฌ ๊ฐ๊ฐ DOM tree์™€ CSSOM tree๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
3. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋ Œ๋”๋ง ์—”์ง„์ด ์•„๋‹Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—”์ง„์— ์˜ํ•ด ํŒŒ์‹ฑ๋œ๋‹ค. ํŒŒ์‹ฑํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋…ธ๋“œ ํŠธ๋ฆฌ์— ์ ์šฉํ•œ๋‹ค.
4. ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ Œ๋” ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
5. ์ด๋ ‡๊ฒŒ ์ƒ์„ฑ๋œ ๋ Œ๋” ํŠธ๋ฆฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์›น ๋ธŒ๋ผ์šฐ์ €๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ํŽ˜์ด์ง€์— ๋ Œ๋”๋งํ•œ๋‹ค.

๋ Œ๋”๋ง ์—”์ง„์ด ๋ธŒ๋ผ์šฐ์ €์— ๋ Œ๋”๋ง ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ์ด ๊ณผ์ •์„ CRP(Critical Rendering Path)๋ผ๊ณ  ํ•œ๋‹ค.
๋ Œ๋”๋ง ์—”์ง„์ด HTML ๋ฌธ์„œ๋ฅผ ํŒŒ์‹ฑํ•˜๊ณ  ํƒœ๊ทธ๋“ค์„ DOM tree๋กœ ๋ณ€ํ™˜์‹œํ‚ค๋Š” ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

<html>
<head>
  <title>Understanding the Critical Rendering Path</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header>
      <h1>Understanding the Critical Rendering Path</h1>
  </header>
  <main>
      <h2>Introduction</h2>
      <p>Lorem ipsum dolor sit amet</p>
  </main>
  <footer>
      <small>Copyright 2017</small>
  </footer>
</body>
</html>

์œ„์™€ ๊ฐ™์€ ํƒœ๊ทธ ๊ตฌ์กฐ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์€ tree node๋กœ ๋ณ€ํ™˜์‹œํ‚จ๋‹ค.

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2021-12-04 แ„‹แ…ฉแ„’แ…ฎ 12 15 19 DOM

์œ„์™€ ๊ฐ™์€ ๊ตฌ์กฐ์˜ ํŠธ๋ฆฌ๋…ธ๋“œ๋ฅผ DOM์ด๋ผ๊ณ  ํ•œ๋‹ค.

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2021-12-04 แ„‹แ…ฉแ„’แ…ฎ 12 16 35 CSSOM

CSSOM๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํŠธ๋ฆฌ๋…ธ๋“œ๋กœ ํ‘œํ˜„๋˜๋ฉฐ, DOM, CSSOM, Javascript๋ฅผ ๋ชจ๋‘ ํ•ฉ์นœ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐ”๋กœ ๋ Œ๋” ํŠธ๋ฆฌ์ด๋‹ค.


๐Ÿ”Ž What is taint flow?

๋งŽ์€ DOM ๊ธฐ๋ฐ˜ ์ทจ์•ฝ์ ์€ ํด๋ผ์ด์–ธํŠธ ์ธก ์ฝ”๋“œ๊ฐ€ ๊ณต๊ฒฉ์ž๊ฐ€ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๊ด€๋ จ๋œ ๋ฌธ์ œ๋กœ ์—ญ์ถ”์  ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋Ÿฌํ•œ ์ทจ์•ฝ์ ์„ ์•…์šฉํ•˜๊ฑฐ๋‚˜ ์™„ํ™”ํ•˜๋ ค๋ฉด ๋จผ์ € Source์™€ Sink ๊ฐ„์˜ ํ๋ฆ„์— ๋Œ€ํ•œ ๊ธฐ๋ณธ์‚ฌํ•ญ์„ ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Source

Source๋Š” ์ž ์žฌ์ ์œผ๋กœ ๊ณต๊ฒฉ์ž๊ฐ€ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํ—ˆ์šฉํ•˜๋Š” JavaScript ์†์„ฑ์ž…๋‹ˆ๋‹ค.
Source์˜ ์˜ˆ๋กœ๋Š” location.search ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด์—์„œ ์ž…๋ ฅ์„ ์ฝ๊ธฐ ๋•Œ๋ฌธ์— ๊ณต๊ฒฉ์ž ์ž…์žฅ์—์„œ ๋น„๊ต์  ์‰ฝ๊ฒŒ ์ปจํŠธ๋กคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ถ๊ทน์ ์œผ๋กœ ๋ชจ๋“  ์žฌ์‚ฐ์€ ๊ณต๊ฒฉ์ž์˜ ์ž ์žฌ์ ์ธ ์†Œ์Šค์— ์˜ํ•ด ์ปจํŠธ๋กค ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” referring URL(eocument.referrer ๋ฌธ์ž์—ด์— ๋…ธ์ถœ),์œ ์ € ์ฟ ํ‚ค(document.cookie ๋ฌธ์ž์—ด์— ๋…ธ์ถœ), ์›น ๋ฉ”์‹œ์ง€๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

Sinks

Sink๋Š” ์ž ์žฌ์ ์œผ๋กœ ์œ„ํ—˜ํ•œ JavaScriptํ•จ์ˆ˜ ๋˜๋Š” DOM ๊ฐœ์ฑ„๋กœ, ๊ณต๊ฒฉ์ž๊ฐ€ ์ปจํŠธ๋กคํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ „๋‹ฌ๋  ๊ฒฝ์šฐ ์›ํ•˜์ง€ ์•Š๋Š” ์˜ํ–ฅ์„ ๋ผ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด eval() ํ•จ์ˆ˜๋Š” JavaScript๋กœ ์ „๋‹ฌ๋˜๋Š” ์ธ์ˆ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— Sink์ž…๋‹ˆ๋‹ค.
HTML sink์˜ ์˜ˆ๋กœ๋Š” ๊ณต๊ฒฉ์ž๊ฐ€ ์•…์˜์ ์ธ HTML์„ ์ฃผ์ž…ํ•˜๊ณ  JavScript๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” document.body.innerHTML๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ DOM ๊ธฐ๋ฐ˜ ์ทจ์•ฝ์ ์€ ์›น ์‚ฌ์ดํŠธ๊ฐ€ Source์—์„œ Sink๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋ฉฐ, Sink๋Š” ํด๋ผ๋ฆฌ์–ธํŠธ ์„ธ์…˜์˜ ์ปจํ…์ŠคํŠธ์—์„œ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์†Œ์Šค๋Š” location ๊ฐœ์ฑ„์™€ ํ•จ๊ป˜ ์•ก์„ธ์Šค๋˜๋Š” URL์ž…๋‹ˆ๋‹ค.

goto = location.hash.slice(1)
if (goto.startsWith('https:')) {
  location = goto;
}

Source๊ฐ€ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ์ฝ”๋“œ๋Š” DOM ๊ธฐ๋ฐ˜ Open Redirection์— ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค.
ํ•ด๋‹น ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด URL์„ ๊ตฌ์„ฑํ•˜์—ฌ ์ทจ์•ฝ์ ์„ ์•…์šฉํ•˜์—ฌ ํ”ผํ•ด์ž๊ฐ€ ํ•ด๋‹น URL์„ ๋ฐฉ๋ฌธํ•˜๋ฉด JavaScript๋Š” location ์†์„ฑ ๊ฐ’์„ https://www.evil-user.net ์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ํ”ผํ•ด์ž๋ฅผ ๋ฆฌ๋‹ค์ด๋ ‰์…˜ ํ•ฉ๋‹ˆ๋‹ค.

https://www.innocent-website.com/example#https://www.evil-user.net
  • Common sources

taint-flow์— ์ทจ์•ฝ์ ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ผ๋ฐ˜์ ์ธ ์†Œ์Šค์ž…๋‹ˆ๋‹ค.

document.URL
document.documentURI
document.URLUnencoded
document.baseURI
location
document.cookie
document.referrer
window.name
history.pushState
history.replaceState
localStorage
sessionStorage
IndexedDB (mozIndexedDB, webkitIndexedDB, msIndexedDB)
Database

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ข…๋ฅ˜์˜ ๋ฐ์ดํ„ฐ๋„ taint-flow ์ทจ์•ฝ์ ์„ ์•…์šฉํ•˜๋Š” ์†Œ์Šค๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Reflected DOM XSS

์ด๋ฏธ์ง€ 1 JSON ์‘๋‹ต ํŽ˜์ด์ง€

ํ•ด๋‹น js์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ ์ฐพ์•„ ์†Œ์Šค์ฝ”๋“œ ๋ถ„์„ ๊ฒฐ๊ณผ eval์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์„ ํ™•์ธ

์ด๋ฏธ์ง€ 3 eval ํ•จ์ˆ˜ ์‚ฌ์šฉ

๋ฐฑ์Šฌ๋ž˜์‹œ๋ฅผ ์‚ฝ์ž… ์‹œ ์‚ฌ์ดํŠธ์—์„œ ํ•„ํ„ฐ๋ง ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š”๊ฒƒ์„ ํ™•์ธ ํ›„ \"-alert(1)}// ๊ณต๊ฒฉ๊ตฌ๋ฌธ์„ ์ž…๋ ฅํ•˜์—ฌ XSS ๋ฐœ์ƒ

//ํŽ˜์ด๋กœ๋“œ ์ž…๋ ฅ์‹œ ์ž…๋ ฅ๋˜์–ด ๋“ค์–ด๊ฐ€์ง€๋Š”๊ฐ’

{"results":[], 
"searchTerm":"\\"-alert(1)}//" }

์ด๋ฏธ์ง€ 4 XSS ๋ฐœ์ƒ

Stored DOM XSS

ํ•ด๋‹น ์›น์‚ฌ์ดํŠธ๋Š” XSS๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด JavaScript replace()๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊บพ์‡  ๊ด„ํ˜ธ๋ฅผ ์ธ์ฝ”๋”ฉํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ ๋ฌธ์ž์—ด์ธ ๊ฒฝ์šฐ ํ•จ์ˆ˜๋Š” ์ฒซ๋ฒˆ์งธ ํ•ญ๋ชฉ๋งŒ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์„ ์‹œ์ž‘ ๋ถ€๋ถ„์— ์ถ”๊ฐ€ ๊บพ์‡  ๊ด„ํ˜ธ ์„ธํŠธ๋ฅผ ํฌํ•จํ•˜์—ฌ ์ทจ์•ฝ์ ์„ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊บพ์‡  ๊ด„ํ˜ธ๋Š” ์ธ์ฝ”๋”ฉ ๋˜์ง€๋งŒ ์ดํ›„์˜ ๋ชจ๋“  ๊บพ์‡  ๊ด„ํ˜ธ๋Š” ์˜ํ–ฅ์„ ๋น‹์ง€ ์•Š์œผ๋ฏ€๋กœ ํ•„ํ„ฐ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<><img src=1 onerror=alert(1)>

์ด๋ฏธ์ง€ 5 ํŽ˜์ด๋กœ๋“œ ์ž…๋ ฅ

์ด๋ฏธ์ง€ 6 Stored XSS


  • Lead to DOM-based vulnerabilities sinks

DOM-based vulnerabilityExample sink
DOM XSSdocument.write()
Open redirectionwindow.location
Cookie manipulationdocument.cookie
JavaScript injectioneval()
Document-domain manipulationdocument.domain
WebSocket-URL poisoningWebSocket()
Link manipulationelement.src
Web message manipulation postMessage()
Ajax request-header manipulationsetRequestHeader()
Local file-path manipulationFileReader.readAsText()
Client-side SQL injectionExecuteSql()
HTML5-storage manipulationsessionStorage.setItem()
Client-side XPath injectiondocument.evaluate()
Client-side JSON injectionJSON.parse()
DOM-data manipulationelement.setAttribute()
Denial of serviceRegExp()



๐Ÿ‘€ How to Prevent ?

DOM ๊ธฐ๋ฐ˜ ๊ณต๊ฒฉ์˜ ์œ„ํ˜‘์„ ์™„์ „ํžˆ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ์ทจํ•  ์ˆ˜ ์žˆ๋Š” ๋‹จ์ผ ์กฐ์น˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์ผ๋ฐ˜์ ์œผ๋กœ DOM ๊ธฐ๋ฐ˜ ์ทจ์•ฝ์ ์„ ํ”ผํ•˜๋Š” ๊ฐ€์žฅ ํšจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ•์€ ์‹ ๋ขฐ ํ•  ์ˆ˜ ์—†๋Š” ์†Œ์Šค์˜ ๋ฐ์ดํ„ฐ๊ฐ€ Sink๋กœ ์ „์†ก๋˜๋Š” ๊ฐ’์„ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์ด๋Ÿฌํ•œ ๋™์ž‘์„ ํ”ผํ•  ์ˆ˜ ์—†์„ ๊ฒฝ์šฐ ํด๋ผ์ด์–ธํŠธ ์ธก ์ฝ”๋“œ ๋‚ด์—์„œ ๋ฐฉ์–ด๊ฐ€ ๊ตฌํ˜„๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์•ˆ์ „ํ•˜๋‹ค๊ณ  ์•Œ๋ ค์ง„ ์ฝ˜ํ…์ธ ๋งŒ ํ—ˆ์šฉํ•˜๋ฉด์„œ ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•˜๊ฑฐ๋‚˜ ์ธ์ฝ”๋”ฉ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
๋ณต์žกํ•œ ์ž‘์—…์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฝ์ž…ํ•  ์ปจํ…์ŠคํŠธ์— ๋”ฐ๋ผ JavaScript escaping, HTML ์ธ์ฝ”๋”ฉ, URL ์ธ์ฝ”๋”ฉ ๋“ฑ์˜ ์กฐํ•ฉ์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿž BugBounty Write up


๐Ÿ“ƒ References