Skip to content

Commit 08ead9e

Browse files
committed
Refactor to improve safe URL detection
1 parent a1fc6d9 commit 08ead9e

2 files changed

Lines changed: 7 additions & 57 deletions

File tree

‎lib/index.js‎

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
import{unreachable}from'devlop'
8282
import{toJsxRuntime}from'hast-util-to-jsx-runtime'
8383
import{urlAttributes}from'html-url-attributes'
84+
import{sanitizeUri}from'micromark-util-sanitize-uri'
8485
// @ts-expect-error: untyped.
8586
import{Fragment,jsx,jsxs}from'react/jsx-runtime'
8687
importremarkParsefrom'remark-parse'
@@ -89,8 +90,6 @@ import {unified} from 'unified'
8990
import{visit}from'unist-util-visit'
9091
import{VFile}from'vfile'
9192

92-
constsafeProtocols=['http','https','mailto','tel']
93-
9493
constown={}.hasOwnProperty
9594
constchangelog=
9695
'https://github.com/remarkjs/react-markdown/blob/main/changelog.md'
@@ -99,6 +98,7 @@ const changelog =
9998
constemptyPlugins=[]
10099
/** @type {Readonly<RemarkRehypeOptions>} */
101100
constemptyRemarkRehypeOptions={allowDangerousHtml: true}
101+
constsafeProtocol=/^(https?|ircs?|mailto|xmpp)$/i
102102

103103
// Mutable because we `delete` any time it’s used and a message is sent.
104104
/** @type {ReadonlyArray<Readonly<Deprecation>>} */
@@ -293,38 +293,5 @@ export function Markdown(options) {
293293
* Safe URL.
294294
*/
295295
exportfunctiondefaultUrlTransform(value){
296-
consturl=value.trim()
297-
constfirst=url.charAt(0)
298-
299-
if(first==='#'||first==='/'){
300-
returnurl
301-
}
302-
303-
constcolon=url.indexOf(':')
304-
if(colon===-1){
305-
returnurl
306-
}
307-
308-
for(constprotocolofsafeProtocols){
309-
if(
310-
colon===protocol.length&&
311-
url.slice(0,protocol.length).toLowerCase()===protocol
312-
){
313-
returnurl
314-
}
315-
}
316-
317-
letindex=url.indexOf('?')
318-
if(index!==-1&&colon>index){
319-
returnurl
320-
}
321-
322-
index=url.indexOf('#')
323-
if(index!==-1&&colon>index){
324-
returnurl
325-
}
326-
327-
// To do: is there an alternative?
328-
// eslint-disable-next-line no-script-url
329-
return'javascript:void(0)'
296+
returnsanitizeUri(value,safeProtocol)
330297
}

‎test.jsx‎

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -288,43 +288,31 @@ test('react-markdown', async function (t) {
288288
})
289289

290290
awaitt.test('should make a `javascript:` URL safe',function(){
291-
constconsoleError=console.error
292-
console.error=noop
293291
assert.equal(
294292
asHtml(<Markdownchildren="[](javascript:alert(1))"/>),
295-
'<p><a href="javascript:void(0)"></a></p>'
293+
'<p><a href=""></a></p>'
296294
)
297-
console.error=consoleError
298295
})
299296

300297
awaitt.test('should make a `vbscript:` URL safe',function(){
301-
constconsoleError=console.error
302-
console.error=noop
303298
assert.equal(
304299
asHtml(<Markdownchildren="[](vbscript:alert(1))"/>),
305-
'<p><a href="javascript:void(0)"></a></p>'
300+
'<p><a href=""></a></p>'
306301
)
307-
console.error=consoleError
308302
})
309303

310304
awaitt.test('should make a `VBSCRIPT:` URL safe',function(){
311-
constconsoleError=console.error
312-
console.error=noop
313305
assert.equal(
314306
asHtml(<Markdownchildren="[](VBSCRIPT:alert(1))"/>),
315-
'<p><a href="javascript:void(0)"></a></p>'
307+
'<p><a href=""></a></p>'
316308
)
317-
console.error=consoleError
318309
})
319310

320311
awaitt.test('should make a `file:` URL safe',function(){
321-
constconsoleError=console.error
322-
console.error=noop
323312
assert.equal(
324313
asHtml(<Markdownchildren="[](file:///etc/passwd)"/>),
325-
'<p><a href="javascript:void(0)"></a></p>'
314+
'<p><a href=""></a></p>'
326315
)
327-
console.error=consoleError
328316
})
329317

330318
awaitt.test('should allow an empty URL',function(){
@@ -1054,8 +1042,3 @@ test('react-markdown', async function (t) {
10541042
functionasHtml(input){
10551043
returnrenderToStaticMarkup(input)
10561044
}
1057-
1058-
/**
1059-
* @returns {undefined}
1060-
*/
1061-
functionnoop(){}

0 commit comments

Comments
 (0)