日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java防止Xss注入json_浅谈 React 中的 XSS 攻击

發布時間:2024/9/19 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java防止Xss注入json_浅谈 React 中的 XSS 攻击 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:陳吉

轉發鏈接:https://mp.weixin.qq.com/s/HweEFh78WXLawyQr_Vsl5g

前言

前端一般會面臨 XSS 這樣的安全風險,但隨著 React 等現代前端框架的流行,使我們在平時開發時不用太關注安全問題。以 React 為例,React 從設計層面上就具備了很好的防御 XSS 的能力。本文將以源碼角度,看看 React 做了哪些事情來實現這種安全性的。

XSS 攻擊是什么

Cross-Site Scripting(跨站腳本攻擊)簡稱 XSS,是一種代碼注入攻擊。XSS 攻擊通常指的是利用網頁的漏洞,攻擊者通過巧妙的方法注入 XSS 代碼到網頁,因為瀏覽器無法分辨哪些腳本是可信的,導致 XSS 腳本被執行。XSS 腳本通常能夠竊取用戶數據并發送到攻擊者的網站,或者冒充用戶,調用目標網站接口并執行攻擊者指定的操作。

XSS 攻擊類型

反射行 XSS

  • XSS 腳本來自當前 HTTP 請求
  • 當服務器在 HTTP 請求中接收數據并將該數據拼接在 HTML 中返回時,例如:
//?某網站具有搜索功能,該功能通過 URL 參數接收用戶提供的搜索詞:https://xxx.com/search?query=123//?服務器在對此 URL 的響應中回顯提供的搜索詞:

您搜索的是:?123

//?如果服務器不對數據進行轉義等處理,則攻擊者可以構造如下鏈接進行攻擊:https://xxx.com/search?query=//?該 URL 將導致以下響應,并運行 alert('xss'):

您搜索的是:?

//?如果有用戶請求攻擊者的 URL ,則攻擊者提供的腳本將在用戶的瀏覽器中執行。

存儲行 XSS

  • XSS 腳本來自服務器數據庫中
  • 攻擊者將惡意代碼提交到目標網站的數據庫中,普通用戶訪問網站時服務器將惡意代碼返回,瀏覽器默認執行,例子:
//?某個評論頁,能查看用戶評論。//?攻擊者將惡意代碼當做評論提交,服務器沒對數據進行轉義等處理//?評論輸入:??//?則攻擊者提供的腳本將在所有訪問該評論頁的用戶瀏覽器執行

DOM 型 XSS

該漏洞存在于客戶端代碼,與服務器無關

  • 類似反射型,區別在于 DOM 型 XSS 并不會和后臺進行交互,前端直接將 URL 中的數據不做處理并動態插入到 HTML 中,是純粹的前端安全問題,要做防御也只能在客戶端上進行防御。

React 如何防止 XSS 攻擊

無論使用哪種攻擊方式,其本質就是將惡意代碼注入到應用中,瀏覽器去默認執行。React 官方中提到了 React DOM 在渲染所有輸入內容之前,默認會進行轉義。它可以確保在你的應用中,永遠不會注入那些并非自己明確編寫的內容。所有的內容在渲染之前都被轉換成了字符串,因此惡意代碼無法成功注入,從而有效地防止了 XSS 攻擊。我們具體看下:

自動轉義

React 在渲染 HTML 內容和渲染 DOM 屬性時都會將 "'&<> 這幾個字符進行轉義,轉義部分源碼如下:

for?(index?=?match.index;?index???????escape?=?'>';??????break;????default:??????continue;????}??}

這段代碼是 React 在渲染到瀏覽器前進行的轉義,可以看到對瀏覽器有特殊含義的字符都被轉義了,惡意代碼在渲染到 HTML 全都被轉成了字符串,如下:

//?一段惡意代碼?//?轉義后輸出到?html?中?

這樣就有效的防止了 XSS 攻擊。

JSX 語法

JSX 實際上是一種語法糖,Babel 會把 JSX 編譯成 React.createElement() 的函數調用,最終返回一個 ReactElement,以下為這幾個步驟對應的代碼:

//?JSXconst?element?=?(??

????Hello,?world!??

);//?通過?babel?編譯后的代碼const?element?=?React.createElement(??'h1',??{className:?'greeting'},??'Hello,?world!');//?React.createElement()?方法返回的?ReactElementconst?element?=?{??$$typeof:?Symbol('react.element'),??type:?'h1',??key:?null,??props:?{????children:?'Hello,?world!',??????className:?'greeting'?????}??...}

我們可以看到,最終渲染的內容是在 Children 屬性中,那了解了 JSX 的原理后,我們來試試能否通過構造特殊的 Children 進行 XSS 注入,來看下面一段代碼:

const?storedData?=?`{??"ref":null,??"type":"body",??"props":{??"dangerouslySetInnerHTML":{??"__html":""??????}??}}`;//?轉成?JSONconst?parsedData?=?JSON.parse(storedData);//?將數據渲染到頁面render?()?{??return??{parsedData}?;?}

這段代碼中, 運行后會報以下錯誤,提示不是有效的 ReactChild

Uncaught?(in?promise)?Error:?Objects?are?not?valid?as?a?React?child?(found:?object?with?keys?{ref,?type,?props}).?If?you?meant?to?render?a?collection?of?children,?use?an?array?instead.

那究竟是哪里出問題了?我們看一下 ReactElement 的源碼:

