TooltipがXSSに対応していない
https://github.com/masayuki0812/c3/issues/1536にあるように、グラフについては、XSSに対応しているようだが Tooltipに関しては未対応の模様。
サンプル : XSS未対応版
alert("XSS" )が表示する<html> <head> <meta charset="UTF-8"> <!-- Load c3.css --> <link href="./c3/c3.css" rel="stylesheet" type="text/css"> <!-- Load d3.js and c3.js --> <script src="http://d3js.org/d3.v3.js" charset="utf-8"></script> <script src="./c3/c3.js"></script></head> </head> <body> <div id="chartToDrow"></div> <script> var chart = c3.generate({ bindto: '#chartToDrow', data: { columns: [ ['data1"><img src="dummy.jpg" onerror="alert(\'XSS\')" />"', 130, 100], ['data2', 150, 50], ], type: 'bar' }, }); </script> </body> </html>
解決案
* 以下の関連記事の「■ 独自のTooltipを実装するには」と「JavaScript でのサニタイジング(エスケープ)」 を使って、修正してみる独自のTooltipを実装するには
http://blogs.yahoo.co.jp/dk521123/35526974.html
JavaScript でのサニタイジング(エスケープ)
http://blogs.yahoo.co.jp/dk521123/35778596.html
解決案サンプル : XSS対応版
エスケープした<script>
var chart = c3.generate({
bindto: '#chartToDrow',
data: {
columns: [
['data1"><img src="dummy.jpg" onerror="alert(\'XSS\')" />"', 130, 100],
['data2', 150, 50],
],
type: 'bar'
},
// ★ここ★
tooltip: {
contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
var $$ = this,
titleFormat = defaultTitleFormat,
nameFormat = function (name) { return name; },
valueFormat = defaultValueFormat,
text, i, title, value, name, bgcolor;
for (i = 0; i < d.length; i++) {
if (! (d[i] && (d[i].value || d[i].value === 0))) { continue; }
if (! text) {
title = titleFormat ? titleFormat(d[i].x) : d[i].x;
text = "<table class='c3-tooltip" + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
}
value = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);
if (value !== undefined) {
name = nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index);
bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);
var targetId = escape(d[i].id);
text += "<tr class='c3-tooltip-name" + "-" + targetId + "'>";
text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + escape(name) + "</td>";
text += "<td class='value'>" + escape(value) + "</td>";
text += "</tr>";
}
}
return text + "</table>";
}
},
});
function escape(targetValue) {
if (targetValue === null || targetValue === undefined) {
return "";
}
return String(targetValue)
.replace(/&/g, "&")
.replace(/"/g, """)
.replace(/'/g, "'")
.replace(/`/g, "`")
.replace(/</g, "<")
.replace(/>/g, ">");
}
</script>
</body>
</html>