Zum Inhalt springen

Services, Wiki-Artikel, Blog-Beiträge und Glossar-Einträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen
Anwendungssicherheit Glossar

Secure by Design

Entwicklungsphilosophie, bei der Sicherheit von Anfang an in Architektur und Code eingebettet wird - nicht als nachträglicher Patch. Secure-by-Design-Prinzipien umfassen minimale Angriffsfläche, sichere Defaults, Defense-in-Depth und fail-safe Defaults.

Secure by Design ist mehr als ein Buzzword - es ist eine Ablehnung der “Security Retrofit”-Mentalität. Wenn ein Produkt erst entwickelt, dann auf Sicherheit “geprüft” und schließlich mit Patches repariert wird, entstehen strukturelle Schwachstellen die sich nicht flicken lassen. Secure by Design dreht diese Reihenfolge um: Bedrohungsmodellierung vor der ersten Codezeile.

Die CISA Secure by Design Prinzipien (2023)

Die US-Behörde CISA hat 2023 gemeinsam mit internationalen Sicherheitsbehörden (darunter das deutsche BSI) Prinzipien für Secure by Design veröffentlicht:

Prinzip 1: Hersteller übernehmen Verantwortung für Sicherheit

  • Nicht: “Nutzer müssen sicher konfigurieren”
  • Sondern: Sichere Defaults aus der Box
  • Beispiel: Passwörter nicht standardmäßig “admin/admin”, sondern zufällig generiert oder mit Änderungszwang

Prinzip 2: Radikale Transparenz und Verantwortlichkeit

  • CVE-Veröffentlichung ohne Verzögerung
  • Klare EOL-Dates (End of Life)
  • Security-Changelogs in Release Notes

Prinzip 3: Kunden-Sicherheit als Kernziel

  • Sicherheit ist kein Premium-Feature
  • Nicht: “MFA ist verfügbar in der Enterprise-Variante”
  • Sondern: MFA ist Standard und kostenlos

Die sechs Secure-by-Design-Prinzipien

1. Minimale Angriffsfläche (Attack Surface Reduction)

Jede unnötige Funktion ist eine potenzielle Schwachstelle.

  • Nur installieren was gebraucht wird
  • Ports/Services: nur das Minimum öffnen
  • Falsch: 12 Services beim Start, Nutzer konfiguriert ab
  • Richtig: 3 Core-Services, Nutzer aktiviert optional
# Alle Ports die standardmäßig gebunden werden:
ss -tlnp  # Jede Zeile hinterfragen: Braucht man das?

2. Sichere Defaults

Aus der Box sicher, nicht “kann sicher konfiguriert werden”.

<!-- FALSCH: -->
<encryption enabled="false">  <!-- Default in config.xml -->
RICHTIG: Verschlüsselung IMMER, kein Opt-out für Daten in Ruhe

FALSCH: Admin-UI default auf 0.0.0.0 (alle Interfaces)
RICHTIG: Admin-UI default auf 127.0.0.1 (nur lokal)

3. Defense in Depth

Keine einzelne Schutzschicht ist ausreichend. Bei Schicht 1 Versagen hält Schicht 2 noch.

Beispiel Web-App:

SchichtMaßnahmeSchützt gegen
Layer 1WAFBlockt bekannte Angriffe
Layer 2Input ValidationBlockt Injection
Layer 3Prepared StatementsBlockt SQLi auch wenn Layer 2 versagt
Layer 4Minimale DB-RechteBegrenzt Schaden wenn Layer 3 versagt
Layer 5Encryption at restBegrenzt Schaden wenn Layer 4 versagt

4. Fail Safe (sicheres Verhalten bei Fehlern)

Bei Fehler: standardmäßig blockieren, nicht erlauben.

// FALSCH:
try { checkPermission(user, resource); }
catch (Exception e) {
  log.error("Permission check failed");
  return true;  // Zugang gewähren wenn Fehler!
}

// RICHTIG:
try { return checkPermission(user, resource); }
catch (Exception e) {
  log.error("Permission check failed - denying access");
  return false;  // Bei Fehler: KEIN Zugang
}

5. Least Privilege

Jede Komponente/Prozess/User erhält nur die minimalen Rechte:

  • DB-User hat nur SELECT auf nötige Tabellen
  • Container läuft nicht als root
  • API-Key hat nur read-Scope wenn write nicht nötig ist

6. Psychologische Akzeptanz (Usability)

Sichere Optionen müssen die einfachste Option sein. Wenn Sicherheit mühsam ist, umgeht der User sie. “Security Theater” (sieht sicher aus, ist es nicht) vermeiden.

Threat Modeling - Sicherheit vor dem Code

Wann: Vor der Implementierung, in der Design-Phase Wer: Entwickler + Security-Experte + Architect Output: Liste von Bedrohungen → Mitigationen → Anforderungen

STRIDE-Methode (Microsoft)

BuchstabeKategorieBeschreibung
SSpoofingAngreifer gibt sich als jemand anderes aus
TTamperingAngreifer manipuliert Daten
RRepudiationAngreifer leugnet Aktionen
IInformation DisclosureDatenleck
DDenial of ServiceSystem lahmlegen
EElevation of PrivilegeRechte erlangen

STRIDE für eine einfache REST-API

Endpunkt: POST /api/orders (Bestellung aufgeben)

