Przeczytałem to w samouczku React. Co to znaczy?
Reakcja jest bezpieczna. Nie generujemy ciągów HTML, więc ochrona XSS jest domyślna.
Jak działają ataki XSS, jeśli React jest bezpieczny? W jaki sposób osiąga się to bezpieczeństwo?
Od tego czasu ReactJS jest całkiem bezpieczny z założenia
więc typowy atak taki jak ten nie zadziała
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>
ale ...
dangerouslySetInnerHTML
Kiedy używasz dangerouslySetInnerHTML
, musisz upewnić się, że zawartość nie zawiera żadnego javascript. React nie może tutaj nic dla Ciebie zrobić.
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>
Przykład 1: użycie javascript: code
Kliknij „Uruchom fragment kodu” -> „Moja witryna”, aby zobaczyć wynik
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>
Przykład 2: Korzystanie z danych zakodowanych w formacie base64:
Kliknij „Uruchom fragment kodu” -> „Moja witryna”, aby zobaczyć wynik
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>
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>
Oto więcej zasobów
React automatycznie wymyka zmienne za Ciebie ... Zapobiega iniekcji XSS przez ciąg znaków HTML ze złośliwym Javascriptem. Oczywiście, dane wejściowe są oczyszczane razem z tym.
Na przykład powiedzmy, że masz ten ciąg
jeśli spróbujesz wyrenderować ten ciąg w reakcji
dosłownie zobaczysz na stronie cały ciąg, łącznie ze
<span>
znacznikiem elementu. aka w przeglądarce, którą zobaczysz<img src="javascript:alert('XSS!')" />
jeśli wyświetlisz źródłowy html, zobaczysz
Oto więcej szczegółów na temat tego, czym jest atak XSS
React w zasadzie sprawia, że nie możesz wstawiać znaczników, chyba że sam utworzysz elementy w funkcji renderowania ... to powiedziawszy, że mają funkcję, która umożliwia takie renderowanie, nazywa się
dangerouslySetInnerHTML
... tutaj jest więcej szczegółów na ten tematEdytować:
Kilka rzeczy do zapamiętania, są sposoby na obejście tego, co ucieka React. Jeszcze jednym popularnym sposobem jest definiowanie przez użytkowników właściwości Twojego komponentu. Nie rozszerzaj żadnych danych wprowadzanych przez użytkownika jako rekwizytów!
źródło