Embedded Systems: 5 kritische Sicherheitsfehler vermeiden
March 25, 2026Embedded Systems: 5 kritische Sicherheitsfehler, die dein Backend gefährden
Warum Embedded Systems besondere Sicherheitsherausforderungen bieten
Begrenzte Ressourcen
Lange Produktlebenszyklen
Physischer Zugang
Heterogene Lieferketten
5 kritische Sicherheitsfehler, die du vermeiden musst
1. Unsichere Kommunikationsprotokolle und fehlende Transportverschlüsselung
Python
# Beispiel: FastAPI Backend mit mTLS-Konfiguration (konzeptuell)
# Dies erfordert eine erweiterte Uvicorn/ASGI-Server-Konfiguration
# und Client-Zertifikatsvalidierung in der FastAPI-Anwendung.
from fastapi import FastAPI, Depends, HTTPException, Request, status
from starlette.middleware.base import BaseHTTPMiddleware
class MutualTLSMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
# In einer echten Umgebung würde hier die Validierung des
# Client-Zertifikats aus dem request.scope['client_cert'] oder
# ähnlichem stattfinden. Der Webserver (z.B. Nginx) würde dies
# bereitstellen.
# Beispielhafter Check: Nur fortfahren, wenn ein Zertifikat vorhanden ist
# und die Validierung durch den vorgelagerten Reverse Proxy erfolgreich war.
# Die genaue Implementierung hängt stark vom Webserver/Proxy ab.
if not request.headers.get("X-Client-Cert-Verified") == "SUCCESS":
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Client certificate required and invalid"
)
response = await call_next(request)
return response
app = FastAPI()
app.add_middleware(MutualTLSMiddleware)
@app.get("/data")
async def read_data():
return {"message": "Sensordaten empfangen"}
# Wichtiger Hinweis: Die eigentliche TLS-Terminierung und mTLS-Validierung
# sollte idealerweise auf einem vorgelagerten Reverse Proxy (Nginx, Envoy) erfolgen,
# der das validierte Zertifikat dann an die Backend-Anwendung weitergibt.
2. Mangelhafte Authentifizierung und Autorisierung der Geräte
Typescript
// Beispiel: JWT-Validierung in einem Node.js/TypeScript Backend
// Nach erfolgreicher mTLS-Authentifizierung könnte ein JWT ausgestellt werden.
import { Request, Response, NextFunction } from 'express';
import * as jwt from 'jsonwebtoken';
interface DevicePayload {
deviceId: string;
roles: string[];
}
const JWT_SECRET = process.env.JWT_SECRET || 'your_secret_key'; // In Produktion sicher verwalten!
export const authenticateDevice = (req: Request, res: Response, next: NextFunction) => {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).send('No token provided.');
}
const token = authHeader.split(' ')[1];
try {
const decoded = jwt.verify(token, JWT_SECRET) as DevicePayload;
(req as any).device = decoded; // Gerätedaten an den Request anhängen
next();
} catch (error) {
return res.status(403).send('Invalid token.');
}
};
// Verwendung in einer Express.js Route:
// app.get('/device-data', authenticateDevice, (req, res) => {
// const deviceId = (req as any).device.deviceId;
// // Zugriff auf Daten basierend auf deviceId und Rollen
// res.json({ message: `Daten für Gerät ${deviceId}` });
// });
3. Firmware-Updates ohne Integritätsprüfung und Rollback-Optionen
Bash
# Beispiel: Signieren einer Firmware-Datei mit GPG auf dem Backend-Server
# (Konzeptuell, da die GPG-Schlüsselverwaltung sehr sicher erfolgen muss)
# 1. Firmware-Image erstellen (angenommen, das ist erledigt)
FIRMWARE_FILE="firmware_v1.2.bin"
# 2. Firmware-Image mit einem privaten GPG-Schlüssel signieren
# Der private Schlüssel muss extrem gut geschützt sein!
gpg --batch --passphrase "your_secure_passphrase" --sign --output "${FIRMWARE_FILE}.sig" "${FIRMWARE_FILE}"
echo "Firmware ${FIRMWARE_FILE} wurde als ${FIRMWARE_FILE}.sig signiert."
# 3. Auf dem Embedded Device müsste dann mit dem öffentlichen Schlüssel
# des Backend-Servers die Signatur verifiziert werden:
# gpg --verify "${FIRMWARE_FILE}.sig" "${FIRMWARE_FILE}"
# Nur wenn die Verifikation erfolgreich ist, wird das Update installiert.
4. Unzureichendes Fehlermanagement und Logging
Python
# Beispiel: Einfache Log-Weiterleitung vom Embedded Device zum Backend (Python)
# Das Gerät sendet einen JSON-Log-Eintrag an einen Backend-Endpoint.
import requests
import json
import datetime
DEVICE_ID = "my_embedded_device_001"
BACKEND_LOG_ENDPOINT = "https://your-secure-backend.com/api/logs"
API_KEY = "your_device_api_key" # Sicherer als feste Keys wären JWTs oder mTLS-Identität
def send_log(level: str, message: str, details: dict = None):
log_entry = {
"timestamp": datetime.datetime.now(datetime.timezone.utc).isoformat(),
"device_id": DEVICE_ID,
"level": level,
"message": message,
"details": details or {}
}
try:
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {API_KEY}" # Oder mTLS-basierte Auth
}
response = requests.post(BACKEND_LOG_ENDPOINT, json=log_entry, headers=headers, timeout=5)
response.raise_for_status() # Löst HTTPError für 4xx/5xx Antworten aus
print(f"Log sent successfully: {log_entry['message']}")
except requests.exceptions.RequestException as e:
print(f"Failed to send log: {e}")
# Beispielhafte Verwendung:
send_log("INFO", "Device started successfully.")
send_log("ERROR", "Failed to connect to sensor X.", {"sensor_id": "X", "error_code": 101})
5. Exposed Management-Schnittstellen und Standard-Zugangsdaten
Dockerfile
# Beispiel: Absicherung einer Management-Schnittstelle mittels Docker und Firewall
# Angenommen, das Management-Interface des Embedded-Devices läuft in einem Container
# Dockerfile des Management-Interfaces (konzeptuell)
FROM alpine/git as builder
# ... Build steps for web interface ...
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
# Nur HTTPS aktivieren, HTTP auf HTTPS umleiten
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 443
# nginx.conf (Auszug, auf HTTPS und strenge Header achten)
# server {
# listen 80;
# return 301 https://$host$request_uri;
# }
# server {
# listen 443 ssl;
# ssl_certificate /etc/nginx/certs/server.crt;
# ssl_certificate_key /etc/nginx/certs/server.key;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_ciphers 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256';
# # ... weitere Security-Header und Konfiguration ...
# }
# Host-System Firewall-Regel (Linux, UFW)
# Nur bestimmten IP-Adressen den Zugriff auf Port 443 erlauben
ufw deny in on eth0 to any port 443
ufw allow in on eth0 to any port 443 from 192.168.1.100 # Erlaube nur der Management-IP
ufw enable # Firewall aktivieren