KRITISCH: Server-Quellcode + kompletter Git-Verlauf waren oeffentlich abrufbar
Sicherheits-Audit vor dem geplanten oeffentlichen Start morgen (21.08.2026, Nutzer-Anfrage: "duerfen die leute keinen zugriff auf veraenderungen haben"). SITE_DIR ist der GESAMTE Repo-Ordner (join(__dirname, "..")), express.static lieferte daher nicht nur die Website aus, sondern auch: - server/ (inkl. gate.js, das komplette Sicherheitskonzept im Klartext) - server-internal/ (Admin-/Supporter-Backend-Quellcode) - cloudflare-worker/ (altes Backend) - .git/ (VOLLSTAENDIGE Commit-Historie, rekonstruierbar per Git-Dump) - CLAUDE.md, DEPLOY.md, wrangler.toml, netlify.toml, gate-worker.js, gate.html.bak-07-08-2026 (Alt-Backup-Datei einer frueheren Session) Live nachgewiesen (mit gueltigem Zugangscode -- morgen faellt die Schranke fuer ALLE weg): /server/gate.js und /.git/config lieferten HTTP 200. Ursache: serve-static blockt per Default nur Dateien, deren EIGENER Name mit einem Punkt beginnt (server/.env -> zufaellig schon 404), aber NICHT rekursiv -- .git/config wird trotzdem ausgeliefert, weil "config" selbst nicht mit einem Punkt beginnt, nur der Ordner davor. Fix: eigene Sperr-Middleware VOR express.static, unabhaengig von gateMiddleware (bleibt also auch nach dem Entfernen der Zugangsschranke wirksam). Blockt ganze Ordner (server/, server-internal/, cloudflare-worker/) + versteckte Ordner/Dateien rekursiv (jedes Pfadsegment, das mit "." beginnt, ausser .well-known) + eine feste Liste an Alt-Dateien + jedes *.bak-Muster, damit auch kuenftige Backup-Reste automatisch mitgeschuetzt sind. Lokal mit echtem Express-Server verifiziert (gateMiddleware absichtlich deaktiviert, um exakt den morgigen "oeffentlich"-Zustand zu simulieren): alle vorher gefundenen Luecken jetzt 404, alle echten Seiten/Assets (index.html, main.css, main.js, manifest.json, robots.txt, favicon) weiterhin 200. Getrennt prooft: server-internal/ (eigener Dienst unter postfach.dogfather-universe.com, Port 4200) hat sein EIGENES, unabhaengiges Session-System -- jede /admin/*-Route ist einzeln per requireTeamSession-Middleware abgesichert (in index.js durchgezaehlt, keine Ausnahme gefunden), live mit einer unauthentifizierten Anfrage gegen /admin/users/list bestaetigt (401). Dieser Dienst war nie vom Website-Gate abhaengig und ist von diesem Fund nicht betroffen. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -37,6 +37,40 @@ app.use(cookieParser());
|
||||
app.use(express.json({ limit: "1mb" }));
|
||||
app.use(gateMiddleware);
|
||||
|
||||
/* Sicherheits-Fix 20.08.2026 (Audit vor dem geplanten öffentlichen Start morgen).
|
||||
SITE_DIR ist der GESAMTE Repo-Ordner (join(__dirname, "..")) — express.static liefert
|
||||
ohne diese Sperre daher nicht nur die eigentliche Website aus, sondern auch den Server-
|
||||
Quellcode (server/, server-internal/, cloudflare-worker/) und das komplette
|
||||
.git-Verzeichnis samt Commit-Historie.
|
||||
Live nachgewiesen (mit gültigem Zugangscode, der morgen für alle wegfällt):
|
||||
/server/gate.js und /.git/config lieferten HTTP 200. Ursache: serve-static blockt per
|
||||
Voreinstellung nur Dateien, deren EIGENER Name mit einem Punkt beginnt (server/.env ->
|
||||
404 durch diese Regel) — aber NICHT rekursiv. Eine Datei wie .git/config wird trotzdem
|
||||
ausgeliefert, weil "config" selbst nicht mit einem Punkt beginnt, nur der Ordnername davor.
|
||||
Diese Sperre läuft daher bewusst unabhängig von gateMiddleware (bleibt auch nach dem
|
||||
morgigen Entfernen der Zugangsschranke wirksam) und blockt ganze Ordner/Muster statt
|
||||
einzelner Dateien, damit neue Dateien darin automatisch mitgeschützt sind. */
|
||||
const GESPERRTE_ORDNER = ["/server", "/server-internal", "/cloudflare-worker"];
|
||||
const GESPERRTE_DATEIEN = [
|
||||
"/CLAUDE.md", "/DEPLOY.md", "/wrangler.toml", "/netlify.toml",
|
||||
"/gate-worker.js", "/_headers", "/.gitignore", "/.nojekyll", "/.assetsignore",
|
||||
];
|
||||
app.use((req, res, next) => {
|
||||
const pfad = req.path;
|
||||
const hatVerstecktenOrdner = pfad
|
||||
.split("/")
|
||||
.some((teil) => teil.startsWith(".") && teil.length > 1 && teil !== ".well-known");
|
||||
const inGesperrtemOrdner = GESPERRTE_ORDNER.some((p) => pfad === p || pfad.startsWith(p + "/"));
|
||||
const istGesperrteDatei = GESPERRTE_DATEIEN.includes(pfad);
|
||||
const istBackupDatei = /\.bak(-|\.|$)/i.test(pfad);
|
||||
if (hatVerstecktenOrdner || inGesperrtemOrdner || istGesperrteDatei || istBackupDatei) {
|
||||
return res.status(404).sendFile(join(SITE_DIR, "404.html"), (err) => {
|
||||
if (err) res.status(404).send("Nicht gefunden.");
|
||||
});
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
app.use(express.static(SITE_DIR, { index: "index.html" }));
|
||||
|
||||
app.use((req, res) => {
|
||||
|
||||
Reference in New Issue
Block a user