diff --git a/server/src/index.ts b/server/src/index.ts index ea463c8..a9a149c 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -30,7 +30,7 @@ import { config } from './config.js' import { ensureAdmin } from './auth.js' import { pruneEvents, pruneSessions, pruneVerwaltung, schreibeAbrufe, zaehleAbruf } from './db.js' import { pruefePlatte, pruefeSicherung } from './meldung.js' -import { absolutePath, checkPath, lohntWebp, mimeFor, thumbPath, webpPfad } from './storage.js' +import { dateiKopf, absolutePath, checkPath, lohntWebp, mimeFor, thumbPath, webpPfad } from './storage.js' import { uploadRoutes } from './routes/upload.js' import { fivemanageRoutes } from './routes/fivemanage.js' import { freigabeRoutes } from './routes/freigabe.js' @@ -152,9 +152,8 @@ async function serveFile(c: any, rawPath: string) { ETag: etag, 'Last-Modified': info.mtime.toUTCString(), 'Accept-Ranges': 'bytes', - // Kein Verlassen auf den Dateinamen: der Browser soll nicht raten, - // was er da vor sich hat. - 'X-Content-Type-Options': 'nosniff', + // nosniff und die Sandbox gegen Skript-SVGs (#254) - storage.ts, dateiKopf. + ...dateiKopf(typ), } // GEZAEHLT WIRD HIER, nach der Pruefung und vor der Auslieferung. @@ -282,7 +281,7 @@ app.get('/t/*', async (c) => { // Kurz: eine Vorschau aendert sich, wenn das Bild neu hochgeladen // wird, und dann soll das Dashboard es sehen. 'Cache-Control': 'public, max-age=60', - 'X-Content-Type-Options': 'nosniff', + ...dateiKopf('image/webp'), }) }) diff --git a/server/src/routes/privat.ts b/server/src/routes/privat.ts index e282329..ebdeb63 100644 --- a/server/src/routes/privat.ts +++ b/server/src/routes/privat.ts @@ -33,6 +33,7 @@ import { fesselText, tokenAllows, tokenFromHeader } from '../auth.js' import { PathError, checkPathUnter, + dateiKopf, kannVorschau, mimeFor, privatPfad, @@ -186,8 +187,8 @@ privatRoutes.get('/datei/:pfad{.+}', async (c) => { return c.body(createReadStream(datei) as any, 200, { 'Content-Type': vorschau ? 'image/webp' : row.mime, 'Content-Length': String(groesse), - // Nie in einem geteilten Zwischenspeicher, und der Browser rät den Typ nicht. + // Nie in einem geteilten Zwischenspeicher; nosniff und Sandbox (#254) aus storage.ts. 'Cache-Control': 'private, no-store', - 'X-Content-Type-Options': 'nosniff', + ...dateiKopf(vorschau ? 'image/webp' : row.mime), }) }) diff --git a/server/src/storage.ts b/server/src/storage.ts index cde8518..d831fab 100644 --- a/server/src/storage.ts +++ b/server/src/storage.ts @@ -74,6 +74,39 @@ export function checkPathUnter(raw: string, basis: string): string { return path } +/** + * DIE KOPFZEILEN AUF JEDER AUSGELIEFERTEN DATEI (d4rk-rp-planung#254). + * + * Ein SVG kann