Skip to content

Commit 19d4b37

Browse files
committed
fix: html script, style, and comment escaping
1 parent 33f925a commit 19d4b37

60 files changed

Lines changed: 394 additions & 11 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/blue-dragons-see.md

Lines changed: 14 additions & 0 deletions

.changeset/frank-memes-knock.md

Lines changed: 13 additions & 0 deletions
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"use strict";
2+
const unsafeCharsReg = />/g;
3+
const replaceMatch = () => ">";
4+
const escape = (str) =>
5+
unsafeCharsReg.test(str) ? str.replace(unsafeCharsReg, replaceMatch) : str;
6+
7+
/**
8+
* Escapes content placed inside an <html-comment> tag.
9+
*
10+
* For example:
11+
* <html-comment>${userInput}</html-comment>
12+
*
13+
* Without escaping, a value of `><script>alert(1)</script><!--` would close the comment early.
14+
*/
15+
module.exports = function escapeCommentHelper(value) {
16+
return escape(value + "");
17+
};

packages/runtime-class/src/runtime/html/helpers/escape-script-placeholder.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"use strict";
2-
const unsafeCharsReg = /<\/script/g;
2+
const unsafeCharsReg = /<\/script/gi;
33
const replaceMatch = () => "\\x3C/script";
44
const escape = (str) =>
55
unsafeCharsReg.test(str) ? str.replace(unsafeCharsReg, replaceMatch) : str;

packages/runtime-class/src/runtime/html/helpers/escape-style-placeholder.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"use strict";
2-
const unsafeCharsReg = /<\/style/g;
2+
const unsafeCharsReg = /<\/style/gi;
33
const replaceMatch = () => "\\3C/style";
44
const escape = (str) =>
55
unsafeCharsReg.test(str) ? str.replace(unsafeCharsReg, replaceMatch) : str;

packages/runtime-class/src/translator/taglib/core/translate-html-comment.js

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
assertNoArgs,
44
assertNoAttributes,
55
assertNoParams,
6+
importDefault,
67
} from "@marko/compiler/babel-utils";
78

89
import writeHTML from "../../util/html-out-write";
@@ -15,11 +16,30 @@ export function enter(path) {
1516
assertNoAttributes(path);
1617

1718
if (path.hub.file.markoOpts.output === "html") {
18-
path.replaceWithMultiple([
19-
writeHTML`<!--`,
20-
...path.node.body.body,
21-
writeHTML`-->`,
22-
]);
19+
const { file } = path.hub;
20+
const nodes = [writeHTML`<!--`];
21+
22+
for (const child of path.node.body.body) {
23+
if (t.isMarkoText(child)) {
24+
nodes.push(child);
25+
} else if (t.isMarkoPlaceholder(child)) {
26+
const escapeFnModule = child.escape
27+
? "marko/src/runtime/html/helpers/escape-comment-placeholder.js"
28+
: "marko/src/runtime/helpers/to-string.js";
29+
const escapeFnAlias = child.escape
30+
? "marko_escapeComment"
31+
: "marko_to_string";
32+
nodes.push(
33+
writeHTML`${t.callExpression(
34+
importDefault(file, escapeFnModule, escapeFnAlias),
35+
[child.value],
36+
)}`,
37+
);
38+
}
39+
}
40+
41+
nodes.push(writeHTML`-->`);
42+
path.replaceWithMultiple(nodes.filter(Boolean));
2343
} else {
2444
const templateQuasis = [];
2545
const templateExpressions = [];
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<!----&gt;-->
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<html-comment>${input.text}</html-comment>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
exports.templateData = {
2+
text: "-->",
3+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<!--"-->"-->

0 commit comments

Comments
 (0)