KategorieBedrohungMitigation
SpoofingAngreifer bestellt als anderer UserStarke Auth (JWT + audience-Check), MFA für hohe Beträge
TamperingAngreifer ändert Bestellpreis in RequestPreise immer serverseitig berechnen, nie vom Client
Repudiation”Ich habe das nie bestellt” - keine BeweiseAudit-Log mit User-ID, Timestamp, IP, Request-Hash
Info DisclosureError-Message zeigt DB-SchemaGenerische Fehlermeldungen im Prod, Details nur in Logs
DoS10.000 Bestellungen/Sekunde → DB überlastetRate Limiting (100/min pro User), Queue für Processing
EoPAngreifer fügt admin=true in POST-Body einWhitelist-Input-Validation, DTO-Mapping ohne admin-Feld

Secure-by-Design in der Praxis: Code-Beispiele

// ===== UNSICHER: Klassische Fehler =====

// 1. SQL Injection durch String-Konkatenation
const query = `SELECT * FROM users WHERE email = '${userInput}'`;
// Payload: ' OR '1'='1 → alle User zurückgegeben

// 2. Fehlermeldung leckt Systeminfos
app.use((err, req, res, next) => {
  res.json({ error: err.stack });  // Stack Trace inkl. Dateipfade!
});

// 3. IDOR: User greift auf fremde Ressource zu
app.get('/invoice/:id', (req, res) => {
  const invoice = db.query('SELECT * FROM invoices WHERE id = ?', req.params.id);
  res.json(invoice);  // Keine Prüfung: gehört Invoice dem User?
});

// ===== SICHER: Secure-by-Design =====

// 1. Prepared Statements (SQLi-sicher)
const query = 'SELECT * FROM users WHERE email = ?';
const user = await db.query(query, [userInput]);

// 2. Fehlerbehandlung ohne Info-Leak
app.use((err, req, res, next) => {
  const errorId = crypto.randomUUID();
  logger.error({ errorId, stack: err.stack, path: req.path });
  res.status(500).json({
    error: 'An internal error occurred',
    errorId  // Zum Nachschlagen im Log, ohne Details
  });
});

// 3. Ownership-Check (IDOR-sicher)
app.get('/invoice/:id', requireAuth, async (req, res) => {
  const invoice = await db.query(
    'SELECT * FROM invoices WHERE id = ? AND user_id = ?',
    [req.params.id, req.user.id]  // IMMER user_id mit prüfen!
  );
  if (!invoice) return res.status(404).json({ error: 'Not found' });
  res.json(invoice);
});

// 4. Input Validation (Zod-Schema)
import { z } from 'zod';

const OrderSchema = z.object({
  productId: z.string().uuid(),
  quantity: z.number().int().min(1).max(100),
  // Kein 'price' oder 'admin' Feld - wird ignoriert wenn gesendet
});

app.post('/orders', requireAuth, async (req, res) => {
  const result = OrderSchema.safeParse(req.body);
  if (!result.success) {
    return res.status(400).json({ error: result.error.issues });
  }
  const { productId, quantity } = result.data;  // Nur validierte Daten!
  // Preis serverseitig aus DB holen:
  const product = await db.getProduct(productId);
  const totalPrice = product.price * quantity;
  // ...
});

Secure by Default - Checkliste für neue Projekte

Authentifizierung

  • Passwörter: bcrypt/Argon2id (kein MD5, SHA-1, unsalted!)
  • Session-Token: kryptographisch zufällig (crypto.randomUUID)
  • JWT: kurze Gültigkeitsdauer (Access: 15min, Refresh: 7 Tage)
  • MFA: optional anbieten, für Admins erzwingen
  • Passwort-Reset: zeitbegrenzte, einmalige Token

Autorisierung

  • RBAC oder ABAC: explizite Zugriffsrechte
  • Ownership-Check: gehören Ressourcen dem anfragenden User?
  • Deny-by-default: kein Zugang außer explizit erlaubt
  • Admin-Funktionen: separater Auth-Check

Input/Output

  • Input Validation: Schema-basiert (Zod, Joi, Pydantic)
  • Output Encoding: XSS-Schutz (React: automatisch; sonst escapen)
  • SQL: Prepared Statements oder ORM
  • Fehlermeldungen: generisch für User, detailliert in Logs

Konfiguration

  • Secrets: Env-Variablen (kein Hardcoding, kein Git!)
  • HTTPS: erzwingen (HSTS)
  • Security Headers: CSP, X-Frame-Options, X-Content-Type
  • CORS: nur erlaubte Origins
  • Debug-Mode: in Produktion deaktiviert

Logging & Monitoring

  • Auth-Ereignisse loggen (Login OK/Fail, Passwort-Reset)
  • Zugriffskontrolle loggen (Denied-Events)
  • Keine sensiblen Daten in Logs (Passwörter, Tokens)
  • Log-Level in Prod: INFO/WARN/ERROR (kein DEBUG)

CISA Secure by Design Pledge (2024)

CISA hat Softwarehersteller aufgefordert, innerhalb eines Jahres freiwillig folgende Ziele zu erfüllen:

  • MFA-Anteil in eigenen Produkten messbar erhöhen
  • Default-Passwörter in allen Produkten eliminieren
  • Anzahl kritischer CVEs im eigenen Produkt-Portfolio reduzieren
  • Transparenz über Schwachstellen-Offenlegungsprozess herstellen
  • CVSSv3 Scores für alle Schwachstellen veröffentlichen

Stand 2025:

  • 250+ Unternehmen haben unterzeichnet
  • Darunter: Microsoft, Google, AWS, Cisco, Palo Alto Networks
  • BSI befürwortet den Ansatz für deutsche Unternehmen

Bedeutung für Einkauf/Beschaffung:

  • Produkte von Secure-by-Design-Pledgers bevorzugen
  • Vertragsklauseln: Hersteller haftet für bekannte Schwachstellen
  • EOL-Garantien vertraglich absichern

Cookielose Analyse via Matomo (selbst gehostet, kein Tracking-Cookie). Datenschutzerklärung