mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
fix(api): sanitize og-story level input (#219)
This commit is contained in:
@@ -25,12 +25,17 @@ const LEVEL_LABELS = {
|
||||
low: 'LOW RISK',
|
||||
};
|
||||
|
||||
function normalizeLevel(rawLevel) {
|
||||
const level = String(rawLevel || '').toLowerCase();
|
||||
return Object.prototype.hasOwnProperty.call(LEVEL_COLORS, level) ? level : 'normal';
|
||||
}
|
||||
|
||||
export default function handler(req, res) {
|
||||
const url = new URL(req.url, `https://${req.headers.host}`);
|
||||
const countryCode = (url.searchParams.get('c') || '').toUpperCase();
|
||||
const type = url.searchParams.get('t') || 'ciianalysis';
|
||||
const score = url.searchParams.get('s');
|
||||
const level = url.searchParams.get('l') || 'normal';
|
||||
const level = normalizeLevel(url.searchParams.get('l'));
|
||||
|
||||
const countryName = COUNTRY_NAMES[countryCode] || countryCode || 'Global';
|
||||
const levelColor = LEVEL_COLORS[level] || '#eab308';
|
||||
|
||||
48
api/og-story.test.mjs
Normal file
48
api/og-story.test.mjs
Normal file
@@ -0,0 +1,48 @@
|
||||
import { strict as assert } from 'node:assert';
|
||||
import test from 'node:test';
|
||||
import handler from './og-story.js';
|
||||
|
||||
function renderOgStory(query = '') {
|
||||
const req = {
|
||||
url: `https://worldmonitor.app/api/og-story${query ? `?${query}` : ''}`,
|
||||
headers: { host: 'worldmonitor.app' },
|
||||
};
|
||||
|
||||
let statusCode = 0;
|
||||
let body = '';
|
||||
const headers = {};
|
||||
|
||||
const res = {
|
||||
setHeader(name, value) {
|
||||
headers[String(name).toLowerCase()] = String(value);
|
||||
},
|
||||
status(code) {
|
||||
statusCode = code;
|
||||
return this;
|
||||
},
|
||||
send(payload) {
|
||||
body = String(payload);
|
||||
},
|
||||
};
|
||||
|
||||
handler(req, res);
|
||||
return { statusCode, body, headers };
|
||||
}
|
||||
|
||||
test('normalizes unsupported level values to prevent SVG script injection', () => {
|
||||
const injectedLevel = encodeURIComponent('</text><script>alert(1)</script><text>');
|
||||
const response = renderOgStory(`c=US&s=50&l=${injectedLevel}`);
|
||||
|
||||
assert.equal(response.statusCode, 200);
|
||||
assert.equal(/<script/i.test(response.body), false);
|
||||
assert.match(response.body, />NORMAL<\/text>/);
|
||||
});
|
||||
|
||||
test('uses a known level when it is allowlisted', () => {
|
||||
const response = renderOgStory('c=US&s=88&l=critical');
|
||||
|
||||
assert.equal(response.statusCode, 200);
|
||||
assert.match(response.body, />CRITICAL<\/text>/);
|
||||
assert.match(response.body, /#ef4444/);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user