From 111f93da445ead15c6dd7d39f9ec1581090f3e1a Mon Sep 17 00:00:00 2001 From: Jeremy Brandenburger Date: Mon, 30 Mar 2026 13:39:28 +0200 Subject: [PATCH] fix: remove upgrade-insecure-requests CSP, protect stratagems via API auth --- public/app.js | 5 ++- public/index.html | 1 - public/stratagems.js | 87 -------------------------------------------- server.js | 21 +++++++---- 4 files changed, 17 insertions(+), 97 deletions(-) delete mode 100644 public/stratagems.js diff --git a/public/app.js b/public/app.js index 9fb340f..9917adc 100644 --- a/public/app.js +++ b/public/app.js @@ -90,11 +90,12 @@ async function checkAuth() { } } -function onLoggedIn() { +async function onLoggedIn() { document.getElementById('main-nav').classList.remove('hidden'); document.getElementById('nav-username').textContent = state.user.user; document.getElementById('nav-admin').classList.toggle('hidden', state.user.role !== 'admin'); - state.stratagems = window.STRATAGEMS || []; + // Stratagems are served via authenticated API – not as a public static file + state.stratagems = await api('GET', '/stratagems').catch(() => []); connectWS(); showView('dashboard'); } diff --git a/public/index.html b/public/index.html index f62a8b1..512324e 100644 --- a/public/index.html +++ b/public/index.html @@ -340,7 +340,6 @@
- diff --git a/public/stratagems.js b/public/stratagems.js deleted file mode 100644 index 76d820e..0000000 --- a/public/stratagems.js +++ /dev/null @@ -1,87 +0,0 @@ -// Helldivers 2 – complete stratagem list -// Sequences use: 'up' | 'down' | 'left' | 'right' -// Source: Helldivers 2 community wiki (helldivers.wiki.gg) -const STRATAGEMS = [ - // ── Patriotic Administration Center ────────────────────────────────────── - { name: 'Reinforce', category: 'Patriotic Administration Center', sequence: ['up','down','right','left','up'] }, - { name: 'Resupply', category: 'Patriotic Administration Center', sequence: ['down','down','up','right'] }, - { name: 'SOS Beacon', category: 'Patriotic Administration Center', sequence: ['up','down','right','up'] }, - { name: 'Hellbomb', category: 'Patriotic Administration Center', sequence: ['down','up','left','down','up','right','down','up'] }, - { name: 'SEAF Artillery', category: 'Patriotic Administration Center', sequence: ['right','up','up','down'] }, - { name: 'Upload Data', category: 'Patriotic Administration Center', sequence: ['right','right','left','up','up'] }, - { name: 'Eagle Rearm', category: 'Patriotic Administration Center', sequence: ['up','up','left','up','right'] }, - { name: 'Prospecting Drill', category: 'Patriotic Administration Center', sequence: ['down','down','left','right','down'] }, - - // ── Orbital Cannons ─────────────────────────────────────────────────────── - { name: 'Orbital Gatling Barrage', category: 'Orbital Cannons', sequence: ['right','down','left','up','up'] }, - { name: 'Orbital Airburst Strike', category: 'Orbital Cannons', sequence: ['right','right','right'] }, - { name: 'Orbital 120MM HE Barrage', category: 'Orbital Cannons', sequence: ['right','right','down','left','right','down'] }, - { name: 'Orbital 380MM HE Barrage', category: 'Orbital Cannons', sequence: ['right','down','up','up','left','down','down'] }, - { name: 'Orbital Walking Barrage', category: 'Orbital Cannons', sequence: ['right','down','right','down','right','down'] }, - { name: 'Orbital Laser', category: 'Orbital Cannons', sequence: ['right','down','up','right','down'] }, - { name: 'Orbital Railcannon Strike', category: 'Orbital Cannons', sequence: ['right','up','down','down','right'] }, - { name: 'Orbital Precision Strike', category: 'Orbital Cannons', sequence: ['right','right','up'] }, - { name: 'Orbital Gas Strike', category: 'Orbital Cannons', sequence: ['right','right','down','right'] }, - { name: 'Orbital EMS Strike', category: 'Orbital Cannons', sequence: ['right','right','left','down'] }, - { name: 'Orbital Smoke Strike', category: 'Orbital Cannons', sequence: ['right','right','down','up'] }, - { name: 'Orbital Illumination Flare',category: 'Orbital Cannons', sequence: ['right','right','left','left'] }, - - // ── Hangar ──────────────────────────────────────────────────────────────── - { name: 'Eagle Strafing Run', category: 'Hangar', sequence: ['up','right','right'] }, - { name: 'Eagle Airstrike', category: 'Hangar', sequence: ['up','right','down','right'] }, - { name: 'Eagle Cluster Bomb', category: 'Hangar', sequence: ['up','right','down','down','right'] }, - { name: 'Eagle Napalm Airstrike', category: 'Hangar', sequence: ['up','right','down','up'] }, - { name: 'LIFT-850 Jump Pack', category: 'Hangar', sequence: ['down','up','up','down','up'] }, - { name: 'Eagle Smoke Strike', category: 'Hangar', sequence: ['up','right','up','down'] }, - { name: 'Eagle 110MM Rocket Pods', category: 'Hangar', sequence: ['up','right','up','left'] }, - { name: 'Eagle 500KG Bomb', category: 'Hangar', sequence: ['up','right','down','down','down'] }, - - // ── Bridge ──────────────────────────────────────────────────────────────── - { name: 'Patriot Exosuit', category: 'Bridge', sequence: ['left','down','right','up','left','down','right'] }, - { name: 'Emancipator Exosuit',category: 'Bridge', sequence: ['left','down','right','up','left','down','down'] }, - - // ── Engineering Bay – Support Weapons ──────────────────────────────────── - { name: 'Machine Gun', category: 'Engineering Bay', sequence: ['down','left','down','up','right'] }, - { name: 'Anti-Materiel Rifle', category: 'Engineering Bay', sequence: ['down','left','right','up','down'] }, - { name: 'Stalwart', category: 'Engineering Bay', sequence: ['down','left','down','up','up','left'] }, - { name: 'Expendable Anti-Tank', category: 'Engineering Bay', sequence: ['down','down','left','up'] }, - { name: 'Recoilless Rifle', category: 'Engineering Bay', sequence: ['down','left','right','right','left'] }, - { name: 'Flamethrower', category: 'Engineering Bay', sequence: ['down','left','up','down','up'] }, - { name: 'Autocannon', category: 'Engineering Bay', sequence: ['down','left','down','up','up','right'] }, - { name: 'Heavy Machine Gun', category: 'Engineering Bay', sequence: ['down','left','up','down','down'] }, - { name: 'Airburst Rocket Launcher', category: 'Engineering Bay', sequence: ['down','up','up','left','right'] }, - { name: 'Commando', category: 'Engineering Bay', sequence: ['down','left','up','down','right'] }, - { name: 'Railgun', category: 'Engineering Bay', sequence: ['down','right','down','up','left','right'] }, - { name: 'Spear', category: 'Engineering Bay', sequence: ['down','down','up','down','down'] }, - { name: 'Quasar Cannon', category: 'Engineering Bay', sequence: ['down','down','up','left','right'] }, - { name: 'Arc Thrower', category: 'Engineering Bay', sequence: ['down','right','down','up','left','left'] }, - { name: 'Laser Cannon', category: 'Engineering Bay', sequence: ['down','left','down','up','left'] }, - { name: 'Grenade Launcher', category: 'Engineering Bay', sequence: ['down','left','up','left','down'] }, - - // ── Engineering Bay – Equipment / Backpacks ─────────────────────────────── - { name: 'Supply Pack', category: 'Engineering Bay', sequence: ['down','left','down','up','up','down'] }, - { name: 'Guard Dog Rover', category: 'Engineering Bay', sequence: ['down','up','left','up','right','right'] }, - { name: 'Guard Dog', category: 'Engineering Bay', sequence: ['down','up','left','up','right','down'] }, - { name: 'Ballistic Shield Backpack', category: 'Engineering Bay', sequence: ['down','left','down','down','up','left'] }, - { name: 'Shield Generator Pack', category: 'Engineering Bay', sequence: ['down','up','left','right','left','right'] }, - { name: 'Directional Shield', category: 'Engineering Bay', sequence: ['down','left','up','up','right'] }, - - // ── Engineering Bay – Mines ─────────────────────────────────────────────── - { name: 'Anti-Personnel Minefield', category: 'Engineering Bay', sequence: ['down','left','up','right'] }, - { name: 'Incendiary Mines', category: 'Engineering Bay', sequence: ['down','left','left','down'] }, - { name: 'Anti-Tank Mines', category: 'Engineering Bay', sequence: ['down','down','left','left'] }, - - // ── Robotics Workshop – Sentries ────────────────────────────────────────── - { name: 'Machine Gun Sentry', category: 'Robotics Workshop', sequence: ['down','up','right','right','up'] }, - { name: 'Gatling Sentry', category: 'Robotics Workshop', sequence: ['down','up','right','left'] }, - { name: 'Mortar Sentry', category: 'Robotics Workshop', sequence: ['down','up','right','right','down'] }, - { name: 'Autocannon Sentry', category: 'Robotics Workshop', sequence: ['down','up','right','up','left','up'] }, - { name: 'Rocket Sentry', category: 'Robotics Workshop', sequence: ['down','up','right','right','left'] }, - { name: 'EMS Mortar Sentry', category: 'Robotics Workshop', sequence: ['down','up','right','down','right'] }, - { name: 'Tesla Tower', category: 'Robotics Workshop', sequence: ['down','up','right','up','left','up','up'] }, - - // ── Defensive / Other ───────────────────────────────────────────────────── - { name: 'Shield Generator Relay', category: 'Defensive', sequence: ['down','up','left','right','left','down'] }, - { name: 'Anti-Tank Emplacement', category: 'Defensive', sequence: ['down','right','right','up','left'] }, - { name: 'Orbital Shield Generator', category: 'Defensive', sequence: ['right','right','left','down','left','down'] }, -]; diff --git a/server.js b/server.js index 46737fb..2f870c0 100644 --- a/server.js +++ b/server.js @@ -171,12 +171,13 @@ app.set('trust proxy', 1); app.use(helmet({ contentSecurityPolicy: { directives: { - defaultSrc: ["'self'"], - scriptSrc: ["'self'"], - styleSrc: ["'self'", "'unsafe-inline'", 'https://fonts.googleapis.com'], - fontSrc: ["'self'", 'https://fonts.gstatic.com'], - imgSrc: ["'self'", 'data:'], - connectSrc: ["'self'", 'ws:', 'wss:'], + defaultSrc: ["'self'"], + scriptSrc: ["'self'"], + styleSrc: ["'self'", "'unsafe-inline'", 'https://fonts.googleapis.com'], + fontSrc: ["'self'", 'https://fonts.gstatic.com'], + imgSrc: ["'self'", 'data:'], + connectSrc: ["'self'", 'ws:', 'wss:'], + upgradeInsecureRequests: null, // Nginx handles HTTPS; this breaks HTTP on LAN/dev }, }, })); @@ -409,7 +410,13 @@ app.get('/api/scores/me', requireAuth, (req, res) => { res.json({ practice, matches }); }); -// ── Static files ────────────────────────────────────────────────────────────── +// ── Stratagems API (authenticated) ──────────────────────────────────────────── +// Stratagem sequences are served via API – not as a public static file. +app.get('/api/stratagems', requireAuth, (req, res) => { + res.json(STRATAGEMS); +}); + +// ── Public static files (index.html, styles.css, app.js) ───────────────────── app.use(express.static(path.join(__dirname, 'public'), { etag: false, setHeaders: (res) => res.setHeader('Cache-Control', 'no-store'),