fix(18): dot-only Manifest-Dateinamen ("."/"..") in getPackage() ablehnen (CR-01)

Die Zeichen-Whitelist /^[A-Za-z0-9._-]+$/ liess Namen wie ".." durch, weil
Punkt und Bindestrich erlaubte Zeichen sind -- path.join(desktopDistDir, '..')
loest aber in den Elternordner auf und unterlaeuft genau die Verteidigung in
der Tiefe (T-18-02), die diese Zeile laut Kommentar herstellen soll. Jetzt
werden "." und ".." explizit abgelehnt UND der aufgeloeste Pfad zusaetzlich
gegen desktopDistDir geprueft (haelt auch kuenftige Varianten ab, falls die
Whitelist anderswo wiederverwendet wird). Neue Testfaelle fuer manifest-Eintraege
namens "..", "." und "../manifest.json".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-16 17:39:29 +02:00
parent a8964f1a23
commit 0d5c80fbbf
2 changed files with 40 additions and 3 deletions
+16 -3
View File
@@ -145,13 +145,26 @@ export class DesktopService {
}
// (4) Verteidigung in der Tiefe (T-18-02): auch ein manipuliertes
// Manifest darf nicht aus dem Ordner hinausfuehren.
if (!/^[A-Za-z0-9._-]+$/.test(entry.name)) {
// Manifest darf nicht aus dem Ordner hinausfuehren. Die Zeichen-Whitelist
// allein reicht nicht -- "." und ".." bestehen ausschliesslich aus
// erlaubten Zeichen, meinen im Dateisystem aber "aktueller"/"uebergeordneter
// Ordner". Deshalb zusaetzlich explizit ausschliessen UND den aufgeloesten
// Pfad gegen den Zielordner pruefen (haelt auch kuenftige Varianten dieses
// Musters ab, falls die Zeichen-Whitelist anderswo wiederverwendet wird).
if (
!/^[A-Za-z0-9._-]+$/.test(entry.name) ||
entry.name === '.' ||
entry.name === '..'
) {
throw new NotFoundException(`No package for platform: ${knownPlatform}`);
}
const filePath = path.join(this.desktopDistDir, entry.name);
const resolvedRoot = path.resolve(this.desktopDistDir) + path.sep;
if (!path.resolve(filePath).startsWith(resolvedRoot)) {
throw new NotFoundException(`No package for platform: ${knownPlatform}`);
}
// (5) Datei muss existieren.
const filePath = path.join(this.desktopDistDir, entry.name);
if (!fs.existsSync(filePath)) {
throw new NotFoundException(`Package file missing: ${entry.name}`);
}