Verwendung fehlerhaft aufgelöster Namen oder Referenzen
Beschreibung
Die Verwendung fehlerhaft aufgelöster Namen oder Referenzen tritt auf, wenn ein Produkt einen Namen oder eine Referenz verwendet, um auf eine Ressource zuzugreifen, aber der Name/die Referenz zu einer Ressource aufgelöst wird, die außerhalb des beabsichtigten Kontrollbereichs liegt. Dies geschieht, wenn Angreifer manipulieren können, wie Namen oder Referenzen aufgelöst werden, wodurch die Anwendung Ressourcen lädt oder auf Ressourcen zugreift, die vom Angreifer kontrolliert werden, anstatt auf die beabsichtigten legitimen Ressourcen. Häufige Erscheinungsformen umfassen DLL/Library-Hijacking, DNS-Rebinding, Symlink-Angriffe, Relative-Path-Injection und Package-Dependency-Confusion.
Risiko
Schwachstellen durch fehlerhaft aufgelöste Namen ermöglichen Angreifern das Einschleusen von bösartigem Code oder die Umleitung des Anwendungsverhaltens. CVE-2025-58362 im Hono JavaScript-Framework (CVSS 7.5) ermöglicht Path-Confusion durch fehlerhafte Request-URIs, wodurch Proxy-ACLs umgangen werden und Zugriff auf geschützte Ressourcen wie /admin erlangt wird. Apache Camel-Schwachstellen ermöglichen Angreifern das Einschleusen von Headern, die das Komponentenverhalten ändern. Der tj-actions Supply-Chain-Angriff im März 2025 modifizierte Repository-Tags, um auf bösartige Commits zu zeigen und Secrets preiszugeben. Diese Schwachstellen können zu Remote-Code-Execution, Authentifizierungsumgehung und vollständiger Systemkompromittierung führen.
Lösung
Verwenden Sie immer absolute, vollqualifizierte Namen für Ressourcen. Validieren Sie, dass aufgelöste Ressourcen sich an erwarteten Orten befinden. Implementieren Sie Allowlists für akzeptable Ressourcenstandorte. Verwenden Sie Package-Lock-Dateien und verifizieren Sie die Paketintegrität mit Checksummen. Pinnen Sie spezifische Versionen statt schwimmender Tags. Implementieren Sie ordnungsgemäße Symlink-Behandlung, die kanonische Pfade validiert. Verwenden Sie sichere DNS-Einstellungen und implementieren Sie DNS-Pinning wo anwendbar. Für Webanwendungen verwenden Sie strikte URL-Analyse und Validierung. Setzen Sie Code-Signing und Signaturverifizierung für geladene Bibliotheken ein.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Zugriffskontrolle | Bereich: Authentifizierungsumgehung Fehlerhaft aufgelöste Namen können Zugriffskontrollen umgehen, wenn Path-Confusion auftritt. |
| Integrität | Bereich: Codeausführung Das Laden von vom Angreifer kontrollierten Bibliotheken oder Code ermöglicht willkürliche Codeausführung. |
| Vertraulichkeit | Bereich: Informationspreisgabe Namensauflösungsangriffe können Anfragen umleiten, um sensible Daten abzufangen. |
Beispielcode + Lösungscode
Verwundbarer Code
// VERWUNDBAR: Relative Pfadauflösung ermöglicht Ausbruch
public class FileService {
private static final String BASE_DIR = "/app/data/";
public File getFile(String filename) {
// Angreifer liefert "../../etc/passwd" - verlässt Basisverzeichnis!
return new File(BASE_DIR + filename);
}
}
// VERWUNDBAR: Bibliothek wird nach Namen geladen, nicht absolutem Pfad
public class PluginLoader {
public void loadPlugin(String pluginName) {
// Durchsucht PATH/LD_LIBRARY_PATH - Angreifer kann bösartige Bibliothek einschleusen
System.loadLibrary(pluginName);
}
}
# VERWUNDBAR: Dynamischer Import mit benutzergesteuertem Namen
import importlib
def load_handler(handler_name):
# Angreifer liefert "os" und ruft Systembefehle auf!
module = importlib.import_module(handler_name)
return module.handle()
# VERWUNDBAR: Package Dependency Confusion
# requirements.txt:
# company-internal-lib==1.0.0
#
# Wenn Angreifer "company-internal-lib" auf PyPI mit höherer Version veröffentlicht,
# könnte pip das bösartige Paket stattdessen installieren
// VERWUNDBAR: Path Traversal beim URL-Parsing
const express = require('express');
const path = require('path');
app.get('/files/:filename', (req, res) => {
const filepath = path.join(__dirname, 'files', req.params.filename);
// req.params.filename = "../../../etc/passwd" entkommt!
res.sendFile(filepath);
});
// VERWUNDBAR: DNS-Rebinding-anfälliger Code
async function fetchData(url) {
const response = await fetch(url);
// Initiales DNS löst zu Angreifer-Server auf, der 200 zurückgibt
// TTL läuft ab, zweite Anfrage löst zu internem Server auf
const data = await response.json();
// Angreifers JS hat jetzt Zugriff auf interne Server-Antwort
}
Lösungscode
// SICHER: Aufgelösten Pfad auf erlaubtes Verzeichnis validieren
import java.nio.file.Path;
import java.nio.file.Paths;
public class SecureFileService {
private static final Path BASE_DIR = Paths.get("/app/data/").toRealPath();
public File getFileSafe(String filename) throws IOException {
// Pfad auflosen und normalisieren
Path requestedPath = BASE_DIR.resolve(filename).normalize();
// Verifizieren, dass aufgelöster Pfad noch innerhalb BASE_DIR ist
if (!requestedPath.startsWith(BASE_DIR)) {
throw new SecurityException("Path-Traversal-Versuch erkannt");
}
// Verifizieren, dass Datei existiert und reguläre Datei ist
File file = requestedPath.toFile();
if (!file.exists() || !file.isFile()) {
throw new FileNotFoundException("Datei nicht gefunden");
}
return file;
}
}
// SICHER: Bibliothek mit absoluter Pfadverifizierung laden
public class SecurePluginLoader {
private static final Path PLUGIN_DIR = Paths.get("/app/plugins/").toRealPath();
private static final Set<String> ALLOWED_PLUGINS = Set.of("auth", "logging", "cache");
public void loadPluginSafe(String pluginName) throws Exception {
// Plugin-Name gegen Allowlist validieren
if (!ALLOWED_PLUGINS.contains(pluginName)) {
throw new SecurityException("Unbekanntes Plugin: " + pluginName);
}
// Absoluten Pfad erstellen
Path pluginPath = PLUGIN_DIR.resolve("lib" + pluginName + ".so").toRealPath();
// Verifizieren, dass Pfad innerhalb Plugin-Verzeichnis ist
if (!pluginPath.startsWith(PLUGIN_DIR)) {
throw new SecurityException("Ungültiger Plugin-Pfad");
}
// Signatur vor Laden verifizieren
if (!verifySignature(pluginPath)) {
throw new SecurityException("Plugin-Signaturverifizierung fehlgeschlagen");
}
System.load(pluginPath.toString());
}
}
# SICHER: Dynamischer Import nur aus Allowlist
import importlib
ALLOWED_HANDLERS = {
'email': 'handlers.email_handler',
'sms': 'handlers.sms_handler',
'push': 'handlers.push_handler'
}
def load_handler_safe(handler_name):
if handler_name not in ALLOWED_HANDLERS:
raise ValueError(f"Unbekannter Handler: {handler_name}")
module_path = ALLOWED_HANDLERS[handler_name]
module = importlib.import_module(module_path)
return module.Handler()
# SICHER: Package-Abhängigkeit mit Hash-Verifizierung
# requirements.txt:
# company-internal-lib==1.0.0 --hash=sha256:abc123...
#
# pip.conf:
# [global]
# index-url = https://private.example.com/simple/
# extra-index-url = https://pypi.org/simple/
#
# Scoped-Namen verwenden: @company/internal-lib
# SICHER: Pfadauflösung mit Validierung
from pathlib import Path
BASE_DIR = Path('/app/data').resolve()
def get_file_safe(filename):
# Vollständigen Pfad auflosen
requested = (BASE_DIR / filename).resolve()
# Verifizieren, dass innerhalb Basisverzeichnis
if not str(requested).startswith(str(BASE_DIR)):
raise SecurityError("Path-Traversal erkannt")
if not requested.exists() or not requested.is_file():
raise FileNotFoundError()
return requested
// SICHER: Strikte Pfadvalidierung
const express = require('express');
const path = require('path');
const FILES_DIR = path.resolve(__dirname, 'files');
app.get('/files/:filename', (req, res) => {
const filename = path.basename(req.params.filename); // Pfadkomponenten entfernen
const filepath = path.resolve(FILES_DIR, filename);
// Verifizieren, dass aufgelöster Pfad im erlaubten Verzeichnis ist
if (!filepath.startsWith(FILES_DIR + path.sep)) {
return res.status(403).json({ error: 'Zugriff verweigert' });
}
// Prüfen ob Datei existiert
if (!fs.existsSync(filepath)) {
return res.status(404).json({ error: 'Nicht gefunden' });
}
res.sendFile(filepath);
});
// SICHER: DNS-Rebinding-Schutz
const ALLOWED_HOSTS = new Set(['api.example.com', 'internal.example.com']);
async function fetchDataSafe(url) {
const parsed = new URL(url);
// Hostname gegen Allowlist validieren
if (!ALLOWED_HOSTS.has(parsed.hostname)) {
throw new Error('Hostname nicht erlaubt');
}
// IP-Adresse für Dauer der Anfrage pinnen
const addresses = await dns.promises.resolve4(parsed.hostname);
const pinnedIp = addresses[0];
// Validieren, dass IP nicht intern ist
if (isPrivateIP(pinnedIp)) {
throw new Error('Zugriff auf private IP nicht möglich');
}
const response = await fetch(url, {
headers: { 'Host': parsed.hostname }
});
return response.json();
}
Ausgenutzt in der Praxis
Hono Framework Path Confusion (Hono, 2025)
CVE-2025-58362 in Hono 4.8.0-4.9.5 ermöglicht Angreifern, fehlerhafte Request-URIs zu erstellen, die falsche Pfadextraktion verursachen, Proxy-ACLs wie Nginx-Location-Blöcke umgehen und Zugriff auf geschützte Endpunkte wie /admin ohne Authentifizierung erhalten (CVSS 7.5).
tj-actions Supply Chain Angriff (GitHub, 2025)
Die tj-actions/changed-files Repository-Tags v1-v45.0.7 wurden von Bedrohungsakteuren am 14.-15. März 2025 modifiziert, um auf einen bösartigen Commit zu zeigen, der Code enthielt, der Secrets aus Action-Logs preisgab.
Apache Camel Header Injection (Apache, 2025)
Schwachstellen in Apache Camel ermöglichen Angreifern, Camel-spezifische Header über HTTP-Anfragen einzuschleusen, die das Verhalten von Komponenten wie camel-bean und camel-exec ändern.
Tools zum Testen/Ausnutzen
-
Burp Suite - Path-Traversal und URL-Parsing-Probleme testen.
-
DLL Hijack Auditor - Namensauflösungsangriffe identifizieren.
-
Snyk - Dependency-Confusion-Schwachstellen erkennen.
CVE-Beispiele
-
CVE-2025-58362 - Hono Path-Confusion-Schwachstelle.
-
CVE-2024-27292 - Docassemble Path-Traversal.
-
CVE-2023-42451 - Mastodon Redirect-Validierungsumgehung.
Referenzen
-
MITRE. "CWE-706: Use of Incorrectly-Resolved Name or Reference." https://cwe.mitre.org/data/definitions/706.html
-
OWASP. "Path Traversal." https://owasp.org/www-community/attacks/Path_Traversal