const?symbolFor?=?Symbol.for;REACT_ELEMENT_TYPE?=?symbolFor('react.element');const?ReactElement?=?function(type,?key,?ref,?self,?source,?owner,?props)?{??const?element?=?{????//?這個?tag?唯一標識了此為?ReactElement????$$typeof:?REACT_ELEMENT_TYPE,????//?元素的內置屬性????type:?type,????key:?key,????ref:?ref,????props:?props,????//?記錄創建此元素的組件????_owner:?owner,??};??...??return?element;}

注意到其中有個屬性是 $$typeof,它是用來標記此對象是一個 ReactElement,React 在進行渲染前會通過此屬性進行校驗,校驗不通過將會拋出上面的錯誤。React 利用這個屬性來防止通過構造特殊的 Children 來進行的 XSS 攻擊,原因是 $$typeof 是個 Symbol 類型,進行 JSON 轉換后會 Symbol 值會丟失,無法在前后端進行傳輸。如果用戶提交了特殊的 Children,也無法進行渲染,利用此特性,可以防止存儲型的 XSS 攻擊。

在 React 中可引起漏洞的一些寫法

使用 dangerouslySetInnerHTML

dangerouslySetInnerHTML 是 React 為瀏覽器 DOM 提供 innerHTML 的替換方案。通常來講,使用代碼直接設置 HTML 存在風險,因為很容易使用戶暴露在 XSS 攻擊下,因為當使用 dangerouslySetInnerHTML 時,React 將不會對輸入進行任何處理并直接渲染到 HTML 中,如果攻擊者在 dangerouslySetInnerHTML 傳入了惡意代碼,那么瀏覽器將會運行惡意代碼。看下源碼:

function?getNonChildrenInnerMarkup(props)?{??const?innerHTML?=?props.dangerouslySetInnerHTML;?//?有dangerouslySetInnerHTML屬性,會不經轉義就渲染__html的內容??if?(innerHTML?!=?null)?{????if?(innerHTML.__html?!=?null)?{??????return?innerHTML.__html;????}??}?else?{????const?content?=?props.children;????if?(typeof?content?===?'string'?||?typeof?content?===?'number')?{??????return?escapeTextForBrowser(content);????}??}??return?null;}

所以平時開發時最好避免使用 dangerouslySetInnerHTML,如果不得不使用的話,前端或服務端必須對輸入進行相關驗證,例如對特殊輸入進行過濾、轉義等處理。前端這邊處理的話,推薦使用白名單過濾 (https://jsxss.com/zh/index.html),通過白名單控制允許的 HTML 標簽及各標簽的屬性。

通過用戶提供的對象來創建 React 組件

舉個例子:

//?用戶的輸入const?userProvidePropsString?=?`{"dangerouslySetInnerHTML":{"__html":""}}"`;//?經過?JSON?轉換const?userProvideProps?=?JSON.parse(userProvidePropsString);//?userProvideProps?=?{//???dangerouslySetInnerHTML:?{//?????"__html":?``//??????}//?};render()?{?????//?出于某種原因解析用戶提供的?JSON?并將對象作為?props?傳遞????return?

這段代碼將用戶提供的數據進行 JSON 轉換后直接當做 div 的屬性,當用戶構造了類似例子中的特殊字符串時,頁面就會被注入惡意代碼,所以要注意平時在開發中不要直接使用用戶的輸入作為屬性。

使用用戶輸入的值來渲染 a 標簽的 href 屬性,或類似 img 標簽的 src 屬性等

const?userWebsite?=?"javascript:alert('xss');";

如果沒有對該 URL 進行過濾以防止通過 javascript: 或 data: 來執行 JavaScript,則攻擊者可以構造 XSS 攻擊,此處會有潛在的安全問題。用戶提供的 URL 需要在前端或者服務端在入庫之前進行驗證并過濾。

服務端如何防止 XSS 攻擊

服務端作為最后一道防線,也需要做一些措施以防止 XSS 攻擊,一般涉及以下幾方面:

  • 在接收到用戶輸入時,需要對輸入進行盡可能嚴格的過濾,過濾或移除特殊的 HTML 標簽、JS 事件的關鍵字等。
  • 在輸出時對數據進行轉義,根據輸出語境 (html/javascript/css/url),進行對應的轉義
  • 對關鍵 Cookie 設置 http-only 屬性,JS腳本就不能訪問到 http-only 的 Cookie 了
  • 利用 CSP (https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP) 來抵御或者削弱 XSS 攻擊,一個 CSP 兼容的瀏覽器將會僅執行從白名單域獲取到的腳本文件,忽略所有的其他腳本 (包括內聯腳本和 HTML 的事件處理屬性)

總結

出現 XSS 漏洞本質上是輸入輸出驗證不充分,React 在設計上已經很安全了,但是一些反模式的寫法還是會引起安全漏洞。Vue 也是類似,Vue 做的安全措施主要也是轉義,HTML 的內容和動態綁定的屬性都會進行轉義。無論使用 React 或 Vue 等前端框架,都不能百分百的防止 XSS 攻擊,所以服務端必須對前端參數做一些驗證,包括但不限于特殊字符轉義、標簽、屬性白名單過濾等。一旦出現安全問題一般都是挺嚴重的,不管是敏感數據被竊取或者用戶資金被盜,損失往往無法挽回。我們平時開發中需要保持安全意識,保持代碼的可靠性和安全性。

作者:陳吉

轉發鏈接:https://mp.weixin.qq.com/s/HweEFh78WXLawyQr_Vsl5g

總結

以上是生活随笔為你收集整理的Java防止Xss注入json_浅谈 React 中的 XSS 攻击的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。