How to safely render html in react?

前端 未结 3 1826
温柔的废话
温柔的废话 2020-12-13 18:30

I\'ve got some user generated html markup from a text area and I\'d like to render it on another part of the screen. The markup is saved as a string in the props of the comp

相关标签:
3条回答
  • 2020-12-13 18:51

    An example based on the accepted answer:

    import sanitizeHtml from 'sanitize-html';
    
    const MyComponent = () => {
      dirty = '<a href="my-slug" target="_blank" onClick="evil()">click</a>';
      const clean = sanitizeHtml(dirty, {
        allowedTags: ['b', 'i', 'em', 'strong', 'a'],
        allowedAttributes: {
          a: ['href', 'target']
        }
      });
      return (
        <div 
          dangerouslySetInnerHTML={{__html: clean}}
        />
      );
    };
    

    MyComponent renders div containing the link without onClick="evil()":

    <a href="my-slug" target="_blank">click</a>
    
    0 讨论(0)
  • 2020-12-13 19:13

    Sanitize the html using the sanitize-html module, and render the sanitized string using dangerouslySetInnerHTML.

    You can create a simple wrapper component:

    const defaultOptions = {
      allowedTags: [ 'b', 'i', 'em', 'strong', 'a' ],
      allowedAttributes: {
        'a': [ 'href' ]
      },
      allowedIframeHostnames: ['www.youtube.com']
    };
    
    const sanitize = (dirty, options) => ({
      __html: sanitizeHtml(
        dirty, 
        options: { ...defaultOptions, ...options }
      )
    });
    
    const SanitizeHTML = ({ html, options }) => (
      <div dangerouslySetInnerHTML={sanitize(html, options)} />
    );
    

    Usage:

    <SanitizeHTML html="<img src=x onerror=alert('img') />" />
    

    You can also use react-sanitized-html's SanitizedHTML component, which is a react wrapper around sanitize-html:

    <SanitizedHTML
      allowedAttributes={{ 'a': ['href'] }}
      allowedTags={['a']}
      html={ `<a href="http://bing.com/">Bing</a>` }
    />
    
    0 讨论(0)
  • 2020-12-13 19:16

    For XSS filtering, there is a good alternative to sanitize-html written by security people, called dompurify.

    Here is how the wrapper from https://stackoverflow.com/a/38663813/1762849 would look with DOMPurify:

    const defaultOptions = {
      ALLOWED_TAGS: [ 'b', 'i', 'em', 'strong', 'a' ], 
      ALLOWED_ATTR: ['href']
    };
    
    const sanitize = (dirty, options) => ({
      __html: DOMPurify.sanitize(
        dirty, 
        { ...defaultOptions, ...options }
      )
    });
    
    const SanitizeHTML = ({ html, options }) => (
      <div dangerouslySetInnerHTML={sanitize(html, options)} />
    );
    

    Usage:

    <SanitizeHTML html="<img src=x onerror=alert('img') />" />
    

    Also, if you you need to sanitize HTML on client and server, consider using the isomophic-dompurify module which unifies use of DOMPurify on frontend and backend.

    0 讨论(0)
提交回复
热议问题