mXSS 兮(結局|新紀元)凡勢是隨欲來矣?
前幾工我佇 X 咧巡田水時影著有人咧講 WHATWG 有一个 spec 隨欲正式實行矣,講是會當去解決著 mXSS 兮問題,予咱向「the end of mXSS」閣較倚一步。
𪜶欲做兮代誌真簡單,就共標題完全仝款——「HTML 咧序󠇡列化兮時,屬性值󠇡內底兮 <
佮 >
愛共伊編碼 (escape) 起來」。毋過 mXSS 是啥物呢?是按怎按呢就會使解決 mXSS 兮問題?
平常時仔有咧舞網頁兮朋友,大概是攏知影 XSS (Cross-Site Scripting) 是啥物貨,嘛知影彼有偌僫處理,一無細膩就無的確會走出來。毋過,恁敢有聽過 mXSS (Mutation XSS) ?咱佇開始講著這个新兮 spec 進前,先來共逐家簡單紹介一下 mXSS 是啥物。
簡單來講,mXSS 是一種「(1) HTML 解析 ⇢ (2) 閣序列化 ⇢ (3) 閣再解析」兮過程中,有變化(mutation)覕佇中央,所造成兮 XSS 攻擊。伊兮原理就是利用瀏覽器佇咧解析佮重新序列化 (re-serialize) HTML 兮時,產生毋是預期兮 mutation,進一步造成 XSS 兮空縫。
這款攻擊上狡怪兮一點是,原本兮 HTML 看來可能原仔攏無啥問題,甚至會當通過一般兮 sanitizer 檢查。毋過,經過瀏覽器彼規套過程了後,走精去兮 DOM tree 就會顛倒變成予惡意兮 JavaScript 有機會執行。
這个 issue (#6235) 是 @securityMB 佇 2020 年提出兮。伊講現此時 HTML 佇咧序列化屬性 (attribute) 內容兮時,並無共 <
佮 >
跳脫做 <
佮 >
。這造成一寡 HTML parser 或者 sanitizer 會有機會予 mXSS 害著。
伊提一个 DOMPurify 這个出名兮踅過 HTML sanitizer 兮情形做例。假使講咱有一段 HTML 碼生按呢:
<svg></p><style><a title="</style><img src onerror=alert(1)>">
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
屬性值
經過 sanitizer 兮處理,閣透過 elem.innerHTML = Sanitizer.sanitize(markup)
這款捷看兮用法共伊寫入去頁面頂,這段 HTML 會先夆序列化,紲落來閣予瀏覽器重新解析。就因為 <
佮 >
無編碼,序列化了後會夆變做:
<svg><p></p><style><a title="</style><img src onerror=alert(1)>"></style></svg>
^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^
攏算是佇 style 內面 新標籤 XSS!
這段 HTML 佇重新解析兮時,因為 <p>
標籤會跳脫 (break out) foreign content (親像 <svg>
) 兮特性,加上 <style>
內容兮處理方式,落尾生出來兮 DOM tree 煞就會走精去,予彼个 onerror=alert(1)
執行起來,造成 XSS。(是講莫相信我 blog 兮 code highlight 喔,彼是毋著兮,這就是 mXSS 趣味兮所在 XD)
我佇遮是講了較簡單,若欲共 mXSS 這个議題讀了閣較詳細一寡,這篇文章(華語)嘛紹介了誠好,會當參考看覓:繞過你的防禦:Mutation XSS
所以,佇咧這个 issue 欲做兮代誌就是,𪜶想欲共屬性值內面兮角括號 escape 來避免這款兮 mXSS。按咱拄才講著兮彼个例,若是佇咱第二步咧序列化兮時,有好好仔共屬性內底兮 <
佮 >
編碼,按呢序列化後兮結果就會是生做這款:
<svg><p></p><style><a title="</style><img src onerror=alert(1)>"></style></svg>
按呢就袂閣有 mXSS 出現矣!
毋過參每一个新標準仝款,嘛是有人咧煩惱這款改變敢會有 web compatibility 兮問題。親像 @zcorpan 就有講著,往擺佇 2008 年兮時,除了 IE 以外兮瀏覽器攏會去共 attribute 內底兮 <
佮 >
編碼,毋過彼當陣為著欲配合 IE,標準煞改做無編碼。雖然彼陣無造成啥物問題,毋過十外冬過去矣,無定有新兮網頁內容是倚靠目前無 escape 兮行為。伊嘛生一个趣味兮例,解說啥款兮 code 會因為這个改變出重耽:
<a href="javascript: if (foo < 10) doSomething()" id="theLink">link</a>
...
<script>
theLink.onclick = function() {
eval(this.outerHTML.match(/href="([^"]+)"/)[1]);
return false;
}
</script>
這款用正󠇡規表示式去掠 outerHTML
內底無編碼過兮 <
兮 code,確實會因為新兮編碼 spec 舞歹去。
毋過,為著解決 mXSS 這个歹扭搦兮問題,WHATWG 彼陣人,包括 securityMB 佮 zcorpan 等等,攏認為這是一个會得試看覓兮方向。
Chromium 𪜶行代先,2023 年 3 月左右就共這个改變囥入去實驗性功能內底,自 2024 年 9 月開始走 Finch 試驗,看來到這馬是攏無啥大問題煏出來,𪜶就按呢煞決定共這个功能捒入去 Chrome stable 版本,六月二四就會正式上版矣。
除了 Chrome, Webkit (Safari) 佮 Firefox 𪜶看著 Chromium 𪜶試驗了無問題,嘛歡喜綴咧行。咱看來這个功能正式是欲成做所有瀏覽器兮標準矣。
毋知未來兮 mXSS 敢真正就會消失去,抑是會踏入去一个新紀元——眾駭客猶原是有才調變一个閣較鑠奅兮步數來舞咧 👀