最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解React?如何防止?XSS?攻擊論$$typeof?的作用

 更新時間:2022年07月25日 09:34:51   作者:??runnerdancer?  
這篇文章主要介紹了詳解React?如何防止?XSS?攻擊論$$typeof?的作用,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

JSX

先來簡單復(fù)習(xí)一下 JSX 的基礎(chǔ)知識。JSX 是React.createElement的語法糖

<div id="container">hello</div>

經(jīng)過 babel 編譯后:

React.createElement(
  "div" /* type */,
  { id: "container" } /* props */,
  "hello" /* children */
);

React.createElement最終返回的結(jié)果就是一個對象,如下:

{
  type: 'div',
  props: {
    id: 'container',
    children: 'hello',
  },
  key: null,
  ref: null,
  $$typeof: Symbol.for('react.element'),
}

這就是一個 React element 對象。

我們甚至可以在代碼中直接寫 React element 對象,React 照樣能正常渲染我們的內(nèi)容:

render() {
  return (
    <div>
      {{
        $$typeof: Symbol.for('react.element'),
        props: {
          dangerouslySetInnerHTML: {
            __html: '<img src="x" onerror="alert(1)">'
          },
        },
        ref: null,
        type: "div",
      }}
    </div>
  );
}

可以復(fù)制這段代碼本地運行一下,可以發(fā)現(xiàn)瀏覽器彈出一個彈窗,并且img已經(jīng)插入了 dom 中。

這里,$$typeof 的作用是啥?為什么使用 Symbol() 作為值?

在了解之前,我們先來簡單看下 XSS 攻擊

XSS 攻擊

我們經(jīng)常需要構(gòu)造 HTML 字符串并插入到 DOM 中,比如:

const messageEl = document.getElementById("message");
var message = "hello world";
messageEl.innerHTML = "<p>" + message + "</p>";

頁面正常顯示。但是如果我們插入一些惡意代碼,比如:

const messageEl = document.getElementById("message");
var message = '<img src onerror="alert(1)">';
messageEl.innerHTML = "<p>" + message + "</p>";

此時頁面就會彈出一個彈窗,彈窗內(nèi)容顯示為 1

因此,直接使用 innerHTML 插入文本內(nèi)容,存在 XSS 攻擊的風(fēng)險

防止 XSS 攻擊的方法

為了解決類似的 XSS 攻擊方法,我們可以使用一些安全的 API 添加文本內(nèi)容,比如:

  • 使用 document.createTextNode('hello world') 插入文本節(jié)點。
  • 或者使用 textContent 而不是 innerHTML 設(shè)置文本內(nèi)容。
  • 對于一些特殊字符,比如 <>,我們可以進行轉(zhuǎn)義,將其轉(zhuǎn)換為 &#60; 以及 &#62;
  • 對于富文本內(nèi)容,我們可以設(shè)置黑名單,過濾一些屬性,比如 onerror 等。

React 對于文本節(jié)點的處理

React 使用 createTextNode 或者 textContent 設(shè)置文本內(nèi)容。

對于下面的代碼:

render() {
  const { count } = this.state
  return (
    <div onClick={() => this.setState({ count: count + 1})}>
      {count}
    </div>
  );
}

React 在渲染過程中會調(diào)用setTextContent方法為div節(jié)點設(shè)置內(nèi)容,其中,第一次渲染時,直接設(shè)置div節(jié)點的textContent,第二次或者第二次以后的更新渲染,由于第一次設(shè)置了textContent,因此divfirstChild值存在,是個文本節(jié)點。此時直接更新這個文本節(jié)點的nodeValue即可

var setTextContent = function (node, text) {
  if (text) {
    var firstChild = node.firstChild;
    // 如果當(dāng)前node節(jié)點已經(jīng)設(shè)置過textContent,則firstChild不為空,是個文本節(jié)點TEXT_NODE
    if (
      firstChild &&
      firstChild === node.lastChild &&
      firstChild.nodeType === TEXT_NODE
    ) {
      firstChild.nodeValue = text;
      return;
    }
  }
  // 第一次渲染,直接設(shè)置textContent
  node.textContent = text;
};

