Merge pull request #3165 from shockey/bug/3163-markdown-xss

Sanitize Markdown inputs
This commit is contained in:
shockey
2017-06-01 23:47:18 -07:00
committed by GitHub
13 changed files with 289 additions and 148 deletions

389
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -67,6 +67,7 @@
"redux-immutable": "3.0.8",
"redux-logger": "*",
"reselect": "2.5.3",
"sanitize-html": "^1.14.1",
"serialize-error": "2.0.0",
"shallowequal": "0.2.2",
"swagger-client": "~3.0.12",

View File

@@ -53,8 +53,7 @@ export default class ApiKeyAuth extends React.Component {
<h4>Api key authorization<JumpToPath path={[ "securityDefinitions", name ]} /></h4>
{ value && <h6>Authorized</h6>}
<Row>
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}}
source={ schema.get("description") } />
<Markdown source={ schema.get("description") } />
</Row>
<Row>
<p>Name: <code>{ schema.get("name") }</code></p>

View File

@@ -59,8 +59,7 @@ export default class BasicAuth extends React.Component {
<h4>Basic authorization<JumpToPath path={[ "securityDefinitions", name ]} /></h4>
{ username && <h6>Authorized</h6> }
<Row>
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}}
source={ schema.get("description") } />
<Markdown source={ schema.get("description") } />
</Row>
<Row>
<label>Username:</label>

View File

@@ -102,8 +102,7 @@ export default class Oauth2 extends React.Component {
<div>
<h4>OAuth2.0 <JumpToPath path={[ "securityDefinitions", name ]} /></h4>
{ !this.state.appName ? null : <h5>Application: { this.state.appName } </h5> }
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}}
source={ schema.get("description") } />
<Markdown source={ schema.get("description") } />
{ isAuthorized && <h6>Authorized</h6> }

View File

@@ -99,7 +99,7 @@ export default class Info extends React.Component {
</hgroup>
<div className="description">
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}} source={ description } />
<Markdown source={ description } />
</div>
{

View File

@@ -1,13 +1,10 @@
import React, { PropTypes } from "react"
import OriCollapse from "react-collapse"
import _Markdown from "react-remarkable"
function xclass(...args) {
return args.filter(a => !!a).join(" ").trim()
}
export const Markdown = _Markdown
export class Container extends React.Component {
render() {
let { fullscreen, full, ...rest } = this.props

View File

@@ -173,7 +173,7 @@ export default class Operation extends React.Component {
{ description &&
<div className="opblock-description-wrapper">
<div className="opblock-description">
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}} source={ description } />
<Markdown source={ description } />
</div>
</div>
}

View File

@@ -99,8 +99,7 @@ export default class ParameterRow extends Component {
</td>
<td className="col parameters-col_description">
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}}
source={ param.get("description") }/>
<Markdown source={ param.get("description") }/>
{(isFormData && !isFormDataSupported) && <div>Error: your browser does not support FormData</div>}
{ bodyParam || !isExecute ? null

View File

@@ -0,0 +1,6 @@
# Providers
Providers are generic bridges to third-party components. They provide two benefits:
1. ability for plugins to override third-party components, because providers are loaded through `getComponent`
2. allows us to avoid painting ourselves into a corner with a third-party component

View File

@@ -0,0 +1,17 @@
import React, { PropTypes } from "react"
import Remarkable from "react-remarkable"
import sanitize from "sanitize-html"
function Markdown({ source }) {
const sanitized = sanitize(source)
return <Remarkable
options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}}
source={sanitized}
></Remarkable>
}
Markdown.propTypes = {
source: PropTypes.string.isRequired
}
export default Markdown

View File

@@ -76,7 +76,7 @@ export default class Response extends React.Component {
<td className="col response-col_description">
<div className="response-col_description__inner">
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}} source={ response.get( "description" ) } />
<Markdown source={ response.get( "description" ) } />
</div>
{ example ? (

View File

@@ -46,6 +46,8 @@ import Model from "core/components/model"
import Models from "core/components/models"
import TryItOutButton from "core/components/try-it-out-button"
import Markdown from "core/components/providers/markdown"
import BaseLayout from "core/components/layouts/base"
import * as LayoutUtils from "core/components/layout-utils"
@@ -89,6 +91,7 @@ export default function() {
model: Model,
models: Models,
TryItOutButton,
Markdown,
BaseLayout
}
}