diff --git a/packages/react-dom-bindings/src/shared/sanitizeURL.js b/packages/react-dom-bindings/src/shared/sanitizeURL.js index b3de4657e915..d1f0e62cbac7 100644 --- a/packages/react-dom-bindings/src/shared/sanitizeURL.js +++ b/packages/react-dom-bindings/src/shared/sanitizeURL.js @@ -7,8 +7,6 @@ * @flow */ -import {disableJavaScriptURLs} from 'shared/ReactFeatureFlags'; - // A javascript: URL can contain leading C0 control or \u0020 SPACE, // and any newline or tab are filtered out as if they're not part of the URL. // https://url.spec.whatwg.org/#url-parsing @@ -22,29 +20,14 @@ import {disableJavaScriptURLs} from 'shared/ReactFeatureFlags'; const isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i; -let didWarn = false; - function sanitizeURL(url: T): T | string { // We should never have symbols here because they get filtered out elsewhere. // eslint-disable-next-line react-internal/safe-string-coercion - const stringifiedURL = '' + (url: any); - if (disableJavaScriptURLs) { - if (isJavaScriptProtocol.test(stringifiedURL)) { - // Return a different javascript: url that doesn't cause any side-effects and just - // throws if ever visited. - // eslint-disable-next-line no-script-url - return "javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')"; - } - } else if (__DEV__) { - if (!didWarn && isJavaScriptProtocol.test(stringifiedURL)) { - didWarn = true; - console.error( - 'A future version of React will block javascript: URLs as a security precaution. ' + - 'Use event handlers instead if you can. If you need to generate unsafe HTML try ' + - 'using dangerouslySetInnerHTML instead. React was passed %s.', - JSON.stringify(stringifiedURL), - ); - } + if (isJavaScriptProtocol.test('' + (url: any))) { + // Return a different javascript: url that doesn't cause any side-effects and just + // throws if ever visited. + // eslint-disable-next-line no-script-url + return "javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')"; } return url; } diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationUntrustedURL-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationUntrustedURL-test.js index 73d511985527..dfdb9ffd2375 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationUntrustedURL-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationUntrustedURL-test.js @@ -23,176 +23,6 @@ const EXPECTED_SAFE_URL = "javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')"; describe('ReactDOMServerIntegration - Untrusted URLs', () => { - // The `itRenders` helpers don't work with the gate pragma, so we have to do - // this instead. - if (gate(flags => flags.disableJavaScriptURLs)) { - it("empty test so Jest doesn't complain", () => {}); - return; - } - - function initModules() { - jest.resetModules(); - React = require('react'); - ReactDOMClient = require('react-dom/client'); - ReactDOMServer = require('react-dom/server'); - act = require('internal-test-utils').act; - - // Make them available to the helpers. - return { - ReactDOMClient, - ReactDOMServer, - }; - } - - const {resetModules, itRenders} = ReactDOMServerIntegrationUtils(initModules); - - beforeEach(() => { - resetModules(); - }); - - itRenders('a http link with the word javascript in it', async render => { - const e = await render( - Click me, - ); - expect(e.tagName).toBe('A'); - expect(e.href).toBe('http://javascript:0/thisisfine'); - }); - - itRenders('a javascript protocol href', async render => { - // Only the first one warns. The second warning is deduped. - const e = await render( -
- p0wned - p0wned again -
, - 1, - ); - expect(e.firstChild.href).toBe('javascript:notfine'); - expect(e.lastChild.href).toBe('javascript:notfineagain'); - }); - - itRenders('a javascript protocol with leading spaces', async render => { - const e = await render( - p0wned, - 1, - ); - // We use an approximate comparison here because JSDOM might not parse - // \u0000 in HTML properly. - expect(e.href).toContain('notfine'); - }); - - itRenders( - 'a javascript protocol with intermediate new lines and mixed casing', - async render => { - const e = await render( - p0wned, - 1, - ); - expect(e.href).toBe('javascript:notfine'); - }, - ); - - itRenders('a javascript protocol area href', async render => { - const e = await render( - - - , - 1, - ); - expect(e.firstChild.href).toBe('javascript:notfine'); - }); - - itRenders('a javascript protocol form action', async render => { - const e = await render(
p0wned
, 1); - expect(e.action).toBe('javascript:notfine'); - }); - - itRenders('a javascript protocol input formAction', async render => { - const e = await render( - , - 1, - ); - expect(e.getAttribute('formAction')).toBe('javascript:notfine'); - }); - - itRenders('a javascript protocol button formAction', async render => { - const e = await render( - , - 1, - ); - expect(e.getAttribute('formAction')).toBe('javascript:notfine'); - }); - - itRenders('a javascript protocol iframe src', async render => { - const e = await render(