diff --git a/scripts/fiber/tests-passing.txt b/scripts/fiber/tests-passing.txt index ed380ce55e18c..002f3c042ff75 100644 --- a/scripts/fiber/tests-passing.txt +++ b/scripts/fiber/tests-passing.txt @@ -664,6 +664,8 @@ src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js * should properly escape text content and attributes values * unmounts children before unsetting DOM node info * should warn about the `onScroll` issue when unsupported (IE8) +* should throw when an invalid tag name is used server-side +* should throw when an attack vector is used server-side * should throw when an invalid tag name is used * should throw when an attack vector is used * should warn about props that are no longer supported diff --git a/src/renderers/dom/fiber/ReactDOMFiberComponent.js b/src/renderers/dom/fiber/ReactDOMFiberComponent.js index 18b3341920e95..44afff611e870 100644 --- a/src/renderers/dom/fiber/ReactDOMFiberComponent.js +++ b/src/renderers/dom/fiber/ReactDOMFiberComponent.js @@ -279,21 +279,6 @@ var voidElementTags = { ...omittedCloseTags, }; -// We accept any tag to be rendered but since this gets injected into arbitrary -// HTML, we want to make sure that it's a safe tag. -// http://www.w3.org/TR/REC-xml/#NT-Name - -var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset -var validatedTagCache = {}; -var hasOwnProperty = {}.hasOwnProperty; - -function validateDangerousTag(tag) { - if (!hasOwnProperty.call(validatedTagCache, tag)) { - invariant(VALID_TAG_REGEX.test(tag), 'Invalid tag: %s', tag); - validatedTagCache[tag] = true; - } -} - function isCustomComponent(tagName, props) { return tagName.indexOf('-') >= 0 || props.is != null; } @@ -488,8 +473,6 @@ var ReactDOMFiberComponent = { rootContainerElement : Element, parentNamespace : string | null ) : Element { - validateDangerousTag(type); - // We create tags in the namespace of their parent container, except HTML // tags get no namespace. var ownerDocument = rootContainerElement.ownerDocument; diff --git a/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js b/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js index 0ab5a21e38927..6c5661e6663d1 100644 --- a/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js +++ b/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js @@ -1207,23 +1207,37 @@ describe('ReactDOMComponent', () => { }); describe('tag sanitization', () => { - it('should throw when an invalid tag name is used', () => { + it('should throw when an invalid tag name is used server-side', () => { var hackzor = React.createElement('script tag'); expect( - () => ReactTestUtils.renderIntoDocument(hackzor) + () => ReactDOMServer.renderToString(hackzor) ).toThrowError( 'Invalid tag: script tag' ); }); - it('should throw when an attack vector is used', () => { + it('should throw when an attack vector is used server-side', () => { var hackzor = React.createElement('div> ReactTestUtils.renderIntoDocument(hackzor) + () => ReactDOMServer.renderToString(hackzor) ).toThrowError( 'Invalid tag: div> { + var hackzor = React.createElement('script tag'); + expect( + () => ReactTestUtils.renderIntoDocument(hackzor) + ).toThrow(); + }); + + it('should throw when an attack vector is used', () => { + var hackzor = React.createElement('div> ReactTestUtils.renderIntoDocument(hackzor) + ).toThrow(); + }); }); describe('nesting validation', () => { diff --git a/src/renderers/dom/stack/client/ReactDOMComponent.js b/src/renderers/dom/stack/client/ReactDOMComponent.js index ee88dce213638..b23a736b083c2 100644 --- a/src/renderers/dom/stack/client/ReactDOMComponent.js +++ b/src/renderers/dom/stack/client/ReactDOMComponent.js @@ -413,7 +413,6 @@ var globalIdCounter = 1; */ function ReactDOMComponent(element) { var tag = element.type; - validateDangerousTag(tag); this._currentElement = element; this._tag = tag.toLowerCase(); this._namespaceURI = null; @@ -605,6 +604,7 @@ ReactDOMComponent.Mixin = { this._createInitialChildren(transaction, props, context, lazyTree); mountImage = lazyTree; } else { + validateDangerousTag(this._tag); var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction, props); var tagContent = this._createContentMarkup(transaction, props, context); if (!tagContent && omittedCloseTags[this._tag]) {