Unsachgemäße Einschränkung des Stromverbrauchs
Beschreibung
Unsachgemäße Einschränkung des Stromverbrauchs tritt auf, wenn Software in Umgebungen betrieben wird, in denen Strom eine begrenzte Ressource ist, die nicht automatisch aufgefüllt werden kann (wie batteriebetriebene Geräte), aber die Strommenge, die der Betrieb verbraucht, nicht ordnungsgemäß einschränkt. Diese Schwachstelle ist besonders relevant für mobile Geräte, eingebettete Systeme, IoT-Geräte und jede batteriebetriebene Ausrüstung. Angreifer können diese Schwäche ausnutzen, indem sie Operationen auslösen, die übermäßigen Stromverbrauch durch Komponenten wie CPU-intensive Berechnungen, Display-Helligkeit, GPS-Empfänger, Funkmodule, Festplatten-I/O, Soundsysteme, Kameras oder USB-Schnittstellen verursachen.
Risiko
Die Ausnutzung dieser Schwachstelle kann zu einem vollständigen Denial-of-Service durch Entleerung der Gerätebatterie führen. Bei mobilen Geräten kann dies Telefone in kritischen Situationen unbrauchbar machen. In IoT- und eingebetteten Systemen kann Stromerschöpfung Sicherheitssysteme, medizinische Geräte oder industrielle Steuerungen deaktivieren. Kontinuierliche Stromverbrauchsangriffe können die Batterielebensdauer durch übermäßige Ladezyklen verkürzen. In sicherheitskritischen Systemen kann unerwarteter Stromverlust schwerwiegende Folgen haben. Der Angriff kann persistent und schwer zu erkennen sein, da der Stromverbrauch eher mit normalem Betrieb als mit bösartiger Aktivität zusammenzuhängen scheint.
Lösung
Implementieren Sie Stromverbrauchsbudgets und -überwachung für alle Operationen. Begrenzen Sie die Häufigkeit stromintensiver Operationen. Verwenden Sie stromeffiziente Algorithmen und Hardware-Funktionen wie Schlafmodi. Implementieren Sie Rate-Limiting für Operationen, die hohen Stromverbrauch auslösen. Überwachen und warnen Sie bei ungewöhnlichen Stromverbrauchsmustern. Entwerfen Sie Anwendungen, um niedrige Stromzustände elegant zu handhaben. Validieren Sie Eingaben, die stromverbrauchende Operationen steuern, um Missbrauch zu verhindern. Erwägen Sie die Implementierung von Stromverbrauchslimits pro Zeitraum. Nutzen Sie Hardware-Strommanagement-Funktionen effektiv. Für mobile Apps folgen Sie den Plattformrichtlinien für Hintergrundverarbeitung und Wake Locks.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Verfügbarkeit | Bereich: Verfügbarkeit DoS: Ressourcenverbrauch - Übermäßiger Stromverbrauch entleert Batterien und führt dazu, dass Geräte herunterfahren und nicht mehr verfügbar sind. |
| Verfügbarkeit | Bereich: Verfügbarkeit DoS: Absturz/Beenden/Neustart - Stromerschöpfung kann dazu führen, dass Anwendungen und ganze Geräte aufhören zu funktionieren. |
Beispielcode
Anfälliger Code
// Anfällig: Android-App mit uneingeschränkter GPS-Nutzung
public class VulnerableLocationService extends Service {
private LocationManager locationManager;
@Override
public void onCreate() {
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
}
public void startTracking(int intervalMs) {
// Anfällig: Keine Validierung des Intervalls, GPS immer an
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
intervalMs, // Angreifer kann 0 für konstante Updates setzen
0,
locationListener
);
// Anfällig: Keine Berücksichtigung des Stromverbrauchs, GPS entleert Batterie schnell
}
}
// Angriff: Tracking mit intervalMs=0 starten, um Batterie schnell zu entleeren
// Anfällig: Uneingeschränkte Wake-Lock-Nutzung
public class VulnerableBackgroundTask {
private PowerManager.WakeLock wakeLock;
public void startTask(Context context) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
// Anfällig: Wake Lock ohne Timeout erwerben
wakeLock = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
"MyApp::BackgroundTask"
);
wakeLock.acquire(); // Kein Timeout - hält CPU unbegrenzt laufen
// Wenn Task nie abschließt oder abstürzt, entleert sich die Batterie
}
// Anfällig: Wird möglicherweise nie aufgerufen, wenn Task fehlschlägt
public void stopTask() {
if (wakeLock != null && wakeLock.isHeld()) {
wakeLock.release();
}
}
}
// Anfällig: iOS-App mit konstantem Netzwerk-Polling
class VulnerableNetworkPoller {
var timer: Timer?
func startPolling(intervalSeconds: Double) {
// Anfällig: Kein Mindestintervall, keine Stromzuständsprüfung
timer = Timer.scheduledTimer(
withTimeInterval: intervalSeconds, // Könnte 0.001 sein
repeats: true
) { _ in
self.fetchData()
}
}
func fetchData() {
// Jede Netzwerkanfrage verhindert Schlaf und nutzt Funk
URLSession.shared.dataTask(with: url) { data, response, error in
// Daten verarbeiten
}.resume()
}
}
// Angriff: Intervall auf 0.001 für 1000 Anfragen/Sekunde setzen
// Anfällig: Eingebettetes System ohne Strommanagement
void vulnerable_sensor_read(void) {
// Anfällig: Sensor immer an, keine Schlafmodi
while (1) {
// Konstantes Sensorlesen ohne Verzögerung
int value = read_sensor();
process_data(value);
// Kein Schlaf, kein Strommanagement
// CPU und Sensor immer auf voller Leistung
}
}
Korrigierter Code
// Korrigiert: Android-App mit strombewusster GPS-Nutzung
public class FixedLocationService extends Service {
private LocationManager locationManager;
private static final long MIN_UPDATE_INTERVAL_MS = 10000; // 10 Sekunden Minimum
private static final long MAX_ACTIVE_TIME_MS = 300000; // 5 Minuten Maximum
private Handler timeoutHandler = new Handler(Looper.getMainLooper());
@Override
public void onCreate() {
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
}
public void startTracking(long requestedIntervalMs) {
// Korrigiert: Mindestintervall erzwingen
long interval = Math.max(requestedIntervalMs, MIN_UPDATE_INTERVAL_MS);
// Korrigiert: Batteriestand vor Start prüfen
if (getBatteryLevel() < 20) {
Log.w(TAG, "Batterie zu niedrig für GPS-Tracking");
return;
}
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
interval,
10, // 10 Meter Mindestdistanz
locationListener
);
// Korrigiert: Automatischer Timeout, um unbegrenzte GPS-Nutzung zu verhindern
timeoutHandler.postDelayed(this::stopTracking, MAX_ACTIVE_TIME_MS);
}
public void stopTracking() {
locationManager.removeUpdates(locationListener);
timeoutHandler.removeCallbacksAndMessages(null);
}
private int getBatteryLevel() {
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = registerReceiver(null, filter);
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
return (int) (level * 100 / (float) scale);
}
}
// Korrigiert: Sichere Wake-Lock-Nutzung mit Timeout
public class FixedBackgroundTask {
private static final long MAX_WAKE_LOCK_MS = 60000; // 1 Minute Maximum
public void startTask(Context context) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
"MyApp::BackgroundTask"
);
// Korrigiert: Mit Timeout erwerben - wird nach Timeout automatisch freigegeben
wakeLock.acquire(MAX_WAKE_LOCK_MS);
try {
performTask();
} finally {
// Korrigiert: Immer im finally-Block freigeben
if (wakeLock.isHeld()) {
wakeLock.release();
}
}
}
}
// Besser: WorkManager für Hintergrund-Tasks verwenden
public class FixedWorkManager {
public void scheduleTask(Context context) {
// WorkManager handhabt Strommanagement automatisch
Constraints constraints = new Constraints.Builder()
.setRequiresBatteryNotLow(true) // Nur ausführen, wenn Batterie OK
.build();
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
.setConstraints(constraints)
.build();
WorkManager.getInstance(context).enqueue(workRequest);
}
}
// Korrigiert: iOS-App mit strombewusstem Polling
class FixedNetworkPoller {
var timer: Timer?
private let minimumInterval: TimeInterval = 30 // 30 Sekunden Minimum
private let maxPollingDuration: TimeInterval = 300 // 5 Minuten Maximum
private var startTime: Date?
func startPolling(requestedInterval: TimeInterval) {
// Korrigiert: Mindestintervall erzwingen
let interval = max(requestedInterval, minimumInterval)
// Korrigiert: Batteriestatus prüfen
UIDevice.current.isBatteryMonitoringEnabled = true
if UIDevice.current.batteryLevel < 0.2 && UIDevice.current.batteryState != .charging {
print("Batterie zu niedrig für Polling")
return
}
startTime = Date()
timer = Timer.scheduledTimer(
withTimeInterval: interval,
repeats: true
) { [weak self] timer in
guard let self = self else {
timer.invalidate()
return
}
// Korrigiert: Prüfen, ob maximale Dauer überschritten
if let start = self.startTime,
Date().timeIntervalSince(start) > self.maxPollingDuration {
self.stopPolling()
return
}
self.fetchData()
}
}
func stopPolling() {
timer?.invalidate()
timer = nil
}
}
// Korrigiert: Eingebettetes System mit Strommanagement
#include <power_management.h>
void fixed_sensor_read(void) {
uint32_t last_read_time = 0;
const uint32_t MIN_INTERVAL_MS = 1000; // 1 Sekunde Minimum
while (1) {
uint32_t current_time = get_system_time_ms();
// Korrigiert: Rate-Limiting
if (current_time - last_read_time < MIN_INTERVAL_MS) {
// In Niedrigstrommodus wechseln während des Wartens
enter_sleep_mode(MIN_INTERVAL_MS - (current_time - last_read_time));
continue;
}
last_read_time = current_time;
// Sensor nur bei Bedarf aktivieren
sensor_power_on();
int value = read_sensor();
sensor_power_off(); // Sensor nach Lesen deaktivieren
process_data(value);
// In Niedrigstrommodus zwischen Lesevorgängen wechseln
enter_sleep_mode(MIN_INTERVAL_MS);
}
}
Verwandte CWEs
- CWE-400: Uncontrolled Resource Consumption (Eltern)
- CWE-770: Allocation of Resources Without Limits or Throttling (verwandt)
- CWE-399: Resource Management Errors (Kategorie)
Referenzen
- MITRE Corporation. "CWE-920: Improper Restriction of Power Consumption." https://cwe.mitre.org/data/definitions/920.html
- Android Developers. "Optimize for battery life." https://developer.android.com/training/monitoring-device-state/battery-monitoring
- Apple Developer Documentation. "Energy Efficiency Guide for iOS Apps."