Skip to content

Commit 3bc4b99

Browse files
authored
Merge pull request #1359 from aprotim/fix_url_sanitization
Make URL handling consistent between links and images
2 parents da9d155 + 2353d95 commit 3bc4b99

File tree

3 files changed

+47
-20
lines changed

3 files changed

+47
-20
lines changed

lib/marked.js

+30-20
Original file line numberDiff line numberDiff line change
@@ -1034,24 +1034,8 @@ Renderer.prototype.del = function(text) {
10341034
};
10351035

10361036
Renderer.prototype.link = function(href, title, text) {
1037-
if (this.options.sanitize) {
1038-
try {
1039-
var prot = decodeURIComponent(unescape(href))
1040-
.replace(/[^\w:]/g, '')
1041-
.toLowerCase();
1042-
} catch (e) {
1043-
return text;
1044-
}
1045-
if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
1046-
return text;
1047-
}
1048-
}
1049-
if (this.options.baseUrl && !originIndependentUrl.test(href)) {
1050-
href = resolveUrl(this.options.baseUrl, href);
1051-
}
1052-
try {
1053-
href = encodeURI(href).replace(/%25/g, '%');
1054-
} catch (e) {
1037+
href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1038+
if (href === null) {
10551039
return text;
10561040
}
10571041
var out = '<a href="' + escape(href) + '"';
@@ -1063,9 +1047,11 @@ Renderer.prototype.link = function(href, title, text) {
10631047
};
10641048

10651049
Renderer.prototype.image = function(href, title, text) {
1066-
if (this.options.baseUrl && !originIndependentUrl.test(href)) {
1067-
href = resolveUrl(this.options.baseUrl, href);
1050+
href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1051+
if (href === null) {
1052+
return text;
10681053
}
1054+
10691055
var out = '<img src="' + href + '" alt="' + text + '"';
10701056
if (title) {
10711057
out += ' title="' + title + '"';
@@ -1343,6 +1329,30 @@ function edit(regex, opt) {
13431329
};
13441330
}
13451331

1332+
function cleanUrl(sanitize, base, href) {
1333+
if (sanitize) {
1334+
try {
1335+
var prot = decodeURIComponent(unescape(href))
1336+
.replace(/[^\w:]/g, '')
1337+
.toLowerCase();
1338+
} catch (e) {
1339+
return null;
1340+
}
1341+
if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
1342+
return null;
1343+
}
1344+
}
1345+
if (base && !originIndependentUrl.test(href)) {
1346+
href = resolveUrl(base, href);
1347+
}
1348+
try {
1349+
href = encodeURI(href).replace(/%25/g, '%');
1350+
} catch (e) {
1351+
return null;
1352+
}
1353+
return href;
1354+
}
1355+
13461356
function resolveUrl(base, href) {
13471357
if (!baseUrls[' ' + base]) {
13481358
// we can ignore everything in base after the last slash of its path component,

test/new/images.html

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<p>Image</p>
2+
<p>Image</p>
3+
<p>Image</p>
4+
<p>Image</p>
5+
<p>Image</p>

test/new/images.md

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
sanitize: true
3+
---
4+
![Image](javascript:alert)
5+
6+
![Image](vbscript:alert)
7+
8+
![Image](javascript&colon;alert&#40;1&#41;)
9+
10+
![Image](javascript&#58document;alert&#40;1&#41;)
11+
12+
![Image](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)

0 commit comments

Comments
 (0)