Skip to content

Commit 3a6a6d6

Browse files
committed
Fix breaking out of comments
1 parent 0ff62a4 commit 3a6a6d6

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

Diff for: lib/comment.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
'use strict'
22

3+
var xtend = require('xtend')
4+
var entities = require('stringify-entities')
5+
36
module.exports = serializeComment
47

8+
// See: <https://html.spec.whatwg.org/multipage/syntax.html#comments>
9+
var breakout = /^>|^->|<!--|-->|--!>|<!-$/g
10+
var subset = ['<', '>']
11+
512
function serializeComment(ctx, node) {
6-
return '<!--' + node.value + '-->'
13+
return '<!--' + node.value.replace(breakout, encode) + '-->'
14+
15+
function encode($0) {
16+
return entities($0, xtend(ctx.entities, {subset: subset}))
17+
}
718
}

Diff for: test/comment.js

+30-7
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,38 @@ test('`comment`', function(t) {
1414
t.deepEqual(
1515
to(u('comment', 'AT&T')),
1616
'<!--AT&T-->',
17-
'should not encode `comment`s (#1)'
17+
'should not encode `comment`s'
1818
)
1919

20-
// No way to get around this.
21-
t.deepEqual(
22-
to(u('comment', '-->')),
23-
'<!---->-->',
24-
'should not encode `comment`s (#2)'
25-
)
20+
// https://html.spec.whatwg.org/multipage/syntax.html#comments
21+
// Optionally, text, with the additional restriction that the text must not
22+
// start with the string `>`, nor start with the string `->`, nor contain the
23+
// strings `<!--`, `-->`, or `--!>`, nor end with the string `<!-`.
24+
var matrix = [
25+
['>a', '&#x3E;a'],
26+
['->a', '-&#x3E;a'],
27+
['a<!--b', 'a&#x3C;!--b'],
28+
['a-->b', 'a--&#x3E;b'],
29+
['a--!>b', 'a--!&#x3E;b'],
30+
['a<!-', 'a&#x3C;!-'],
31+
// Not at start:
32+
['a>'],
33+
['a->'],
34+
// Not at end:
35+
['a<!-b']
36+
]
37+
38+
matrix.forEach(function(d) {
39+
var input = d[0]
40+
var output = d[1] || d[0]
41+
var ok = d[1] === undefined
42+
43+
t.deepEqual(
44+
to(u('comment', input)),
45+
'<!--' + output + '-->',
46+
'security: should ' + (ok ? 'allow' : 'prevent') + ' `' + input + '`'
47+
)
48+
})
2649

2750
t.end()
2851
})

Diff for: test/security.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ var to = require('..')
88
test('security', function(t) {
99
t.equal(
1010
to(u('root', [u('comment', '--><script>alert(1)</script><!--')])),
11-
'<!----><script>alert(1)</script><!---->',
12-
'comments can break out of their context (unsafe)'
11+
'<!----&#x3E;<script>alert(1)</script>&#x3C;!---->',
12+
'comments cannot break out of their context (safe)'
1313
)
1414

1515
t.equal(

0 commit comments

Comments
 (0)