10月18號, W3C中網絡平臺孵化器小組(Web Platform Incubator Community Group)公布了HTML Sanitizer API的規范草案。這份草案用來解決瀏覽器如何解決XSS攻擊問題。
網絡安全中比較讓開發者們頭疼的一類是XSS跨站點腳本攻擊。這種攻擊通常指的是通過利用網頁開發時留下的漏洞,即將惡意指令代碼注入到網頁,使用戶加載并執行攻擊者惡意制造的網頁程序。
這些惡意代碼沒有經過過濾,與網站的正常代碼混在一起,瀏覽器無法分辨哪些內容是可信的,惡意腳本就會被執行。而XSS攻擊的核心有兩個步驟:1、處理攻擊者提交惡意代碼;2、瀏覽器執行惡意代碼。
為了解決在這兩步惡意攻擊中解決這個問題,通常有以下手段,
以上手段這些步驟繁瑣,需要注意的內容也很多。為了讓開發者更加便捷地解決XSS攻擊的問題,瀏覽器現提供了原生的XSS攻擊消毒能力。
HTML Sanitizer API——這份由谷歌、Mozilla和Cure53聯手發起提供的API即將最終完成,通過這個瀏覽器原生API我們可以更加輕松地保護Web應用程序免受XSS的攻擊。
接下來我們一起來了解一下這個安全API吧。
Sanitizer API可以讓瀏覽器直接從網站動態更新的標記中刪除惡意代碼。當有惡意HTML字符串、和文檔或文檔片段對象想插入現有DOM之中,我們可以使用HTML Sanitizer API直接將這些內容清理。有點像電腦的安全衛士應用,可以清除風險內容。
使用Sanitizer API有以下三個優點:
Sanitizer API為HTML字符串安全打開新世界大門,將所有的功能大致分類,可以分為以下三個主要特性:
1.對用戶輸入進行殺毒
Sanitizer API的主要功能是接受字符串并將其轉換為更安全的字符串。這些轉換后的字符串不會執行額外的JavaScript,并確保應用程序受到XSS攻擊的保護。
2.瀏覽器內置
該庫在瀏覽器安裝的時候一同預裝,并在發現bug或出現新的攻擊時進行更新。相當于我們的瀏覽器有了內置的殺毒措施,無需導入任何外部庫。
3.使用簡潔安全
在使用了Sanitizer API之后,瀏覽器此時就有了一個強大又安全的解析器,作為一個成熟的瀏覽器,它知道如何處理DOM中每個元素的活動。相比之下,用JavaScript開發的外部解析器不僅成本高昂,同時很容易跟不上前端大環境的更新速度。
說完了這些使用上的亮點特性,讓我們一起來看看這個API的具體用法。
Sanitizer API使用Sanitizer()方法構造函數,Sanitizer類進行配置。
官方提供了三種基礎清理方式:
1、清理隱藏上下文的字符串
Element.setHTML() 用于解析和清理字符串,并立即將其插入DOM,這個方法適用于目標DOM元素已知且HTML內容為字符串的情況。
const?$div?=?document.querySelector('div') const?user_input?=?`<em>Hello?There</em><img?src=""?onerror="alert(0)">`?//?The?user?string. const?sanitizer?=?new?Sanitizer()?//?Our?Sanitizer //?We?want?to?insert?the?HTML?in?user_string?into?a?target?element?with?id //?target.?That?is,?we?want?the?equivalent?of?target.innerHTML?=?value,?except //?without?the?XSS?risks. $div.setHTML(user_input,?sanitizer)?//?<div><em>Hello?There</em><img?src=""></div>
2、清理給定上下的文字符串
Sanitizer.sanitizeFor() 用于解析、清理和準備稍后準備添加到DOM中的字符串。
適用于HTML內容是字符串,并且目標DOM元素類型已知(例如div、span)的情況。
const?user_input?=?`<em>Hello?There</em><img?src=""?onerror="alert(0)">` const?sanitizer?=?new?Sanitizer() //?Later: //?The?first?parameter?describes?the?node?type?this?result?is?intended?for. sanitizer.sanitizeFor("div",?user_input)?//?HTMLDivElement?<div>
需要注意的是, HTMLElement中 .innerHTML 的清理輸出結果是字符串格式。
sanitizer.sanitizeFor("div",?user_input).innerHTML?//?<em>Hello?There</em><img?src="">
3、清理請理節點
對于已經有用戶控制的DocumentFragment,Sanitizer.sanitize()可以直接對DOM樹節點進行清理。
//?Case:?The?input?data?is?available?as?a?tree?of?DOM?nodes. const?sanitizer?=?new?Sanitizer() const?$userDiv?=?...; $div.replaceChildren(s.sanitize($userDiv));
除了以上提到的三種方式之外,SanitizerAPI通過刪除和、過濾屬性和標記來修改HTML字符串。
舉個“栗子”。
<a>
標簽和colspanson,
標簽上的HREF。默認設置中,這個安全API只用來防止XSS的出現。但是一些情況下我們也需要自定義自義設置,下面介紹一些常用的配置。
創建一個配置對象,并在初始化Sanitizer API時將其傳遞給構造函數。
const?config?=?{ ??allowElements:?[], ??blockElements:?[], ??dropElements:?[], ??allowAttributes:?{}, ??dropAttributes:?{}, ??allowCustomElements:?true, ??allowComments:?true }; //?sanitized?result?is?customized?by?configuration new?Sanitizer(config)
下面是一些常用方法:
const?str?=?`hello?<b><i>there</i></b>` new?Sanitizer().sanitizeFor("div",?str) //?<div>hello?<b><i>there</i></b></div> new?Sanitizer({allowElements:?[?"b"?]}).sanitizeFor("div",?str) //?<div>hello?<b>there</b></div> new?Sanitizer({blockElements:?[?"b"?]}).sanitizeFor("div",?str) //?<div>hello?<i>there</i></div> new?Sanitizer({allowElements:?[]}).sanitizeFor("div",?str) //?<div>hello?there</div>
const?str?=?`<span?id="foo"?class="bar"?style="color:?red">hello?there</span>` new?Sanitizer().sanitizeFor("div",?str) //?<div><span?id="foo"?class="bar"?style="color:?red">hello?there</span></div> new?Sanitizer({allowAttributes:?{"style":?["span"]}}).sanitizeFor("div",?str) //?<div><span?style="color:?red">hello?there</span></div> new?Sanitizer({dropAttributes:?{"id":?["span"]}}).sanitizeFor("div",?str) //?<div><span?class="bar"?style="color:?red">hello?there</span></div>
const?str?=?`<elem>hello?there</elem>` new?Sanitizer().sanitizeFor("div",?str); //?<div></div> new?Sanitizer({?allowCustomElements:?true, ????????????????allowElements:?["div",?"elem"] ??????????????}).sanitizeFor("div",?str); //?<div><elem>hello?there</elem></div>
如果沒有進行任何配置,會直接使用默認配置內容。
這個API看起來能為我們解決不小少的問題,但是現在瀏覽器對其的支持還有限,更多功能還在持續完善中。我們也很期待看到功能更加完善的SanitizerAPI
對它感興趣的小伙伴在Chrome93+中可以通過about://flags/#enable-experimental-web-platform-features啟用,Firefox中目前也在實驗階段,可以在about:config將dom.security.sanitizer.enabled 設為true來啟用。
了解更多內容可以查看:https://developer.mozilla.org/en-US/docs/Web/API/HTML_Sanitizer_API
根據 Verizon 2020 年數據泄露調查報告(Verizon Business,2020 年)顯示,約90% 的數據泄露事件是由于跨站點腳本((XSS))和安全漏洞造成的。對于前端開發者而言,面對越發頻繁的網絡攻擊,除了借助Sanitizer API等安全機制外,還可以考慮使用"數據與代碼分離"的SpreadJS等前端表格控件。</a></div>
|