綜上,對于普通的文本節(jié)點來說,由于 React 是采用 textContent 或者 createTextNode 的方式添加的,因此是不會存在 XSS 攻擊的,即使上面示例中,count 的值為 '<img src="x" onerror="alert(1)">'也不會有被攻擊的風(fēng)險

dangerouslySetInnerHTML 處理富文本節(jié)點

有時候我們確實需要顯示富文本的內(nèi)容,React 提供了dangerouslySetInnerHTML方便我們顯式的插入富文本內(nèi)容

render() {
  return (
    <div
      id="dangerous"
      dangerouslySetInnerHTML={{ __html: '<img src="x" onerror="alert(1)">' }}
    >
    </div>
  );
}

React 在為 DOM 更新屬性時,會判斷屬性的key是不是dangerouslySetInnerHTML,如果是的話,調(diào)用setInnerHTML 方法直接給 dom 的innerHTML屬性設(shè)置文本內(nèi)容

function setInitialDOMProperties(
  tag,
  domElement,
  rootContainerElement,
  nextProps
) {
  for (var propKey in nextProps) {
    if (propKey === "dangerouslySetInnerHTML") {
      var nextHtml = nextProp ? nextProp.__html : undefined;
      if (nextHtml != null) {
        setInnerHTML(domElement, nextHtml);
      }
    }
  }
}
var setInnerHTML = function (node, html) {
  node.innerHTML = html;
};

可以看出,React 在處理富文本時,也僅僅是簡單的設(shè)置 DOM 的innerHTML屬性來實現(xiàn)的。

對于富文本潛在的安全風(fēng)險,交由開發(fā)者自行把控。

$$typeof 的作用

render() {
  const { text } = this.state
  return (
    <div>
      {text}
    </div>
  );
}

假設(shè)這個text是從后端返回來的,同時后端允許用戶存儲 JSON 對象,如果用戶傳入下面這樣的一個類似 React element 的對象:

{
  type: "div",
  props: {
    dangerouslySetInnerHTML: {
      __html: '<img src="x" onerror="alert(1)">'
    },
  },
  ref: null
}

別忘了前面說過,我們在 JSX 中直接插入 React element 對象也是能夠正常渲染的。

在這種情況下,在React0.13版本時,這是一個潛在的XSS攻擊,這個漏洞源于服務(wù)端。如果攻擊者惡意偽造一個類似 React element 對象的數(shù)據(jù)返回給前端,React 就會執(zhí)行惡意代碼。但是 React 可以采取措施預(yù)防這種攻擊。

React0.14版本開始,React 為每個 element 都添加了一個Symbol標(biāo)志:

{
  $$typeof: Symbol.for('react.element'),
  props: {
    id: 'container'
  },
  ref: null,
  type: "div",
}

這個行得通,是因為 JSON 不支持Symbol。因此即使是服務(wù)端有風(fēng)險漏洞并且返回一個 JSON,這個 JSON 也不會包含Symbol.for('react.element').,在 Reconcile 階段,React 會檢查element.$$typeof標(biāo)志是否合法。不合法的話直接報錯,React 不能接受對象作為 children

專門使用 Symbol.for() 的好處是, Symbols 在 iframe 和 worker 等環(huán)境之間是全局的。因此,即使在更奇特的條件下,Symbols 也能在不同的應(yīng)用程序之間傳遞受信任的元素。同樣,即使頁面上有多個 React 副本,它們?nèi)匀豢梢?ldquo;同意”有效的 $$typeof 值

如果瀏覽器不支持Symbols,React 使用0xeac7代替

{
  $$typeof: '0xeac7',
}

