Fix XSS by parsing player counts as raw data and validating favicon URIs (#116)

* Fix XSS by parsing player counts as raw data (instead of parsing it)

* Ensure the returned favicon is a data URI

* Force server favicon size to 64px

* Increase specificity of data URI validation

The previous commit would happily accept any domain (or subdomain) that started with "data"
This commit is contained in:
Hugo Manrique 2019-09-05 23:15:44 +02:00 committed by Crypt
parent 6da613bbb8
commit 0392fce6c3
3 changed files with 15 additions and 6 deletions

1
.eslintignore Normal file

@ -0,0 +1 @@
*

@ -11,6 +11,7 @@ var mojangServicesUpdater;
var sortServersTask; var sortServersTask;
var currentServerHover; var currentServerHover;
var faviconSize = 64;
function updateServerStatus(lastEntry) { function updateServerStatus(lastEntry) {
var info = lastEntry.info; var info = lastEntry.info;
@ -413,7 +414,7 @@ $(document).ready(function() {
class: 'server', class: 'server',
'server-id': safeNameCopy, 'server-id': safeNameCopy,
html: '<div id="server-' + safeNameCopy + '" class="column" style="width: 80px;">\ html: '<div id="server-' + safeNameCopy + '" class="column" style="width: 80px;">\
<img id="favicon_' + safeNameCopy + '" title="' + info.name + '\n' + info.ip + printPort(info.port) + '">\ <img id="favicon_' + safeNameCopy + '" title="' + info.name + '\n' + info.ip + printPort(info.port) + '" height="' + faviconSize + '" width="' + faviconSize + '">\
<br />\ <br />\
<p class="text-center-align rank" id="ranking_' + safeNameCopy + '"></p>\ <p class="text-center-align rank" id="ranking_' + safeNameCopy + '"></p>\
</div>\ </div>\

@ -11,15 +11,22 @@ function pingMinecraftPC(host, port, timeout, callback, version) {
if (err) { if (err) {
callback(err, null); callback(err, null);
} else { } else {
// Remap our JSON into our custom structure. // Remap our JSON into our custom structure.
var favicon;
// Ensure the returned favicon is a data URI
if (res.favicon.indexOf('data:image/') === 0) {
favicon = res.favicon;
}
callback(null, { callback(null, {
players: { players: {
online: res.players.online, online: parseInt(res.players.online),
max: res.players.max max: parseInt(res.players.max)
}, },
version: res.version.protocol, version: parseInt(res.version.protocol),
latency: util.getCurrentTimeMs() - startTime, latency: util.getCurrentTimeMs() - startTime,
favicon: res.favicon favicon
}); });
} }
}, timeout, version); }, timeout, version);