fix: mitigate "sequential @import chaining" vulnerability (#5616)
* `test/e2e-cypress/tests/features/xss/` -> `test/e2e-cypress/tests/security` * add tests * filter <style> tags out of Markdown fields * initialize OAuth inputs without applying `value` attribute
This commit is contained in:
@@ -96,6 +96,7 @@ export default class Oauth2 extends React.Component {
|
||||
const AuthError = getComponent("authError")
|
||||
const JumpToPath = getComponent("JumpToPath", true)
|
||||
const Markdown = getComponent( "Markdown" )
|
||||
const InitializedInput = getComponent("InitializedInput")
|
||||
|
||||
const { isOAS3 } = specSelectors
|
||||
|
||||
@@ -170,10 +171,10 @@ export default class Oauth2 extends React.Component {
|
||||
{
|
||||
isAuthorized ? <code> ****** </code>
|
||||
: <Col tablet={10} desktop={10}>
|
||||
<input id="client_id"
|
||||
<InitializedInput id="client_id"
|
||||
type="text"
|
||||
required={ flow === PASSWORD }
|
||||
value={ this.state.clientId }
|
||||
initialValue={ this.state.clientId }
|
||||
data-name="clientId"
|
||||
onChange={ this.onInputChange }/>
|
||||
</Col>
|
||||
@@ -187,8 +188,8 @@ export default class Oauth2 extends React.Component {
|
||||
{
|
||||
isAuthorized ? <code> ****** </code>
|
||||
: <Col tablet={10} desktop={10}>
|
||||
<input id="client_secret"
|
||||
value={ this.state.clientSecret }
|
||||
<InitializedInput id="client_secret"
|
||||
initialValue={ this.state.clientSecret }
|
||||
type="text"
|
||||
data-name="clientSecret"
|
||||
onChange={ this.onInputChange }/>
|
||||
|
||||
36
src/core/components/initialized-input.jsx
Normal file
36
src/core/components/initialized-input.jsx
Normal file
@@ -0,0 +1,36 @@
|
||||
// This component provides an interface that feels like an uncontrolled input
|
||||
// to consumers, while providing a `defaultValue` interface that initializes
|
||||
// the input's value using JavaScript value property APIs instead of React's
|
||||
// vanilla[0] implementation that uses HTML value attributes.
|
||||
//
|
||||
// This is useful in situations where we don't want to surface an input's value
|
||||
// into the HTML/CSS-exposed side of the DOM, for example to avoid sequential
|
||||
// input chaining attacks[1].
|
||||
//
|
||||
// [0]: https://github.com/facebook/react/blob/baff5cc2f69d30589a5dc65b089e47765437294b/fixtures/dom/src/components/fixtures/text-inputs/README.md
|
||||
// [1]: https://github.com/d0nutptr/sic
|
||||
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export default class InitializedInput extends React.Component {
|
||||
componentDidMount() {
|
||||
// Set the element's `value` property (*not* the `value` attribute)
|
||||
// once, on mount, if an `initialValue` is provided.
|
||||
if(this.props.initialValue) {
|
||||
this.inputRef.value = this.props.initialValue
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
// Filter out `value` and `defaultValue`, since we have our own
|
||||
// `initialValue` interface that we provide.
|
||||
// eslint-disable-next-line no-unused-vars, react/prop-types
|
||||
const { value, defaultValue, ...otherProps } = this.props
|
||||
return <input {...otherProps} ref={c => this.inputRef = c} />
|
||||
}
|
||||
}
|
||||
|
||||
InitializedInput.propTypes = {
|
||||
initialValue: PropTypes.string
|
||||
}
|
||||
@@ -51,6 +51,7 @@ export default Markdown
|
||||
|
||||
export function sanitizer(str) {
|
||||
return DomPurify.sanitize(str, {
|
||||
ADD_ATTR: ["target"]
|
||||
ADD_ATTR: ["target"],
|
||||
FORBID_TAGS: ["style"],
|
||||
})
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ import Headers from "core/components/headers"
|
||||
import Errors from "core/components/errors"
|
||||
import ContentType from "core/components/content-type"
|
||||
import Overview from "core/components/overview"
|
||||
import InitializedInput from "core/components/initialized-input"
|
||||
import Info, {
|
||||
InfoUrl,
|
||||
InfoBasePath
|
||||
@@ -105,6 +106,7 @@ export default function() {
|
||||
basicAuth: BasicAuth,
|
||||
clear: Clear,
|
||||
liveResponse: LiveResponse,
|
||||
InitializedInput,
|
||||
info: Info,
|
||||
InfoContainer,
|
||||
JumpToPath,
|
||||
|
||||
Reference in New Issue
Block a user