React'in XSS korumalı olduğunu söylemeleri ne anlama geliyor?


119

Bunu React eğitiminde okudum. Ne anlama geliyor?

React güvenlidir. HTML dizeleri oluşturmuyoruz, bu nedenle XSS koruması varsayılandır.

React güvenliyse XSS saldırıları nasıl çalışır? Bu güvenliğe nasıl ulaşılır?

Yanıtlar:


194

ReactJS tasarımı gereği oldukça güvenlidir

  1. Görünümlerdeki dize değişkenleri otomatik olarak atlanır
  2. JSX ile kötü amaçlı kod içerebilen bir dize yerine olay işleyici olarak bir işlev iletirsiniz.

bu yüzden bunun gibi tipik bir saldırı işe yaramayacak

const username = "<img onerror='alert(\"Hacked!\")' src='invalid-image' />";

class UserProfilePage extends React.Component {
  render() {
    return (
      <h1> Hello {username}!</h1>
    );
  }
}

ReactDOM.render(<UserProfilePage />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

fakat ...

❗❗❗Uyarı❗❗❗

React'te kendinizi halletmeniz gereken hala bazı XSS ​​saldırı vektörleri var!

1. XSS aracılığıyla dangerouslySetInnerHTML

Kullandığınızda dangerouslySetInnerHTMLiçeriğin herhangi bir javascript içermediğinden emin olmanız gerekir. React burada sizin için hiçbir şey yapamaz.

const aboutUserText = "<img onerror='alert(\"Hacked!\");' src='invalid-image' />";

class AboutUserComponent extends React.Component {
  render() {
    return (
      <div dangerouslySetInnerHTML={{"__html": aboutUserText}} />
    );
  }
}

ReactDOM.render(<AboutUserComponent />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

2. a.href özelliği aracılığıyla XSS

Örnek 1: javascript kullanma: kod

Sonucu görmek için "Kod pasajını çalıştır" -> "Web Sitem" seçeneğini tıklayın

const userWebsite = "javascript:alert('Hacked!');";

class UserProfilePage extends React.Component {
  render() {
    return (
      <a href={userWebsite}>My Website</a>
    )
  }
}

ReactDOM.render(<UserProfilePage />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Örnek 2: Base64 kodlu verileri kullanma:

Sonucu görmek için "Kod pasajını çalıştır" -> "Web Sitem" seçeneğini tıklayın

const userWebsite = "data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGFja2VkISIpOzwvc2NyaXB0Pg==";

class UserProfilePage extends React.Component {
  render() {
    const url = userWebsite.replace(/^(javascript\:)/, "");
    return (
      <a href={url}>My Website</a>
    )
  }
}

ReactDOM.render(<UserProfilePage />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

3. Saldırgan kontrollü sahne aracılığıyla XSS

const customPropsControledByAttacker = {
  dangerouslySetInnerHTML: {
    "__html": "<img onerror='alert(\"Hacked!\");' src='invalid-image' />"
  }
};

class Divider extends React.Component {
  render() {
    return (
      <div {...customPropsControledByAttacker} />
    );
  }
}

ReactDOM.render(<Divider />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

İşte daha fazla kaynak


14
Bu cevap harika! Kod parçacıkları ve sondaki referanslarla ...! Teşekkür ederim!
Ioanna

Bu cevap yazıldıktan sonra yukarıdaki örneklerden herhangi biri React tarafından ele alındı ​​mı? Aşağıdaki slayt gösterisini okuduğumdan beri soruyorum: slideshare.net/kseniadmitrieva/… slayt # 20, 15 Kasım'da React 0.14'te sabitlenen kullanıcı kontrollü sahne
omer

@omer no ve tepki, React seviyesinde bu saldırı vektörlerine dikkat etmemeye karar verdi. İşte neden React düzeyinde github.com/facebook/react/issues/3473 ( github.com/facebook/react/issues/3473#issuecomment-91349525 , github.com/facebook/react ile işlem görmediklerini açıklayan birkaç iyi yorum var. / konular / 3473 # issuecomment-90594748 )
CyberPanda Consulting

1
@omer, bahsettiğiniz sorun bir güvenlik hatasıydı ve düzeltildi, ancak listelediğim 3. nokta bununla ilgili değil, yine de herhangi bir react sürümü altında kodumu çalıştırarak 3. nokta çalıştığını kontrol edebilirsiniz.
CyberPanda Consulting

63

React değişkenlerden sizin için otomatik olarak kaçar ... Zararlı Javascript ile string HTML üzerinden XSS enjeksiyonunu engeller. Doğal olarak, bununla birlikte girdiler de temizlenir.

Örneğin bu dizeye sahip olduğunuzu varsayalım

var htmlString = '<img src="javascript:alert('XSS!')" />';

bu dizgeyi tepki olarak oluşturmaya çalışırsanız

render() {
    return (
        <div>{htmlString}</div>
    );
}

<span>Öğe etiketi dahil tüm dizeyi sayfada kelimenin tam anlamıyla göreceksiniz . aka tarayıcıda göreceksiniz<img src="javascript:alert('XSS!')" />

kaynak html'yi görüntülerseniz görürsünüz

<span>"<img src="javascript:alert('XSS!')" />"</span>

İşte XSS saldırısının ne olduğuna dair biraz daha ayrıntı

İşaretleme ekleme render işlevinde unsurları kendiniz yaratamazsınız sürece temelde yapar Tepki ... bu varlık onlar onun adı verilen render böyle sağlayan bir işlevi var dedi dangerouslySetInnerHTML... burada bu konuda biraz daha detay


Düzenle:

Unutulmaması gereken birkaç şey var, React'in kaçtığını aşmanın yolları var. Daha yaygın bir yol, kullanıcıların bileşeniniz için sahne tanımlamasıdır. Kullanıcı girdisinden herhangi bir veriyi sahne olarak genişletmeyin!


14
Her şeyden kaçar mı? Gerçekten mi? React varsayılan olarak güvenli DEĞİLDİR, elle yapmanız ve anlamanız gereken vektörlere saldırmanız gereken birçok şey vardır. React'in yaptığı tek şey, {html} ile eklemeye çalıştığınızda html'den string'e kaçmaktır. Ancak XSS'ye izin vermenin, React'in korumadığı milyonlarca başka yol vardır. <a href="{...}" />, <img src = {...} />, <iframe src = "{...} /> ve çalıştırılabilir javascript enjekte etmeye izin veren diğer tonlarca sahne. Ve sonra style = {...} prop aracılığıyla CSS komut dosyası enjeksiyonları var. @Marty Aghajanyan'ın aşağıdaki cevabı aslında olası risklerin ana hatlarını çiziyor.
18:40

@andree yazım hatamı işaret ettiğin için teşekkürler. 3 yıllık bir gönderi. Açıkçası, React'in kaçtığını aşmanın yolları var ve her geliştirici bundan bıkmış olmalı.
John Ruddell

@John Ruddell cevabınızı düzenlediğiniz için teşekkür ederiz. Alınma ama cevabınız React'in gerçekte olduğundan daha güvenli görünmesini sağladı ve cevabınız konuyla ilgili ilk ortaya çıkanlardan biri olduğu için, sadece bunu belirtmek istedim. Ne yazık ki bu, genel ön uç (sadece React değil) güvenliğinde gördüğüm yaygın bir tema - yüzeyde her şey güvenli veya kolayca korunabilir görünüyor, ancak kazdığınızda büyük delikler ortaya çıkıyor. Temel güvenlik soruları, bir yerde özetlenen, bulması kolay cevaplara sahip olmalı, maalesef son zamanlarda benim deneyimim bu değil.
andree

Eh .. zamanla güvenlik test edilirken belgeler ortaya çıkar. Bir zamanlar yardımcı olduğumuz yanıtlar pek yardımcı olmuyor. Zor kısım, tüm yanıtları değişen teknolojiyle güncel tutmaktır
John Ruddell
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.