v0.5.1 — Escape userscript metadata in settings UI

Fixes XSS via malicious userscript @name, @author, @version, @description
metadata and script setting titles/descriptions. Also escapes checkbox
grid labels. All use existing escapeHtml() helper.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 09:04:50 -08:00
parent 819caea65a
commit b8bfa2941c
2 changed files with 8 additions and 8 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "krunker-civilian-client",
"version": "0.5.0",
"version": "0.5.1",
"description": "Cross-platform Krunker game client",
"main": "dist/main/index.js",
"homepage": "https://gitea.crjlab.net/bigjakk/krunker-civilian-client",
+7 -7
View File
@@ -372,7 +372,7 @@ function createCheckboxGrid(opts: {
const label = document.createElement('label');
label.className = 'hostOpt';
label.innerHTML =
'<span class="optName">' + item.label + '</span>' +
'<span class="optName">' + escapeHtml(item.label) + '</span>' +
'<input type="checkbox"' + (opts.selected.includes(item.value) ? ' checked' : '') + '>' +
'<div class="optCheck"></div>';
const cb = label.querySelector('input') as HTMLInputElement;
@@ -1114,12 +1114,12 @@ function renderUserscriptsSection(body: HTMLElement): void {
const scriptRow = document.createElement('div');
scriptRow.className = 'setting settName safety-0 bool';
const displayName = inst.meta.name || inst.filename;
const displayName = escapeHtml(inst.meta.name || inst.filename);
let metaParts: string[] = [];
if (inst.meta.author) metaParts.push('by ' + inst.meta.author);
if (inst.meta.version) metaParts.push('v' + inst.meta.version);
if (inst.meta.author) metaParts.push('by ' + escapeHtml(inst.meta.author));
if (inst.meta.version) metaParts.push('v' + escapeHtml(inst.meta.version));
const metaLine = metaParts.length > 0 ? '<span class="kpc-us-meta">' + metaParts.join(' &middot; ') + '</span>' : '';
const descText = inst.meta.desc || '';
const descText = escapeHtml(inst.meta.desc || '');
scriptRow.innerHTML =
'<span class="setting-title">' + displayName + '</span>' +
@@ -1161,8 +1161,8 @@ function renderScriptSettings(inst: UserscriptInstance, container: HTMLElement):
const row = document.createElement('div');
row.className = 'setting settName safety-0' + (typeClass ? ' ' + typeClass : '');
row.innerHTML =
'<span class="setting-title">' + setting.title + '</span>' +
(setting.desc ? '<div class="setting-desc-new">' + setting.desc + '</div>' : '');
'<span class="setting-title">' + escapeHtml(setting.title) + '</span>' +
(setting.desc ? '<div class="setting-desc-new">' + escapeHtml(setting.desc) + '</div>' : '');
switch (setting.type) {
case 'bool': {