mirror of
				https://github.com/Redocly/redoc.git
				synced 2025-11-04 01:37:32 +03:00 
			
		
		
		
	Implement sanitization (aka untrustedSpec option)
This commit is contained in:
		
							parent
							
								
									ce1f014f62
								
							
						
					
					
						commit
						07eef93820
					
				| 
						 | 
				
			
			@ -28,6 +28,7 @@
 | 
			
		|||
  "devDependencies": {
 | 
			
		||||
    "@types/chai": "^4.0.5",
 | 
			
		||||
    "@types/cypress": "^0.1.2",
 | 
			
		||||
    "@types/dompurify": "^0.0.31",
 | 
			
		||||
    "@types/enzyme": "^2.8.10",
 | 
			
		||||
    "@types/enzyme-to-json": "^1.5.0",
 | 
			
		||||
    "@types/jest": "^20.0.8",
 | 
			
		||||
| 
						 | 
				
			
			@ -72,6 +73,7 @@
 | 
			
		|||
  "dependencies": {
 | 
			
		||||
    "@types/prop-types": "^15.5.2",
 | 
			
		||||
    "decko": "^1.2.0",
 | 
			
		||||
    "dompurify": "^1.0.2",
 | 
			
		||||
    "eventemitter3": "^2.0.3",
 | 
			
		||||
    "json-pointer": "^0.6.0",
 | 
			
		||||
    "json-schema-ref-parser": "^3.3.1",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,8 @@ import * as React from 'react';
 | 
			
		|||
import styled from '../../styled-components';
 | 
			
		||||
 | 
			
		||||
import { MarkdownRenderer } from '../../services';
 | 
			
		||||
import { ComponentWithOptions } from '../OptionsProvider';
 | 
			
		||||
import * as DOMPurify from 'dompurify';
 | 
			
		||||
 | 
			
		||||
import { markdownCss } from './styles';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -12,9 +14,10 @@ interface MarkdownProps {
 | 
			
		|||
  className?: string;
 | 
			
		||||
  raw?: boolean;
 | 
			
		||||
  components?: { [name: string]: React.ComponentClass };
 | 
			
		||||
  sanitize?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class InternalMarkdown extends React.PureComponent<MarkdownProps> {
 | 
			
		||||
class InternalMarkdown extends ComponentWithOptions<MarkdownProps> {
 | 
			
		||||
  constructor(props: MarkdownProps) {
 | 
			
		||||
    super(props);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +27,14 @@ class InternalMarkdown extends React.PureComponent<MarkdownProps> {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    let sanitize: (string) => string;
 | 
			
		||||
 | 
			
		||||
    if (this.props.sanitize || this.options.untrustedSpec) {
 | 
			
		||||
      sanitize = html => DOMPurify.sanitize(html);
 | 
			
		||||
    } else {
 | 
			
		||||
      sanitize = html => html;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const renderer = new MarkdownRenderer();
 | 
			
		||||
    const { source, raw, className, components, inline, dense } = this.props;
 | 
			
		||||
    const parts = components
 | 
			
		||||
| 
						 | 
				
			
			@ -40,7 +51,7 @@ class InternalMarkdown extends React.PureComponent<MarkdownProps> {
 | 
			
		|||
      return (
 | 
			
		||||
        <span
 | 
			
		||||
          className={className + appendClass}
 | 
			
		||||
          dangerouslySetInnerHTML={{ __html: parts[0] as string }}
 | 
			
		||||
          dangerouslySetInnerHTML={{ __html: sanitize(parts[0] as string) }}
 | 
			
		||||
        />
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +61,7 @@ class InternalMarkdown extends React.PureComponent<MarkdownProps> {
 | 
			
		|||
        {parts.map(
 | 
			
		||||
          (part, idx) =>
 | 
			
		||||
            typeof part === 'string' ? (
 | 
			
		||||
              <div key={idx} dangerouslySetInnerHTML={{ __html: part }} />
 | 
			
		||||
              <div key={idx} dangerouslySetInnerHTML={{ __html: sanitize(part) }} />
 | 
			
		||||
            ) : (
 | 
			
		||||
              <part.component key={idx} {...part.attrs} />
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@ export interface RedocRawOptions {
 | 
			
		|||
  noAutoAuth?: boolean | string;
 | 
			
		||||
  nativeScrollbars?: boolean | string;
 | 
			
		||||
  pathInMiddlePanel?: boolean | string;
 | 
			
		||||
  untrustedSpec?: boolean | string;
 | 
			
		||||
  hideLoading?: boolean | string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -29,6 +30,7 @@ export class RedocNormalizedOptions {
 | 
			
		|||
  noAutoAuth: boolean;
 | 
			
		||||
  nativeScrollbars: boolean;
 | 
			
		||||
  pathInMiddlePanel: boolean;
 | 
			
		||||
  untrustedSpec: boolean;
 | 
			
		||||
 | 
			
		||||
  constructor(raw: RedocRawOptions) {
 | 
			
		||||
    this.theme = { ...(raw.theme || {}), ...defaultTheme }; // todo: merge deep
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +41,7 @@ export class RedocNormalizedOptions {
 | 
			
		|||
    this.noAutoAuth = argValueToBoolean(raw.noAutoAuth);
 | 
			
		||||
    this.nativeScrollbars = argValueToBoolean(raw.nativeScrollbars);
 | 
			
		||||
    this.pathInMiddlePanel = argValueToBoolean(raw.pathInMiddlePanel);
 | 
			
		||||
    this.untrustedSpec = argValueToBoolean(raw.untrustedSpec);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static normalizeExpandResponses(value: RedocRawOptions['expandResponses']) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,10 @@
 | 
			
		|||
  version "0.1.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/cypress/-/cypress-0.1.3.tgz#1783db79f0d1a44b85aae6a473104e2d7987e022"
 | 
			
		||||
 | 
			
		||||
"@types/dompurify@^0.0.31":
 | 
			
		||||
  version "0.0.31"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-0.0.31.tgz#f152d5a81f2b5625e29f11eb016cd9b301d0d4b4"
 | 
			
		||||
 | 
			
		||||
"@types/enzyme-to-json@^1.5.0":
 | 
			
		||||
  version "1.5.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/enzyme-to-json/-/enzyme-to-json-1.5.0.tgz#0b53c4c8479050e76a38ad298fb2672a7241fad3"
 | 
			
		||||
| 
						 | 
				
			
			@ -1774,6 +1778,10 @@ domhandler@^2.3.0:
 | 
			
		|||
  dependencies:
 | 
			
		||||
    domelementtype "1"
 | 
			
		||||
 | 
			
		||||
dompurify@^1.0.2:
 | 
			
		||||
  version "1.0.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-1.0.2.tgz#7cf47d57614324a9723a1ba69143eeb7d3c617ac"
 | 
			
		||||
 | 
			
		||||
domutils@1.1:
 | 
			
		||||
  version "1.1.6"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.1.6.tgz#bddc3de099b9a2efacc51c623f28f416ecc57485"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user