10個React安全實踐
你在找保護 React 應用程序的最佳方法嗎?那你找對地方了!
我創建了這個 React 安全最佳實踐清單,以幫助你和你的團隊發現并解決 React 應用中的安全問題。這篇文章將展示如何自動測試你的 React 代碼中的安全問題,并修復它們。
讓我們開始吧。
- 數據綁定( Data Binding)默認的xss保護
- 危險的URL
- 渲染html
- 直接訪問dom
- 服務端渲染
- 檢測依賴項中的漏洞
- JSON State
- 檢測React易受攻擊版本
- linter工具
- 危險的庫代碼
1、數據綁定( Data Binding)默認的 xss 保護
使用默認的{}進行數據綁定,React會自動對值進行轉義以防止XSS攻擊。但注意這種保護只在渲染textContent時候有用,渲染HTML attributes的時候是沒用的。
使用數據綁定語法{}將數據在組件中。
這樣做:
- <div>{data}</div>
避免沒有經過自定義驗證的動態HTML attributes值。
別這樣做:
- <form action={data}>...
2、危險的URL
URL是可以通過javascript:協議來引入動態腳本的。所以需要驗證你的連接是否是http:或者https:以防止javascript:url的腳本注入。使用原生的URL parsing方法進行URL驗證,判斷其協議是否在你的白名單中。
這樣做:
- function validateURL(url) {
- const parsed = new URL(url)
- return ['https:', 'http:'].includes(parsed.protocol)
- }
- <a href={validateURL(url) ? url : ''}>Click here!</a>
別這樣做:
- <a href={attackerControlled}>Click here!</a>
3、渲染html
React是可以通過dangerouslySetInnerHTML將html代碼直接渲染到dom節點中的。但以這種方式插入的任何內容都必須事先消毒。
在將任何值放入dangerouslySetInnerHTML屬性之前,需要用dompurify對其消毒。
在插入html時用dompurify進行處理
- import purify from "dompurify";
- <div dangerouslySetInnerHTML={{ __html:purify.sanitize(data) }} />
4、直接訪問dom
應該避免訪問DOM然后直接將內容注入DOM節點。如果你一定要插入HTML,那就先用dompurify消毒,然后再用dangerouslySetInnerHTML屬性。
這樣做:
- import purify from "dompurify";
- <div dangerouslySetInnerHTML={{__html:purify.sanitize(data) }} />
不要使用refs 和findDomNode()去訪問渲染出來的DOM元素,然后用類似innerHTML的方法或者屬性去注入內容。
別這樣做:
- this.myRef.current.innerHTML = attackerControlledValue;
5、服務端渲染
在使用像ReactDOMServer.renderToString()和ReactDOMServer.renderToStaticMarkup()這類方法的時候,數據綁定會自動提供內容轉義的功能。
避免在將字符串發送到客戶端瀏覽器進行注水(hydration)之前,把其他的一些(未經檢驗的)字符串連接到renderToStaticMarkup()的輸出上。
不要把未經消毒的數據連接到renderToStaticMarkup()的輸出上,以防止XSS
- app.get("/", function (req, res) {
- return res.send(
- ReactDOMServer.renderToStaticMarkup(
- React.createElement("h1", null, "Hello World!")
- ) + otherData
- );
- });
6、檢測依賴項中的漏洞
一些第三方組件的某些版本可能包含安全問題。檢查您的依賴關系,并及時更新到更好的版本。
使用類似snyk CLI[1]的工具進行漏洞檢查。
snyk CLI 還可以與代碼管理系統集成,然后自動修復漏洞:
$ npx snyk test
7、JSON state
將JSON數據與SSR后的React頁面一起發送是常見做法。一定要用無害的等價字符轉移<字符。
使用良性等效字符轉義JSON中的HTML有效值:
- window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace( /</g, '\\u003c')}
8、易受攻擊的React版本
React庫在過去有一些嚴重性很高的漏洞,因此最好保持最新版本。
使用npm outdated查看是否處于最新版本,從而避免使用react和react dom的易受攻擊版本。
9、linter工具
安裝能自動檢測代碼中的安全問題并提供修正建議的Linter配置和插件。
使用 ESLint React security config[2] 來檢查安全漏洞。
配置能在使用husky這樣的庫檢測到安全相關的問題時,會失敗的pre-commit鉤子。
使用Snyk自動更新版本[3] 當其檢查到你當前的版本有安全問題。
10、危險的庫代碼
庫代碼通常會進行危險的操作,如直接將HTML插入DOM。人工或使用linter工具來檢查庫代碼,以檢測是否有對React機制的不安全使用。
避免那些使用dangerouslySetInnerHTML、innerHTML、未驗證的URL或其他不安全模式的庫。使用linter工具對node_modules目錄進行檢查。
后話
以上就是我要分享的10個React安全實踐。你在 React 安全方面有哪些經驗,歡迎在評論中分享出來。