Initialisierung mit hartkodierten Netzwerkressourcen-Konfigurationsdaten
Beschreibung
Initialisierung mit hartkodierten Netzwerkressourcen-Konfigurationsdaten tritt auf, wenn Software Daten mit hartkodierten Werten initialisiert, die als Netzwerkressourcen-Identifikatoren fungieren. Dies umfasst das Einbetten von IP-Adressen, Hostnamen, Portnummern, URLs, API-Endpunkten oder anderen Netzwerkkonfigurationen direkt im Quellcode, anstatt externe Konfigurationsdateien, Umgebungsvariablen oder dynamische Erkennungsmechanismen zu verwenden. Solche Hartkodierung macht die Software unflexibel und kann zu Ausfällen führen, wenn sie in verschiedenen Netzwerkumgebungen bereitgestellt wird.
Risiko
Obwohl primär ein Zuverlässigkeits- und Wartbarkeitsproblem, hat hartkodierte Netzwerkkonfiguration Sicherheitsimplikationen. Hartkodierte Anmeldedaten oder Endpunkte können aus kompiliertem Code extrahiert werden. Das Ändern kompromittierter Endpunkte erfordert Code-Änderungen und Neubereitstellung anstatt Konfigurationsaktualisierungen. Im Code exponierte interne Netzwerkadressen können Infrastrukturdetails an Angreifer preisgeben. Anwendungen können möglicherweise nicht auf Backup- oder Failover-Systeme umschalten. Sicherheitspatches für Endpunktänderungen werden langsamer bereitgestellt. In einigen Fällen können hartkodierte Werte auf Test- oder Entwicklungsumgebungen verweisen, die keine Produktionssicherheitskontrollen haben.
Lösung
Externalisieren Sie die Netzwerkkonfiguration durch: (1) Konfigurationsdateien (mit ordnungsgemäßen Zugriffskontrollen), (2) Umgebungsvariablen, (3) Service-Discovery-Mechanismen, (4) Container-Orchestrierungskonfiguration (Kubernetes ConfigMaps usw.), (5) Zentralisierte Konfigurationsdienste (Consul, etcd, Spring Cloud Config). Stellen Sie sinnvolle Standardwerte bereit und ermöglichen Sie deren Überschreibung. Validieren Sie die Konfiguration beim Start. Verwenden Sie DNS-Namen anstelle von IP-Adressen, wo möglich. Implementieren Sie Konfigurationsaktualisierungsmechanismen für Laufzeitaktualisierungen. Verschlüsseln Sie sensible Netzwerkkonfigurationen wie API-Schlüssel oder Authentifizierungsendpunkte.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Sonstiges | Bereich: Sonstiges Reduzierte Zuverlässigkeit - Anwendung kann in Umgebungen fehlschlagen, die nicht den hartkodierten Netzwerk-Identifikatoren entsprechen. |
| Sonstiges | Bereich: Sonstiges Reduzierte Wartbarkeit - Änderung der Netzwerkkonfiguration erfordert Code-Änderungen, was die Sicherheitsreaktion verlangsamt. |
| Vertraulichkeit | Bereich: Vertraulichkeit Informationsoffenlegung - Im Code hartkodierte interne Adressen können Infrastrukturdetails preisgeben. |
Beispielcode und Lösung
Verwundbarer Code
// Verwundbar: Hartkodierte Netzwerkkonfiguration
public class VerwundbarerApiClient {
// Verwundbar: Hartkodierte URL
private static final String API_URL = "https://api.production.example.com:8443";
// Verwundbar: Hartkodierte IP-Adresse
private static final String DATABASE_HOST = "192.168.1.100";
private static final int DATABASE_PORT = 5432;
// Verwundbar: Hartkodierter Backup-Server
private static final String BACKUP_SERVER = "10.0.0.50";
public void connect() {
// Diese Werte können nicht ohne Neukompilierung geändert werden
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(API_URL + "/health"))
.build();
// Wenn API_URL kompromittiert wird oder sich ändert, muss Code geändert werden
}
}
# Verwundbar: Hartkodierte Endpunkte in Python
class VerwundbarerService:
# Verwundbar: Hartkodierte Konfiguration
API_ENDPOINT = "https://internal-api.company.local:8080"
REDIS_HOST = "172.16.0.10"
REDIS_PORT = 6379
MESSAGE_QUEUE = "amqp://10.0.1.50:5672"
def __init__(self):
# Alle Verbindungen verwenden hartkodierte Werte
self.redis = redis.Redis(host=self.REDIS_HOST, port=self.REDIS_PORT)
self.mq = pika.BlockingConnection(
pika.URLParameters(self.MESSAGE_QUEUE)
)
Sichere Lösung
// Sicher: Externalisierte Netzwerkkonfiguration
public class SichererApiClient {
private final String apiUrl;
private final String databaseHost;
private final int databasePort;
// Sicher: Konfiguration über Konstruktor injiziert
public SichererApiClient(NetzwerkKonfig config) {
this.apiUrl = config.getApiUrl();
this.databaseHost = config.getDatabaseHost();
this.databasePort = config.getDatabasePort();
}
// Alternative: Aus Konfigurationsdatei laden
public static SichererApiClient ausKonfig() {
Properties props = loadProperties("network.properties");
return new SichererApiClient(
new NetzwerkKonfig(
props.getProperty("api.url"),
props.getProperty("database.host"),
Integer.parseInt(props.getProperty("database.port"))
)
);
}
// Alternative: Aus Umgebungsvariablen laden
public static SichererApiClient ausUmgebung() {
return new SichererApiClient(
new NetzwerkKonfig(
System.getenv("API_URL"),
System.getenv("DB_HOST"),
Integer.parseInt(System.getenv("DB_PORT"))
)
);
}
}
// Konfigurationsklasse mit Validierung
public class NetzwerkKonfig {
private final String apiUrl;
private final String databaseHost;
private final int databasePort;
public NetzwerkKonfig(String apiUrl, String databaseHost, int databasePort) {
// Konfiguration validieren
Objects.requireNonNull(apiUrl, "API-URL ist erforderlich");
Objects.requireNonNull(databaseHost, "Datenbank-Host ist erforderlich");
if (databasePort < 1 || databasePort > 65535) {
throw new IllegalArgumentException("Ungültige Portnummer");
}
this.apiUrl = apiUrl;
this.databaseHost = databaseHost;
this.databasePort = databasePort;
}
}
# Sicher: Konfigurationsbasierte Netzwerkeinstellungen
import os
from dataclasses import dataclass
from typing import Optional
import yaml
@dataclass
class NetzwerkKonfig:
api_endpoint: str
redis_host: str
redis_port: int
message_queue: str
@classmethod
def aus_umgebung(cls) -> 'NetzwerkKonfig':
"""Konfiguration aus Umgebungsvariablen laden"""
return cls(
api_endpoint=os.environ['API_ENDPOINT'],
redis_host=os.environ.get('REDIS_HOST', 'localhost'),
redis_port=int(os.environ.get('REDIS_PORT', '6379')),
message_queue=os.environ['MESSAGE_QUEUE_URL']
)
@classmethod
def aus_datei(cls, pfad: str) -> 'NetzwerkKonfig':
"""Konfiguration aus YAML-Datei laden"""
with open(pfad) as f:
config = yaml.safe_load(f)
return cls(
api_endpoint=config['api']['endpoint'],
redis_host=config['redis']['host'],
redis_port=config['redis']['port'],
message_queue=config['messaging']['url']
)
def validieren(self):
"""Konfigurationswerte validieren"""
if not self.api_endpoint.startswith('https://'):
raise ValueError("API-Endpunkt muss HTTPS verwenden")
if not 1 <= self.redis_port <= 65535:
raise ValueError("Ungültiger Redis-Port")
class SichererService:
def __init__(self, config: NetzwerkKonfig):
config.validieren()
self.config = config
self.redis = redis.Redis(
host=config.redis_host,
port=config.redis_port
)
CVE-Beispiele
Diese CWE ist als VERBOTEN für direkte CVE-Zuordnung markiert, da sie eher ein Qualitäts-/Zuverlässigkeitsproblem als eine direkte Sicherheitsschwachstelle darstellt.
Referenzen
-
MITRE Corporation. "CWE-1051: Initialization with Hard-Coded Network Resource Configuration Data." https://cwe.mitre.org/data/definitions/1051.html
-
The Twelve-Factor App. "Configuration."
-
OWASP. "Configuration and Deployment Management Testing."