Exponierung von Ressourcen an falsche Sphäre
Beschreibung
Exponierung von Ressourcen an falsche Sphäre tritt auf, wenn ein Produkt eine Ressource der falschen Kontrollsphäre aussetzt und unbeabsichtigten Akteuren unangemessenen Zugriff auf die Ressource gewährt. Eine "Kontrollsphäre" ist eine Menge von Ressourcen und Verhaltensweisen, die einem einzelnen Akteur oder einer Gruppe von Akteuren zugänglich sind. Produkte definieren typischerweise mehrere Sphären—Administratoren, reguläre Benutzer, Gäste, externe Systeme—jeweils mit unterschiedlichen Zugriffsebenen. Wenn Ressourcen, die für eine Sphäre bestimmt sind, einer anderen zugänglich sind, können Angreifer auf sensible Daten, Funktionalitäten oder Dienste zugreifen, zu denen sie keinen Zugang haben sollten, was zu Privilegieneskalation, Informationsoffenlegung oder unbefugten Operationen führt.
Risiko
Die Exponierung von Ressourcen an falsche Sphären ist ein grundlegender Zugriffskontrollfehler. CVE-2025-49574 im Quarkus-Framework ermöglicht das Durchsickern von Transaktionsdaten einschließlich Sicherheitsanmeldedaten über Transaktionsgrenzen hinweg aufgrund von Kontext-Duplikationsproblemen. CVE-2024-5313 bei Schneider Electric exponiert SSH-Schnittstellen über Produktnetzwerkschnittstellen. CVE-2025-6788 exponiert TGML-Diagramme an falsche Kontrollsphären. Diese Schwachstellen wurden in IBM Business Automation, HPE-Servern und Lenovo Intel DTT Software gefunden. Wenn Ressourcen Kontrollsphärengrenzen überschreiten, können Angreifer auf administrative Funktionen zugreifen, vertrauliche Daten lesen oder Systeme über ihre Autorisierungsebene hinaus manipulieren.
Lösung
Implementieren Sie ordnungsgemäße Zugriffskontrollgrenzen zwischen Kontrollsphären. Verwenden Sie das Prinzip der minimalen Rechte—Ressourcen sollten nur dem minimalen Satz von Akteuren zugänglich sein, die sie benötigen. Validieren Sie die Autorisierung an jedem Zugriffspunkt, nicht nur auf der UI-Ebene. Implementieren Sie Netzwerksegmentierung, um Ressourcen zwischen Sphären zu isolieren. Verwenden Sie separate Prozesse oder Container für unterschiedliche Vertrauensebenen. Prüfen Sie die Ressourcenexponierung während Design und Test. Implementieren Sie ordnungsgemäße Session-Isolierung, um sphärenübergreifende Datenlecks zu verhindern. Verwenden Sie defensive Programmierung, um den Kontext vor dem Zugriff auf sensible Ressourcen zu validieren.
Häufige Konsequenzen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Bereich: Informationsoffenlegung Ressourcen für privilegierte Benutzer könnten weniger privilegierten oder externen Akteuren zugänglich sein. |
| Integrität | Bereich: Unbefugte Modifikation Angreifer in der falschen Sphäre könnten Ressourcen modifizieren, auf die sie keinen Zugriff haben sollten. |
| Zugriffskontrolle | Bereich: Privilegieneskalation Zugriff auf Ressourcen der falschen Sphäre ermöglicht oft weitere Privilegieneskalation. |
Beispielcode + Lösungscode
Verwundbarer Code
// VERWUNDBAR: Admin-Funktionalität allen authentifizierten Benutzern exponiert
@RestController
@RequestMapping("/api")
public class AdminController {
// Keine Rollenprüfung - jeder authentifizierte Benutzer kann zugreifen!
@GetMapping("/admin/users")
public List<User> getAllUsers() {
return userRepository.findAll(); // Enthält sensible Daten
}
@DeleteMapping("/admin/users/{id}")
public void deleteUser(@PathVariable Long id) {
userRepository.deleteById(id); // Jeder Benutzer kann löschen!
}
}
// VERWUNDBAR: Thread-lokaler Kontext leckt über Anfragen hinweg
public class RequestContext {
private static ThreadLocal<UserSession> currentSession = new ThreadLocal<>();
public static void setSession(UserSession session) {
currentSession.set(session);
}
public static UserSession getSession() {
return currentSession.get(); // Könnte vorherige Benutzer-Session zurückgeben!
}
// Fehlende Bereinigung - Session leckt zur nächsten Anfrage
}
# VERWUNDBAR: Debug-Endpoint in Produktion exponiert
from flask import Flask, request, jsonify
app = Flask(__name__)
# Debug-Route ohne Authentifizierung zugänglich!
@app.route('/debug/config')
def debug_config():
# Exponiert interne Konfiguration an jeden
return jsonify({
'database_url': app.config['DATABASE_URL'],
'secret_key': app.config['SECRET_KEY'],
'api_keys': app.config['EXTERNAL_API_KEYS']
})
# VERWUNDBAR: Interne API extern exponiert
@app.route('/internal/metrics')
def internal_metrics():
# Sollte nur vom internen Netzwerk zugänglich sein
return jsonify(get_system_metrics())
// VERWUNDBAR: Mandantenübergreifende Datenexponierung
class MultiTenantService {
constructor() {
this.dataCache = new Map(); // Geteilter Cache über Mandanten!
}
async getData(userId, dataId) {
const cacheKey = dataId; // Keine Mandantenisolierung im Cache-Schlüssel
if (this.dataCache.has(cacheKey)) {
// Gibt möglicherweise Daten eines anderen Mandanten zurück!
return this.dataCache.get(cacheKey);
}
const data = await this.db.findById(dataId);
this.dataCache.set(cacheKey, data);
return data;
}
}
// VERWUNDBAR: Datei-Upload für falsche Sphäre zugänglich
app.post('/upload', upload.single('file'), (req, res) => {
// Dateien in öffentlich zugänglichem Verzeichnis gespeichert
const path = `/public/uploads/${req.file.filename}`;
res.json({ url: path });
});
Lösungscode
// SICHER: Ordnungsgemäße rollenbasierte Zugriffskontrolle
@RestController
@RequestMapping("/api")
public class SecureAdminController {
@GetMapping("/admin/users")
@PreAuthorize("hasRole('ADMIN')") // Nur Admins können zugreifen
@Secured("ROLE_ADMIN")
public List<UserDTO> getAllUsers() {
// DTO ohne sensible Felder zurückgeben
return userRepository.findAll().stream()
.map(this::toSafeDTO)
.collect(Collectors.toList());
}
@DeleteMapping("/admin/users/{id}")
@PreAuthorize("hasRole('ADMIN')")
@Transactional
public void deleteUser(@PathVariable Long id, Principal principal) {
// Aktion protokollieren
auditLog.info("Benutzer {} gelöscht von Admin {}",
id, principal.getName());
userRepository.deleteById(id);
}
private UserDTO toSafeDTO(User user) {
// Sensible Felder ausschließen
return new UserDTO(user.getId(), user.getUsername(), user.getEmail());
}
}
// SICHER: Ordnungsgemäße Kontextbereinigung
public class SecureRequestContext implements AutoCloseable {
private static final ThreadLocal<UserSession> currentSession = new ThreadLocal<>();
public static void setSession(UserSession session) {
currentSession.set(session);
}
public static UserSession getSession() {
UserSession session = currentSession.get();
if (session == null) {
throw new SecurityException("Keine Session im Kontext");
}
return session;
}
@Override
public void close() {
// Immer bereinigen um Lecks zu verhindern
currentSession.remove();
}
}
// Verwendung mit try-with-resources
try (SecureRequestContext ctx = new SecureRequestContext()) {
SecureRequestContext.setSession(userSession);
processRequest();
} // Automatisch bereinigt
# SICHER: Debug-Endpoints in Produktion deaktiviert
from flask import Flask, request, jsonify, abort
import os
app = Flask(__name__)
def require_debug_mode(f):
"""Nur im Debug-Modus erlauben."""
@wraps(f)
def decorated(*args, **kwargs):
if not app.debug:
abort(404) # Endpoint in Produktion verstecken
return f(*args, **kwargs)
return decorated
@app.route('/debug/config')
@require_debug_mode # Funktioniert nur im Debug-Modus
def debug_config():
# Ausgabe auch im Debug-Modus bereinigen
return jsonify({
'environment': app.config['ENV'],
'debug': app.debug
# Niemals Geheimnisse exponieren
})
# SICHER: Interne Endpoints durch Netzwerk und Authentifizierung geschützt
@app.route('/internal/metrics')
@require_internal_network # Quell-IP prüfen
@require_service_auth # Service-zu-Service-Auth erfordern
def internal_metrics():
return jsonify(get_system_metrics())
def require_internal_network(f):
@wraps(f)
def decorated(*args, **kwargs):
client_ip = request.remote_addr
if not is_internal_ip(client_ip):
abort(403)
return f(*args, **kwargs)
return decorated
// SICHER: Mandantenisoliertes Caching
class SecureMultiTenantService {
constructor() {
this.dataCache = new Map();
}
async getData(tenantId, userId, dataId) {
// Mandant im Cache-Schlüssel für Isolierung einbeziehen
const cacheKey = `${tenantId}:${dataId}`;
if (this.dataCache.has(cacheKey)) {
const cached = this.dataCache.get(cacheKey);
// Mandanteneigentum verifizieren
if (cached.tenantId !== tenantId) {
throw new SecurityError('Mandantenübergreifender Zugriff verweigert');
}
return cached;
}
const data = await this.db.findById(dataId);
// Verifizieren, dass Daten zum anfragenden Mandanten gehören
if (data.tenantId !== tenantId) {
throw new SecurityError('Daten gehören nicht zum Mandanten');
}
this.dataCache.set(cacheKey, data);
return data;
}
}
// SICHER: Datei-Uploads in privatem Ort mit Zugriffskontrolle gespeichert
const UPLOAD_BASE = '/private/uploads';
app.post('/upload', authenticate, upload.single('file'), async (req, res) => {
const userId = req.user.id;
// In benutzerspezifischem privatem Verzeichnis speichern
const userDir = path.join(UPLOAD_BASE, userId.toString());
await fs.mkdir(userDir, { recursive: true });
const filename = `${crypto.randomUUID()}-${req.file.originalname}`;
const filepath = path.join(userDir, filename);
await fs.rename(req.file.path, filepath);
// Signierte URL für Zugriffskontrolle zurückgeben
const signedUrl = generateSignedUrl(filepath, req.user);
res.json({ url: signedUrl });
});
// Dateien durch zugriffskontrollierten Endpoint bereitgestellt
app.get('/files/:userId/:filename', authenticate, async (req, res) => {
// Verifizieren, dass Benutzer auf diese Datei zugreifen kann
if (req.user.id !== req.params.userId && !req.user.isAdmin) {
return res.status(403).json({ error: 'Zugriff verweigert' });
}
const filepath = path.join(UPLOAD_BASE, req.params.userId, req.params.filename);
res.sendFile(filepath);
});
Ausgenutzt in der Praxis
Quarkus Framework Kontextleck (Quarkus, 2025)
CVE-2025-49574 im Quarkus-Framework vor 3.24.1 ermöglicht das Durchsickern von Transaktionsdaten einschließlich Sicherheitsanmeldedaten und Metadaten über Transaktionsgrenzen hinweg, wenn Vert.x-Kontexte mehrfach dupliziert werden, was Isolierungsprinzipien verletzt.
Schneider Electric SSH-Exponierung (Schneider Electric, 2024)
CVE-2024-5313 in Schneider Electric-Produkten exponiert SSH-Schnittstellen an die Produktnetzwerkschnittstelle, was Port-Scanning, Fingerprinting und potentielle Denial-of-Service-Angriffe auf exponierte SSH-Dienste ermöglicht.
TGML-Diagramm-Exponierung (2025)
CVE-2025-6788 exponiert TGML-Diagramm-Ressourcen an falsche Kontrollsphären und ermöglicht authentifizierten Benutzern den Zugriff auf Diagramme, auf die sie keinen Zugriff haben sollten.
Werkzeuge zum Testen/Ausnutzen
-
Burp Suite — Zugriffskontrollgrenzen testen.
-
OWASP ZAP — Automatisierte Zugriffskontrolltests.
-
Postman — API-Zugriff über verschiedene Benutzerrollen testen.
CVE-Beispiele
-
CVE-2025-49574 — Quarkus-Kontextdatenleck.
-
CVE-2024-5313 — Schneider Electric SSH-Exponierung.
-
CVE-2023-27976 — Zoom-Ressourcenexponierungs-Schwachstelle.
Referenzen
-
MITRE. "CWE-668: Exposure of Resource to Wrong Sphere." https://cwe.mitre.org/data/definitions/668.html
-
OWASP. "Broken Access Control." https://owasp.org/Top10/A01_2021-Broken_Access_Control/