Fix remaining frontend security issues (3 medium, 2 low)

- Escape user-input port number in app-selector innerHTML
- Replace inline onclick with addEventListener in backup history (HTML entity decode bypass)
- Add Content-Security-Policy meta tag with script hash
- Replace document.write with textContent for footer year
- Filter __proto__/constructor/prototype in Object.assign calls

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 02:06:55 -08:00
parent 52577b11ed
commit 9a0abc02d1
4 changed files with 20 additions and 6 deletions

View File

@@ -47,8 +47,10 @@ const SITE = {
SITE.dnsIp = c.dns.ip || '';
SITE.dnsPort = c.dns.port || DC.DEFAULTS.DNS_PORT;
}
if (c.dnsServers) {
Object.assign(SITE.dnsServers, c.dnsServers);
if (c.dnsServers && typeof c.dnsServers === 'object') {
for (const [k, v] of Object.entries(c.dnsServers)) {
if (k !== '__proto__' && k !== 'constructor' && k !== 'prototype') SITE.dnsServers[k] = v;
}
}
if (c.configurationType) SITE.configurationType = c.configurationType;
if (c.domain) SITE.domain = c.domain;
@@ -352,7 +354,12 @@ const AppState = {
},
updateApp(id, changes) {
const app = this._apps.find(a => a.id === id);
if (app) { Object.assign(app, changes); DC_BUS.emit('apps:changed', this._apps); }
if (app) {
for (const [k, v] of Object.entries(changes)) {
if (k !== '__proto__' && k !== 'constructor' && k !== 'prototype') app[k] = v;
}
DC_BUS.emit('apps:changed', this._apps);
}
return app;
}
};