到此這篇關(guān)于詳解React 如何防止 XSS 攻擊論$$typeof 的作用的文章就介紹到這了,更多相關(guān)React $$typeof 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解如何在React單頁面應(yīng)用中捕獲錯誤

    詳解如何在React單頁面應(yīng)用中捕獲錯誤

    在當(dāng)前的Web開發(fā)中,使用React構(gòu)建單頁面應(yīng)用(SPA)已經(jīng)成為一種常見的做法,然而,當(dāng)應(yīng)用程序遇到錯誤時,有可能會導(dǎo)致整個頁面崩潰,給用戶帶來不好的體驗,本文將介紹如何在React單頁面應(yīng)用中捕獲錯誤,以防止整個頁面的崩潰,需要的朋友可以參考下
    2023-09-09
  • 詳解如何封裝和使用一個React鑒權(quán)組件

    詳解如何封裝和使用一個React鑒權(quán)組件

    JavaScript?和?React?提供了靈活的事件處理機制,特別是通過利用事件的捕獲階段來阻止事件傳播可以實現(xiàn)精細的權(quán)限控制,本文將詳細介紹這一技術(shù)的應(yīng)用,并通過實踐案例展示如何封裝和使用一個?React?鑒權(quán)組件,需要的可以參考下
    2024-03-03
  • 每天一個hooks學(xué)習(xí)之useUpdateEffect

    每天一個hooks學(xué)習(xí)之useUpdateEffect

    這篇文章主要為大家介紹了每天一個hooks學(xué)習(xí)之useUpdateEffect使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • React實現(xiàn)輪播效果

    React實現(xiàn)輪播效果

    這篇文章主要為大家詳細介紹了React實現(xiàn)輪播效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • 詳解react使用react-bootstrap當(dāng)輪子造車

    詳解react使用react-bootstrap當(dāng)輪子造車

    本篇文章主要介紹了詳解react使用react-bootstrap當(dāng)輪子造車,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-08-08
  • react中setState的執(zhí)行機制詳解

    react中setState的執(zhí)行機制詳解

    setState() 的執(zhí)行機制包括狀態(tài)合并、批量更新、異步更新、虛擬 DOM 比較和渲染組件等步驟,這樣可以提高性能并優(yōu)化渲染過程,這篇文章主要介紹了react中的setState的執(zhí)行機制,需要的朋友可以參考下
    2023-10-10
  • React組件化學(xué)習(xí)入門教程講解

    React組件化學(xué)習(xí)入門教程講解

    React是現(xiàn)在前端使用頻率最高的三大框架之一,React率先提出虛擬DOM的思想和實現(xiàn),使其保持有良好的性能。本篇文章將對React組件化的入門學(xué)習(xí)進行講解,同時針對模塊化的思想進行概述,為接下來組件化開發(fā)的文章進行知識儲備
    2022-09-09
  • React虛擬列表的實現(xiàn)

    React虛擬列表的實現(xiàn)

    在開發(fā)過程中,總是遇到很多列表的顯示。當(dāng)上數(shù)量級別的列表渲染于瀏覽器,終會導(dǎo)致瀏覽器的性能下降,你可以選擇其他方式避免,本文就介紹了虛擬列表來解決這個問題
    2021-05-05
  • React?forwardRef?用法案例分析

    React?forwardRef?用法案例分析

    這篇文章主要介紹了React forwardRef用法,forwardRef允許你的組件使用ref將一個DOM節(jié)點暴露給父組件,本文結(jié)合案例分析給大家講解的非常詳細,需要的朋友可以參考下
    2023-06-06
  • Redux中subscribe的作用及說明

    Redux中subscribe的作用及說明

    由于redux使用這方面有很多的不解,不是很熟練,所以我查找資料,進行一個總結(jié),希望可以鞏固知識,并且能幫助到需要的人,所以我會寫的比較清晰簡單明了點,若有不對之處,請大家糾正
    2023-10-10

最新評論

华坪县| 临清市| 南涧| 资中县| 攀枝花市| 麻阳| 同心县| 双柏县| 龙川县| 吉安市| 乳山市| 沂水县| 大宁县| 临西县| 井研县| 内乡县| 静安区| 盐津县| 江阴市| 青神县| 安义县| 嵩明县| 高安市| 唐海县| 资兴市| 香港 | 三门县| 交城县| 子洲县| 常熟市| 都江堰市| 正镶白旗| 华亭县| 包头市| 荣成市| 丰都县| 宜兰市| 萝北县| 宁国市| 阳江市| 始兴县|