TOC

工具

multipage 和 one-page 內容有出入

解析

字組 code points 定義

An ASCII tab or newline is U+0009 TAB, U+000A LF, or U+000D CR.
ASCII whitespace is U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or U+0020 SPACE

可解析成 script 的 content-type

HTML entity

HTML attribute

協議

protocol, scheme

HTML Quirk

  • TODO

execution order

  • 在 document 尚未解析完前 document.write 會寫在下一行,解析完後是 overwrite

    ​​​​<p>a</p>
    ​​​​<script>
    ​​​​  const a= ()=>(document.write('aaaa'))
    ​​​​  a()
    ​​​​</script>
    ​​​​<p>b</p>
    
  • <svg><svg/onload> 在插入前就觸發

    猜測:因為 svg 切換成 XML parsing 後,第二層的 svg 經過 tokenize 後直接觸發 tree construction

    ​​​​<div id=x></div>
    ​​​​<div id=y>hello</div>
    ​​​​<script>
    ​​​​    x.innerHTML = '<svg><svg onload=alert(window.y.innerText)>'
    ​​​​    y.innerText = 'updated'
    ​​​​</script>
    ​​​​<!-- 在 y.innerText 前就觸發 -->
    

HTML Element 特性

  • HTML Parser spec
    • 分成 tokenizer 和 tree construction 兩塊,tokenizer 把餵入的文本 tokenized 後 emit token,每次 emit 後就換 tree construction 把 token 轉成 element,依據演算法插入 DOM 位置,然後影響接下去的 tokenizer 過程,兩個流程交互作用

meta

comment

select

table

a

  • download
    • 指定 download filename
    ​​​​<a download=qwe> // filename=qwe.txt
    ​​​​<a download=pwn.exe> // filename=pwn.exe
    
    • data uri + download
      • 隨意創造 download 內容<a href='data:,jizzz' download>
    • Alles CTF 2021 ALLES!Chat
  • href
    • a 轉換成字串時,會使用 href 內容
    ​​​​<a href='ji:alert(1)' id=aaa>
    ​​​​aaa + ''  // 'ji:alert(1)'
    ​​​​<a href=' alert(1)' id=aaa>
    ​​​​aaa + '' //  '$SCHEMA://$HOST/alert(1)'
    

iframe

ref
  • spec
  • cross origin 可接觸 property

A JavaScript property name P is a cross-origin accessible window property name if it is "window", "self", "location", "close", "closed", "focus", "blur", "frames", "length", "top", "opener", "parent", "postMessage", or an array index property name.
https://html.spec.whatwg.org/multipage/browsers.html#crossoriginproperties-(-o-)

  • 可以更改不同源底下任意 iframe location
    • 可以偷取 postMessage 資訊

    Always specify an exact target origin, not *, when you use postMessage to send data to other windows. A malicious site can change the location of the window without your knowledge, and therefore it can intercept the data sent using postMessage.ref

  • 可以 redirect top location,非同源 chrome 會預設阻擋
  • src
    • 支援 data:, javascript:
    • data: origin 會設成 null
    • javascript: 要求 same origin
  • srcdoc
    • = src + data URI
    • origin === parent.origin
  • csp
    • 設定 csp 屬性
    • 變嚴格可以使一些 script 失效
  • sandbox
    • 將 iframe origin 預設成 null 並且關閉許多功能
    • sandbox 開啟的東西會繼承 sandbox 限制
    • 會把新開啟的頁面 origin 跟著變 null,有機會繞過 same origin 檢查 e.g. postMessage

form

  • 提交 json-like body
<form method='POST' enctype='plain/text'>

<input name='{"k":"v' value='"}"'>

</form>

script

refs
  • 可解析的 Content-Type
    • by spec
    • by implement and implement Chromium build 103.0.5012.1
    • legacy supported build 103.0.5012.1
      legacy supprted list
      ​​​​​​​​"application/ecmascript",
      ​​​​​​​​"application/javascript",
      ​​​​​​​​"application/x-ecmascript",
      ​​​​​​​​"application/x-javascript",
      ​​​​​​​​"text/ecmascript",
      ​​​​​​​​"text/javascript",
      ​​​​​​​​"text/javascript1.0",
      ​​​​​​​​"text/javascript1.1",
      ​​​​​​​​"text/javascript1.2",
      ​​​​​​​​"text/javascript1.3",
      ​​​​​​​​"text/javascript1.4",
      ​​​​​​​​"text/javascript1.5",
      ​​​​​​​​"text/jscript",
      ​​​​​​​​"text/livescript",
      ​​​​​​​​"text/x-ecmascript",
      ​​​​​​​​"text/x-javascript",
      
    • application/webbundle: TODO
  • script type attribute 可接受ㄉ值
    • Content-Type 那些
    • webbundle
    • module
    • importmap
    • speculationrules
  • Script data double escape start state
    • 一般來說,<script> 碰到 </script> 就會被閉合,執行中間內容
    • 在 tokenizer 階段 script data (內容)遇到 <!--<script> ,這個 state 會把後面遇到的 </script> 也當成內容的一部分,然後才尋找 </script> 做閉合,因此可以跨過 script ,另外內容的 <!--<script 要 balanced 內容才會被執行
      ​​​​​​​​<script>
      ​​​​​​​​    alert('exec1')
      ​​​​​​​​    <!--<script>
      ​​​​​​​​    /*  
      ​​​​​​​​</script>
      ​​​​​​​​    -->
      ​​​​​​​​<script>
      ​​​​​​​​    */
      ​​​​​​​​    alert('exec2')
      ​​​​​​​​</script>
      
    • 以下是實際上執行內容,<!----> 在 browser 被視為單行註釋,下面的 --> 是為了平衡而沒有註釋效果,被包在 /**/ 本身已經是註釋一部份
      ​​​​​​​​alert('exec1')
      ​​​​​​​​<!--<script>
      ​​​​​​​​/*  
      ​​​​​​​​</script>
      ​​​​​​​​-->
      ​​​​​​​​<script>
      ​​​​​​​​*/
      ​​​​​​​​alert('exec2')
      
      
  • script under svg
    • 普通的 script innerText 是無法使用 HTML entity,若是在 svg 裡則可以使用,可以繞過 WAF
    • ​​​​​​​​<body>
      ​​​​​​​​  <svg>
      ​​​​​​​​    <script>
      ​​​​​​​​      &#x61;lert("works!");
      ​​​​​​​​    </script>
      ​​​​​​​​  </svg>
      ​​​​​​​​  <script>
      ​​​​​​​​    &#x61;lert("not workQQ");
      ​​​​​​​​  </script>
      ​​​​​​​​</body>
      
    • chromium issue

svg

  • svg 會把 parsing 模式轉換成 xml
  • script 會解析 HTML entity
  • <foreignObject> 可寫 html
// from huli
  <foreignObject>
    <iframe srcdoc="&lt;script&gt;alert(document.domain)&lt;/script&gt;"></iframe>
  </foreignObject>

label

input

HTML attribute

popover

markup dangling attack

ref: maple3124

mxss