跨站點腳本(XSS)攻擊是一種將惡意代碼注入網頁而後執行的攻擊。這是前端Web開發人員必須應對的最多見的網絡攻擊形式之一,所以瞭解攻擊的工做原理和防範方法很是重要。html
在本文中,咱們將查看幾個用React編寫的代碼示例,這樣您也能夠保護您的站點和用戶。前端
對於咱們全部的示例,咱們將實現相同的基本功能。咱們將在頁面上有一個搜索框,用戶能夠在其中輸入文本。點擊「Go」按鈕將模擬運行搜索,而後一些確認文本將顯示在屏幕上,並向用戶重複他們搜索的術語。這是任何容許你搜索的網站的標準行爲。git
很簡單,對吧?會出什麼問題呢?github
好吧,若是咱們在搜索框中輸入一些HTML怎麼辦?讓咱們嘗試如下代碼段:npm
<img src="1" onerror="alert('Gotcha!')" />
如今會發生什麼?編程
哇,onerror
事件處理程序已執行!那不是咱們想要的!咱們只是不知不覺地從不受信任的用戶輸入中執行了腳本。瀏覽器
而後,破碎的圖像將呈如今頁面上,那也不是咱們想要的。安全
那麼咱們是怎麼到這裏的呢?好吧,在本例中渲染搜索結果的JSX中,咱們使用瞭如下代碼:網絡
<p style={searchResultsStyle}>You searched for: <b><span dangerouslySetInnerHTML={{ __html: this.state.submittedSearch }} /></b></p>
用戶輸入被解析和渲染的緣由是咱們使用了 dangerouslySetInnerHTML
屬性,這是React中的一個特性,它的工做原理就像原生的 innerHTML
瀏覽器API同樣,因爲這個緣由,通常認爲使用這個屬性是不安全的。xss
如今,讓咱們看一個成功防護XSS攻擊的示例。這裏的修復方法很是簡單:爲了安全地渲染用戶輸入,咱們不該該使用 dangerouslySetInnerHTML
屬性。相反,讓咱們這樣編寫輸出代碼:
<p style={searchResultsStyle}>You searched for: <b>{this.state.submittedSearch}</b></p>
咱們將輸入相同的輸入,但這一次,這裏是輸出:
很好!用戶輸入的內容在屏幕上只呈現爲文字,威脅已被解除。
這是個好消息!React默認狀況下會對渲染的內容進行轉義處理,將全部的數據都視爲文本字符串處理,這至關於使用原生 textContent
瀏覽器API。
因此,這裏的建議彷佛很簡單。只要不要在你的React代碼中使用dangerouslySetInnerHTML
你就能夠了。但若是你發現本身須要使用這個功能呢?
例如,也許您正在從諸如Drupal之類的內容管理系統(CMS)中提取內容,而其中某些內容包含標記。(順便說一句,我可能一開始就不建議在文本內容和來自CMS的翻譯中包含標記,但對於本例,咱們假設您的意見被否決了,而且帶有標記的內容將保留下來。)
在這種狀況下,您確實想解析HTML並將其呈如今頁面上。那麼,您如何安全地作到這一點?
答案是在渲染HTML以前對其進行清理。與徹底轉義HTML不一樣,在渲染以前,您將經過一個函數運行內容以去除任何潛在的惡意代碼。
您可使用許多不錯的HTML清理庫。和任何與網絡安全有關的東西同樣,最好不要本身寫這些東西。有些人比你聰明得多,無論他們是好人仍是壞人,他們比你考慮得更多,必定要使用久經考驗的解決方案。
我最喜歡的清理程序庫之一稱爲sanitize-html,它的功能恰如其名。您從一些不乾淨的HTML開始,經過一個函數運行它,而後獲得一些漂亮、乾淨、安全的HTML做爲輸出。若是您想要比它們的默認設置提供更多的控制,您甚至能夠自定義容許的HTML標記和屬性。
就是這樣了。如何執行XSS攻擊,如何防止它們,以及如何在必要時安全地解析HTML內容。
祝您編程愉快,安全無虞!
完整的代碼示例可在GitHub上找到:https://github.com/thawkin3/x...