-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathsvg_text_utils_test.js
138 lines (106 loc) · 4.44 KB
/
svg_text_utils_test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
var d3 = require('d3');
var util = require('@src/lib/svg_text_utils');
describe('svg+text utils', function() {
'use strict';
describe('convertToTspans should', function() {
function mockTextSVGElement(txt) {
return d3.select('body')
.append('svg')
.attr('id', 'text')
.append('text')
.text(txt)
.call(util.convertToTspans)
.attr('transform', 'translate(50,50)');
}
function assertAnchorLink(node, href) {
var a = node.select('a');
expect(a.attr('xlink:href')).toBe(href);
expect(a.attr('xlink:show')).toBe(href === null ? null : 'new');
}
function assertAnchorAttrs(node) {
var a = node.select('a');
var WHITE_LIST = ['xlink:href', 'xlink:show', 'style'],
attrs = listAttributes(a.node());
// check that no other attribute are found in anchor,
// which can be lead to XSS attacks.
var hasWrongAttr = attrs.some(function(attr) {
return WHITE_LIST.indexOf(attr) === -1;
});
expect(hasWrongAttr).toBe(false);
}
function listAttributes(node) {
var items = Array.prototype.slice.call(node.attributes);
var attrs = items.map(function(item) {
return item.name;
});
return attrs;
}
afterEach(function() {
d3.select('#text').remove();
});
it('check for XSS attack in href', function() {
var node = mockTextSVGElement(
'<a href="javascript:alert(\'attack\')">XSS</a>'
);
expect(node.text()).toEqual('XSS');
assertAnchorAttrs(node);
assertAnchorLink(node, null);
});
it('check for XSS attack in href (with plenty of white spaces)', function() {
var node = mockTextSVGElement(
'<a href = " javascript:alert(\'attack\')">XSS</a>'
);
expect(node.text()).toEqual('XSS');
assertAnchorAttrs(node);
assertAnchorLink(node, null);
});
it('whitelist http hrefs', function() {
var node = mockTextSVGElement(
'<a href="http://bl.ocks.org/">bl.ocks.org</a>'
);
expect(node.text()).toEqual('bl.ocks.org');
assertAnchorAttrs(node);
assertAnchorLink(node, 'http://bl.ocks.org/');
});
it('whitelist https hrefs', function() {
var node = mockTextSVGElement(
'<a href="https://plot.ly">plot.ly</a>'
);
expect(node.text()).toEqual('plot.ly');
assertAnchorAttrs(node);
assertAnchorLink(node, 'https://plot.ly');
});
it('whitelist mailto hrefs', function() {
var node = mockTextSVGElement(
'<a href="mailto:[email protected]">support</a>'
);
expect(node.text()).toEqual('support');
assertAnchorAttrs(node);
assertAnchorLink(node, 'mailto:[email protected]');
});
it('wrap XSS attacks in href', function() {
var textCases = [
'<a href="XSS\" onmouseover="alert(1)\" style="font-size:300px">Subtitle</a>',
'<a href="XSS" onmouseover="alert(1)" style="font-size:300px">Subtitle</a>'
];
textCases.forEach(function(textCase) {
var node = mockTextSVGElement(textCase);
expect(node.text()).toEqual('Subtitle');
assertAnchorAttrs(node);
assertAnchorLink(node, 'XSS onmouseover=alert(1) style=font-size:300px');
});
});
it('should keep query parameters in href', function() {
var textCases = [
'<a href="https://abc.com/myFeature.jsp?name=abc&pwd=def">abc.com?shared-key</a>',
'<a href="https://abc.com/myFeature.jsp?name=abc&pwd=def">abc.com?shared-key</a>'
];
textCases.forEach(function(textCase) {
var node = mockTextSVGElement(textCase);
assertAnchorAttrs(node);
expect(node.text()).toEqual('abc.com?shared-key');
assertAnchorLink(node, 'https://abc.com/myFeature.jsp?name=abc&pwd=def');
});
});
});
});