Fix front-end XSS prevention
This commit is contained in:
parent
5e9da1e492
commit
3adf04ff6d
|
|
@ -2,6 +2,11 @@
|
|||
|
||||
const $ = require('jquery');
|
||||
window.$ = window.jQuery = $;
|
||||
$.fn.dataTable = {
|
||||
defaults: {},
|
||||
ext: { errMode: '' },
|
||||
render: { text: () => ({ filter: text => text }) }
|
||||
};
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
|
|
@ -1318,7 +1323,6 @@ describe('tests for "common" module', () => {
|
|||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'Recorded.' }));
|
||||
|
||||
$.fn.dataTable = { defaults: {}, ext: { errMode: '' } };
|
||||
window.document.cookie = '';
|
||||
window.fetch = fetch;
|
||||
window.blessing = {
|
||||
|
|
@ -1347,7 +1351,6 @@ describe('tests for "common" module', () => {
|
|||
const showModal = jest.fn();
|
||||
window.trans = jest.fn(t => t);
|
||||
window.showModal = showModal;
|
||||
$.fn.dataTable = { defaults: {}, ext: { errMode: '' } };
|
||||
|
||||
handleDataTablesAjaxError(undefined, undefined, '{}');
|
||||
expect(showModal).not.toBeCalled();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
const $ = require('jquery');
|
||||
window.$ = window.jQuery = $;
|
||||
$.fn.dataTable = { render: { text: () => ({ filter: text => text }) } };
|
||||
|
||||
window.getQueryString = jest.fn((key, defaultValue) => defaultValue);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
const $ = require('jquery');
|
||||
window.$ = window.jQuery = $;
|
||||
$.fn.dataTable = { render: { text: () => ({ filter: text => text }) } };
|
||||
|
||||
describe('tests for "verification" module', () => {
|
||||
const modulePath = '../user/verification';
|
||||
|
|
|
|||
|
|
@ -19,30 +19,38 @@ const marketTableColumnDefs = [
|
|||
targets: 0,
|
||||
title: trans('admin.pluginTitle'),
|
||||
data: 'title',
|
||||
render: (title, type, row) => `<strong>${ title }</strong><div class="plugin-name">${ row.name }</div>`
|
||||
render: (title, type, row) => {
|
||||
return $.fn.dataTable.render.text().filter(`
|
||||
<strong>${ title }</strong>
|
||||
<div class="plugin-name">${ row.name }</div>
|
||||
`);
|
||||
}
|
||||
},
|
||||
{
|
||||
targets: 1,
|
||||
title: trans('admin.pluginDescription'),
|
||||
data: 'description',
|
||||
render: $.fn.dataTable.render.text(),
|
||||
orderable: false
|
||||
},
|
||||
{
|
||||
targets: 2,
|
||||
title: trans('admin.pluginAuthor'),
|
||||
data: 'author',
|
||||
render: $.fn.dataTable.render.text(),
|
||||
orderable: false
|
||||
},
|
||||
{
|
||||
targets: 3,
|
||||
title: trans('admin.pluginVersion'),
|
||||
data: 'version',
|
||||
render: $.fn.dataTable.render.text(),
|
||||
orderable: false
|
||||
},
|
||||
{
|
||||
targets: 4,
|
||||
data: 'dependencies',
|
||||
title: trans('admin.pluginDependencies'),
|
||||
data: 'dependencies',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
render: data => {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ const playersTableColumnDefs = [
|
|||
},
|
||||
{
|
||||
targets: 2,
|
||||
data: 'player_name'
|
||||
data: 'player_name',
|
||||
render: $.fn.dataTable.render.text()
|
||||
},
|
||||
{
|
||||
targets: 3,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ const pluginsTableColumnDefs = [
|
|||
}
|
||||
|
||||
return `
|
||||
<strong>${ title }</strong>
|
||||
<strong>${ $.fn.dataTable.render.text().filter(title) }</strong>
|
||||
<div class="actions">${ actions.join(' | ') }</div>
|
||||
`;
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@ const pluginsTableColumnDefs = [
|
|||
orderable: false,
|
||||
render: (description, type, row) => {
|
||||
return `
|
||||
<div class="plugin-description"><p>${ description }</p></div>
|
||||
<div class="plugin-description"><p>${ $.fn.dataTable.render.text().filter(description) }</p></div>
|
||||
<div class="plugin-version-author">
|
||||
${ trans('admin.pluginVersion') } <span class="text-primary">${ row.version }</span> |
|
||||
${ trans('admin.pluginAuthor') } <a href="${ row.url }">${ row.author }</a> |
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ const usersTableColumnDefs = [
|
|||
},
|
||||
{
|
||||
targets: 2,
|
||||
data: 'nickname'
|
||||
data: 'nickname',
|
||||
render: $.fn.dataTable.render.text()
|
||||
},
|
||||
{
|
||||
targets: 3,
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ function renderSkinlibItemComponent(item) {
|
|||
title = item.liked ? trans('skinlib.removeFromCloset') : trans('skinlib.addToCloset');
|
||||
}
|
||||
|
||||
item.name = $.fn.dataTable.render.text().filter(item.name);
|
||||
|
||||
return `<a href="${ url('skinlib/show/' + item.tid) }">
|
||||
<div class="item" tid="${ item.tid }">
|
||||
<div class="item-body">
|
||||
|
|
|
|||
|
|
@ -115,26 +115,30 @@ async function initCloset() {
|
|||
* @param {{ name: string, tid: number, type: 'steve' | 'alex' | 'cape' }} item
|
||||
*/
|
||||
function renderClosetItemComponent(item) {
|
||||
// Prevent XSS
|
||||
item.name = $.fn.dataTable.render.text().filter(item.name);
|
||||
|
||||
return `
|
||||
<div class="item" tid="${item.tid}" data-texture-type="${item.type}">
|
||||
<div class="item-body">
|
||||
<img src="${url('/')}preview/${item.tid}.png">
|
||||
</div>
|
||||
<div class="item-footer">
|
||||
<p class="texture-name">
|
||||
<span title="${item.name}">${item.name} <small>(${item.type})</small></span>
|
||||
</p>
|
||||
<div class="item-body">
|
||||
<img src="${url('/')}preview/${item.tid}.png">
|
||||
</div>
|
||||
<div class="item-footer">
|
||||
<p class="texture-name">
|
||||
<span title="${item.name}">${item.name} <small>(${item.type})</small></span>
|
||||
</p>
|
||||
|
||||
<a href="${url('/')}skinlib/show/${item.tid}" title="${trans('user.viewInSkinlib')}" class="more" data-toggle="tooltip" data-placement="bottom"><i class="fa fa-share"></i></a>
|
||||
<span title="${trans('general.more')}" class="more" data-toggle="dropdown" aria-haspopup="true" id="more-button"><i class="fa fa-cog"></i></span>
|
||||
<a href="${url('/')}skinlib/show/${item.tid}" title="${trans('user.viewInSkinlib')}" class="more" data-toggle="tooltip" data-placement="bottom"><i class="fa fa-share"></i></a>
|
||||
<span title="${trans('general.more')}" class="more" data-toggle="dropdown" aria-haspopup="true" id="more-button"><i class="fa fa-cog"></i></span>
|
||||
|
||||
<ul class="dropup dropdown-menu" aria-labelledby="more-button">
|
||||
<li><a onclick="renameClosetItem(${item.tid}, '${item.name}');">${trans('user.renameItem')}</a></li>
|
||||
<li><a onclick="removeFromCloset(${item.tid});">${trans('user.removeItem')}</a></li>
|
||||
<li><a onclick="setAsAvatar(${item.tid});">${trans('user.setAsAvatar')}</a></li>
|
||||
</ul>
|
||||
<ul class="dropup dropdown-menu" aria-labelledby="more-button">
|
||||
<li><a onclick="renameClosetItem(${item.tid}, '${item.name}');">${trans('user.renameItem')}</a></li>
|
||||
<li><a onclick="removeFromCloset(${item.tid});">${trans('user.removeItem')}</a></li>
|
||||
<li><a onclick="setAsAvatar(${item.tid});">${trans('user.setAsAvatar')}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user