Zum Inhalt

🎓 Security Training & Awareness — easySale Developer Education

Dokument-Typ: Security Training Framework & Guidelines
Erstellt: 7. April 2026
Letztes Update: 7. April 2026
Zielgruppe: Entwickler, DevOps, Product Manager, QA
Verantwortlich: Security Team (security@easysale.de)


Inhaltsverzeichnis

  1. Ăśberblick
  2. Onboarding Security Training
  3. OWASP Top 10 2021 — Developer Guide
  4. Secure Coding Guidelines
  5. Mobile Security (OWASP MASVS)
  6. Firebase & Cloud Security
  7. Incident Response Training
  8. Security Tools & Resources
  9. Quarterly Security Awareness
  10. Compliance & Zertifizierungen

1. Ăśberblick

Warum Security Training?

Security ist Teamarbeit — jede Zeile Code, jede Konfiguration, jedes Deployment kann potenzielle Sicherheitslücken einführen. Dieses Dokument dient als:

  • 📚 Lern-Ressource fĂĽr neue und bestehende Team-Mitglieder
  • 🛡️ Nachschlagewerk fĂĽr sichere Entwicklungspraktiken
  • âś… Checkliste fĂĽr Code-Reviews und Security-Audits
  • 🎯 Awareness-Programm fĂĽr kontinuierliche Security-Kultur

Training-Struktur

Phase Zeitpunkt Dauer Format
Onboarding Erste Woche 4 Stunden Interaktiv + Hands-on
OWASP Deep-Dive Erste 2 Wochen 8 Stunden Self-paced + Workshop
Quarterly Reviews Alle 3 Monate 1 Stunde Team-Meeting
Ad-hoc Training Bei neuen Findings 30-60 Min Post-Incident Review

Lernziele

Nach Abschluss des Security Trainings sollten alle Entwickler:

  • âś… OWASP Top 10 2021 verstehen und vermeiden können
  • âś… Sichere Authentifizierung & Autorisierung implementieren
  • âś… Input-Validierung & Output-Encoding korrekt anwenden
  • âś… Sensible Daten schĂĽtzen (Encryption at Rest & in Transit)
  • âś… Security-Tools (Dependabot, SecureLogger, Firebase Rules) nutzen
  • âś… Security Incidents erkennen und korrekt melden

2. Onboarding Security Training

Tag 1: Security Fundamentals (2 Stunden)

đź“– Theoretischer Teil (60 Min)

Themen: 1. easySale Security Architecture Overview - Single-Tenant-Architektur (Firebase-Projekte pro Kunde) - Defense-in-Depth Layers (8 Schichten) - Threat Model: Wer sind unsere Angreifer?

  1. Security Policies kennenlernen
  2. SECURITY.md durchlesen (20 Sektionen)
  3. Responsible Disclosure Policy verstehen
  4. Incident Response Workflow (6 Stufen)

  5. Compliance-Anforderungen

  6. GDPR (DSGVO) Basics fĂĽr Entwickler
  7. OWASP Top 10 2021 Ăśberblick
  8. OWASP MASVS (Mobile Security)

📚 Pflichtlektüre: - SECURITY.md — Vollständig lesen - OWASP Top 10 2021 Summary - owasp-analyse.md — Abschnitt "Positive Findings"

🛠️ Praktischer Teil (60 Min)

Hands-on Ăśbungen:

  1. Setup Security Tools (30 Min)

    # 1. Git Secrets installieren (verhindert Secrets im Commit)
    brew install git-secrets
    cd /path/to/easySale
    git secrets --install
    git secrets --register-aws
    
    # 2. Pre-commit Hooks aktivieren
    # (verhindert sensible Daten in Commits)
    
    # 3. Firebase CLI mit Security Rules Emulator
    npm install -g firebase-tools
    firebase init emulators
    

  2. Security Rules testen (20 Min)

  3. Firestore Rules im Emulator laden
  4. Versuchen, ohne Auth auf Daten zuzugreifen (sollte fehlschlagen)
  5. Versuchen, Cross-Tenant-Zugriff (sollte fehlschlagen)

  6. SecureLogger in Action (10 Min)

    // ❌ FALSCH: Sensible Daten loggen
    debugPrint('User logged in: ${user.email} with token ${token}');
    
    // âś… RICHTIG: SecureLogger nutzen
    SecureLogger.info('User logged in successfully');
    SecureLogger.debug('Auth token refreshed', sanitize: true);
    


Tag 2-5: OWASP Practical Workshop (2 Stunden)

Format: Pair Programming mit erfahrenem Entwickler

Aufgaben: 1. Code-Review einer Pull Request mit Security-Fokus 2. Implementierung einer Feature unter Security-Gesichtspunkten 3. Firestore Security Rules fĂĽr neue Collection schreiben 4. Input-Validierung fĂĽr ein neues Formular implementieren

Checkliste für Pair Programming: - [ ] Wurden alle Inputs validiert? - [ ] Sind sensible Daten verschlüsselt (FlutterSecureStorage)? - [ ] Gibt es Null-Checks bei currentUser? - [ ] Werden Firestore Security Rules durchgesetzt? - [ ] Sind Passwörter/Tokens aus Logs entfernt? - [ ] Wurde Rate Limiting berücksichtigt?


3. OWASP Top 10 2021 — Developer Guide

FĂĽr jede OWASP-Kategorie: Was ist es? Wie verhindere ich es in easySale?

A01:2021 — Broken Access Control

Was ist das?
Nutzer können auf Ressourcen zugreifen, für die sie keine Berechtigung haben (z.B. Cross-Tenant-Zugriff, Privilege Escalation).

Wie verhindere ich es?

âś… Firestore Security Rules verwenden (Server-seitig!)

// ❌ FALSCH: Nur Client-seitige Filterung
const data = await firestore.collection('customers')
  .where('customerId', '==', myCustomerId).get();

// âś… RICHTIG: Firestore Rules erzwingen Server-seitig
// In firestore.rules:
match /customers/{customerId} {
  allow read: if hasCustomerAccess(customerId);
  allow write: if false; // Nur via Admin SDK
}

âś… Cloud Functions: Custom Claims validieren

// Cloud Function
exports.getCustomerData = functions.https.onCall(async (data, context) => {
  if (!context.auth) {
    throw new functions.https.HttpsError('unauthenticated', 'User not signed in');
  }

  const customerId = context.auth.token.customerId;
  if (!customerId) {
    throw new functions.https.HttpsError('permission-denied', 'No customer access');
  }

  // Jetzt sicher customerId verwenden
});

âś… Flutter: Defensive Null-Checks

// ❌ FALSCH: Ohne Null-Check
final userId = FirebaseAuth.instance.currentUser!.uid; // Crash!

// âś… RICHTIG: Mit Null-Check
final user = FirebaseAuth.instance.currentUser;
if (user == null) {
  throw Exception('User not authenticated');
}
final userId = user.uid;

Real-World easySale Beispiele: - CRIT-1: Ungeschützte Firestore Queries — Behoben durch hasCustomerAccess() in Rules - CRIT-4: currentUser ohne Null-Check — Behoben durch defensive Programmierung


A02:2021 — Cryptographic Failures

Was ist das?
Sensible Daten werden unverschlüsselt gespeichert oder übertragen (Passwörter, Tokens, PII).

Wie verhindere ich es?

âś… FlutterSecureStorage fĂĽr alle Secrets

// ❌ FALSCH: SharedPreferences für Passwörter
await prefs.setString('password', password); // Plaintext!

// âś… RICHTIG: FlutterSecureStorage
final storage = FlutterSecureStorage();
await storage.write(key: 'saved_password', value: password);

âś… Hive mit AES-256 VerschlĂĽsselung

// ❌ FALSCH: Hive ohne Verschlüsselung
await Hive.openBox('userData');

// âś… RICHTIG: Hive mit HiveAesCipher
final encryptionKey = await _getOrCreateEncryptionKey();
final encryptedBox = await Hive.openBox(
  'userData',
  encryptionCipher: HiveAesCipher(encryptionKey),
);

âś… TLS fĂĽr alle Netzwerk-Verbindungen

// ❌ FALSCH: HTTP erlauben
NetworkSecurityConfig.allowCleartext = true;

// âś… RICHTIG: Nur HTTPS
// In android/app/src/main/res/xml/network_security_config.xml:
<base-config cleartextTrafficPermitted="false" />

Real-World easySale Beispiele: - CRIT-2: Passwort in SharedPreferences — Migriert zu FlutterSecureStorage - HIGH-6: Unverschlüsselte App State — Hive mit AES-256 - MED-5: Unverschlüsselte lokale Caches — HiveAesCipher implementiert


A03:2021 — Injection

Was ist das?
Unvalidierte User-Inputs werden direkt in Queries, Commands oder Code ausgefĂĽhrt (SQL Injection, XSS, Command Injection).

Wie verhindere ich es?

âś… Input-Validierung fĂĽr alle User-Inputs

// ❌ FALSCH: Keine Validierung
final email = emailController.text;
await createUser(email);

// âś… RICHTIG: Regex-Validierung
final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
if (!emailRegex.hasMatch(emailController.text)) {
  throw ValidationException('Invalid email format');
}

âś… Cloud Functions: JSON-Parsing mit Validierung

// ❌ FALSCH: Direktes JSON.parse ohne Validierung
const data = JSON.parse(request.body);

// âś… RICHTIG: safeJsonParse mit Fehlerbehandlung
function safeJsonParse(jsonString, context = 'data') {
  if (!jsonString || typeof jsonString !== 'string') {
    throw new HttpsError('invalid-argument', `${context} must be a string`);
  }
  const parsed = JSON.parse(jsonString);
  if (!parsed || typeof parsed !== 'object') {
    throw new HttpsError('invalid-argument', `${context} must be valid JSON`);
  }
  return parsed;
}

âś… XSS-Schutz: Content Security Policy

<!-- In firebase.json hosting headers: -->
"headers": [{
  "key": "Content-Security-Policy",
  "value": "default-src 'self'; script-src 'self' https://apis.google.com"
}]

Real-World easySale Beispiele: - CRIT-3: Fehlende Input Sanitization — Vollständige Validierung implementiert - MED-2: XSS-Risiko bei Web-Ansichten — CSP aktiviert - MED-10: Unvalidierte Deep Links — Allowlist-Validierung


A04:2021 — Insecure Design

Was ist das?
Architektur- oder Design-Fehler, die später nicht durch Code-Fixes behoben werden können.

Wie verhindere ich es?

âś… Error Boundaries implementieren

// âś… RICHTIG: MaterialApp mit ErrorWidget
MaterialApp(
  builder: (context, widget) {
    ErrorWidget.builder = (FlutterErrorDetails errorDetails) {
      return ErrorScreen(errorDetails: errorDetails);
    };
    return widget!;
  },
);

âś… Jailbreak/Root Detection

// âś… Bei App-Start prĂĽfen
final isSafe = await FlutterJailbreakDetection.jailbroken;
if (isSafe) {
  // App blockieren oder Warnung anzeigen
  showSecurityWarning();
}

âś… Rate Limiting fĂĽr kritische Aktionen

// âś… Login Rate Limiting
if (!RateLimiterService.canAttemptLogin(email)) {
  throw Exception('Too many login attempts. Please wait.');
}
await RateLimiterService.recordLoginAttempt(email);

Real-World easySale Beispiele: - MED-1: Fehlende Error Boundary — ErrorWidget implementiert - MED-6: Fehlende Jailbreak/Root Detection — flutter_jailbreak_detection - HIGH-1: Fehlende Rate Limiting — RateLimiterService in shared-Package


A05:2021 — Security Misconfiguration

Was ist das?
Default-Konfigurationen, fehlende Security Headers, Debug-Modus in Production.

Wie verhindere ich es?

âś… Debug-Modus in Production deaktivieren

// âś… RICHTIG: kReleaseMode-Checks
import 'package:flutter/foundation.dart';

if (kDebugMode) {
  print('Debug log'); // Nur in Debug
}

if (kReleaseMode) {
  // Production-spezifischer Code
}

âś… Security Headers konfigurieren

// In firebase.json:
"headers": [
  { "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains" },
  { "key": "X-Content-Type-Options", "value": "nosniff" },
  { "key": "X-Frame-Options", "value": "DENY" },
  { "key": "Content-Security-Policy", "value": "default-src 'self'" }
]

âś… Permissions-Minimierung

<!-- AndroidManifest.xml: Nur notwendige Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Keine unnötigen Permissions wie CAMERA, LOCATION etc. -->

Real-World easySale Beispiele: - MED-9: Debug-Modus in Production — kReleaseMode-Guards - HIGH-11: Missing Security Headers — Vollständige Header-Config - LOW-5: Fehlende CSP — Strict CSP implementiert


A06:2021 — Vulnerable and Outdated Components

Was ist das?
Verwendung veralteter npm-Pakete, Flutter-Dependencies mit bekannten Schwachstellen.

Wie verhindere ich es?

âś… Dependabot aktivieren (bereits aktiv)

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/core/functions"
    schedule:
      interval: "daily"

✅ Regelmäßig Dependencies aktualisieren

# Flutter Apps
cd apps/erp_system
flutter pub upgrade
flutter pub outdated

# Cloud Functions
cd core/functions
npm audit
npm audit fix

âś… CI/CD: Automatische Security-Scans

# In .github/workflows/security.yml
- name: Run npm audit
  run: npm audit --audit-level=high
  working-directory: core/functions

Real-World easySale Beispiele: - LOW-2: Veraltete Dependencies — Vollständig aktualisiert (35/37 Packages) - Dependabot: Automatische PRs bei neuen Sicherheitsupdates


A07:2021 — Identification and Authentication Failures

Was ist das?
Schwache Authentifizierung, keine Session-Timeouts, fehlerhafte Passwort-Policies.

Wie verhindere ich es?

âś… Starke Passwort-Policy erzwingen

// âś… RICHTIG: Passwort-Validierung
bool isStrongPassword(String password) {
  if (password.length < 8) return false;
  if (!password.contains(RegExp(r'[A-Z]'))) return false;
  if (!password.contains(RegExp(r'[a-z]'))) return false;
  if (!password.contains(RegExp(r'[0-9]'))) return false;
  if (!password.contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]'))) return false;
  return true;
}

âś… Session-Timeout implementieren

// ✅ RICHTIG: Automatischer Logout nach Inaktivität
class SessionManager {
  static const _sessionTimeout = Duration(hours: 12);

  void startPeriodicTokenRefresh() {
    Timer.periodic(Duration(minutes: 4), (_) async {
      await validateAndRefreshSession();
    });
  }

  Future<void> validateAndRefreshSession() async {
    final user = FirebaseAuth.instance.currentUser;
    if (user == null) return;

    final metadata = user.metadata;
    final lastSignIn = metadata.lastSignInTime;
    if (lastSignIn != null && 
        DateTime.now().difference(lastSignIn) > _sessionTimeout) {
      await FirebaseAuth.instance.signOut();
    }
  }
}

âś… Biometrische Authentifizierung

// âś… RICHTIG: local_auth Package nutzen
final authenticated = await authService.authenticateWithBiometrics(
  localizedReason: 'Bitte authentifizieren Sie sich',
);
if (!authenticated) {
  throw AuthException('Biometric authentication failed');
}

Real-World easySale Beispiele: - HIGH-4: Session Timeout fehlt — Automatischer Token-Refresh implementiert - HIGH-5: Fehlende Biometric Auth — local_auth integriert - HIGH-9: Weak Password Policy — Min. 8 Zeichen + Komplexität


A08:2021 — Software and Data Integrity Failures

Was ist das?
Unvalidierte Updates, fehlende Integritätsprüfungen, unsichere Deserialisierung.

Wie verhindere ich es?

âś… Request Signing (HMAC)

// âś… RICHTIG: Cloud Function Requests signieren
final signedData = await _requestSigning.signCloudFunctionPayload(
  functionName: 'createOrder',
  data: orderData,
);

// Server validiert Signature

âś… File Downloads validieren

// ❌ FALSCH: Beliebige URLs akzeptieren
await downloadFile(url);

// âś… RICHTIG: Nur Firebase Storage URLs
if (!FirebaseStorageUrlValidator.isValid(url)) {
  throw SecurityException('Invalid download URL');
}

âś… Rollback-Mechanismen

// âś… RICHTIG: Optimistic Updates mit Rollback
try {
  await updateData(newValue);
} catch (e) {
  await rollbackToLastKnownGood();
  rethrow;
}

Real-World easySale Beispiele: - HIGH-7: Fehlende Request Signing — HMAC-SHA256 implementiert - HIGH-3: Unvalidierte File Downloads — URL-Validierung - MED-3: Unzureichende Rollback-Mechanismen — Implementiert


A09:2021 — Security Logging and Monitoring Failures

Was ist das?
Sensible Daten in Logs, fehlende Audit-Trails, keine Monitoring-Alerts.

Wie verhindere ich es?

âś… SecureLogger verwenden

// ❌ FALSCH: Sensible Daten loggen
print('User: ${user.email}, Token: ${token}');

// âś… RICHTIG: SecureLogger mit Sanitization
SecureLogger.info('User authenticated successfully');
SecureLogger.debug('Token refreshed', sanitize: true);

// SecureLogger maskiert automatisch:
// - Passwörter, Tokens, API-Keys
// - E-Mail-Adressen (teilweise)
// - Telefonnummern, Kreditkarten

âś… Strukturiertes Logging

// âś… RICHTIG: Strukturierte Logs fĂĽr Monitoring
SecureLogger.event('order_created', {
  'orderId': orderId,
  'customerId': customerId,
  'amount': amount,
  'timestamp': DateTime.now().toIso8601String(),
});

âś… Monitoring-Alerts konfigurieren - Firebase Crashlytics fĂĽr Crash-Reports - Sentry fĂĽr Error Tracking (optional) - Cloud Monitoring fĂĽr Cloud Functions Performance

Real-World easySale Beispiele: - HIGH-2: Token in Debug-Logs — SecureLogger implementiert - SecureLogger in shared-Package für beide Apps verfügbar


A10:2021 — Server-Side Request Forgery (SSRF)

Was ist das?
Cloud Functions rufen unvalidierte externe URLs auf, die von Angreifern kontrolliert werden.

Wie verhindere ich es?

âś… URL-Allowlist verwenden

// âś… RICHTIG: Nur erlaubte Domains
const ALLOWED_DOMAINS = [
  'api.stripe.com',
  'api.sendgrid.com',
  'storage.googleapis.com'
];

function validateExternalUrl(url) {
  const urlObj = new URL(url);
  if (!ALLOWED_DOMAINS.includes(urlObj.hostname)) {
    throw new HttpsError('permission-denied', 'URL not allowed');
  }
  return url;
}

âś… Keine User-Inputs direkt in URLs

// ❌ FALSCH: User-Input direkt verwenden
const url = `https://api.example.com/?callback=${req.body.url}`;

// âś… RICHTIG: Input validieren + escapen
const callback = validateAndEscapeUrl(req.body.url);

Real-World easySale Beispiele: - Alle Cloud Functions validieren externe URLs gegen Allowlist - Kein user-kontrollierter SSRF-Vektor identifiziert


4. Secure Coding Guidelines

Flutter/Dart Best Practices

1. Null-Safety konsequent nutzen

// âś… RICHTIG: Null-aware Operators
final email = user?.email ?? 'unknown@example.com';
final data = response.data?.map((e) => Model.fromJson(e)).toList() ?? [];

2. Immutability bevorzugen

// âś… RICHTIG: Immutable Data Classes
@immutable
class Customer {
  final String id;
  final String name;

  const Customer({required this.id, required this.name});

  Customer copyWith({String? id, String? name}) {
    return Customer(id: id ?? this.id, name: name ?? this.name);
  }
}

3. Stream Subscriptions canceln

// âś… RICHTIG: Subscription cleanup
class MyBloc extends Bloc<MyEvent, MyState> {
  StreamSubscription? _subscription;

  MyBloc() {
    _subscription = someStream.listen((data) { /*...*/ });
  }

  @override
  Future<void> close() async {
    await _subscription?.cancel();
    return super.close();
  }
}

Cloud Functions (Node.js) Best Practices

1. Immer Auth-Context validieren

exports.myFunction = functions.https.onCall(async (data, context) => {
  // âś… RICHTIG: Auth-Validierung
  if (!context.auth) {
    throw new functions.https.HttpsError('unauthenticated', 'User not signed in');
  }

  const customerId = context.auth.token.customerId;
  if (!customerId) {
    throw new functions.https.HttpsError('permission-denied', 'No customer access');
  }

  // Jetzt sicher arbeiten
});

2. Input-Validierung mit Schema

// âś… RICHTIG: Joi-Schema fĂĽr Validierung
const Joi = require('joi');

const orderSchema = Joi.object({
  customerId: Joi.string().required(),
  items: Joi.array().items(Joi.object({
    productId: Joi.string().required(),
    quantity: Joi.number().integer().min(1).max(999).required()
  })).min(1).required()
});

const { error, value } = orderSchema.validate(data);
if (error) {
  throw new functions.https.HttpsError('invalid-argument', error.message);
}

3. Environment Variables fĂĽr Secrets

// âś… RICHTIG: Secrets aus Environment
const apiKey = functions.config().stripe.key; // Nicht hardcoded!

5. Mobile Security (OWASP MASVS)

MASVS-STORAGE — Sichere Datenspeicherung

Checkliste fĂĽr lokale Datenspeicherung

  • [ ] Keine sensiblen Daten in SharedPreferences/UserDefaults
  • [ ] FlutterSecureStorage fĂĽr Passwörter, Tokens, Keys
  • [ ] Hive mit HiveAesCipher fĂĽr strukturierte Daten
  • [ ] Encryption-Key in Keychain (iOS) / Keystore (Android)
  • [ ] Keine Logs mit PII in Release-Builds

Code-Beispiel: Richtige Datenspeicherung

class SecureStorageService {
  final _secureStorage = FlutterSecureStorage();
  final _encryptionKeyName = 'hive_encryption_key';

  Future<Uint8List> _getOrCreateEncryptionKey() async {
    String? keyString = await _secureStorage.read(key: _encryptionKeyName);

    if (keyString == null) {
      final key = Hive.generateSecureKey();
      await _secureStorage.write(
        key: _encryptionKeyName,
        value: base64Url.encode(key),
      );
      return key;
    }

    return base64Url.decode(keyString);
  }

  Future<Box> openSecureBox(String name) async {
    final key = await _getOrCreateEncryptionKey();
    return await Hive.openBox(
      name,
      encryptionCipher: HiveAesCipher(key),
    );
  }
}

MASVS-CRYPTO — Kryptographie

Checkliste Kryptographie

  • [ ] AES-256 fĂĽr symmetrische VerschlĂĽsselung
  • [ ] RSA-2048+ / ECDSA fĂĽr asymmetrische Kryptographie
  • [ ] SHA-256 fĂĽr Hashing (kein MD5, SHA-1)
  • [ ] SecureRandom fĂĽr Zufallszahlen
  • [ ] Keine selbst-implementierten Crypto-Algorithmen

Code-Beispiel: Sichere Zufallszahlen

// ❌ FALSCH: Unsicherer Random
final random = Random();
final sessionId = random.nextInt(1000000);

// âś… RICHTIG: Kryptographisch sicherer Random
import 'dart:math' show Random;
import 'package:crypto/crypto.dart';

final secureRandom = Random.secure();
final sessionId = secureRandom.nextInt(1000000);

// Oder mit crypto-Package fĂĽr Keys:
final bytes = List<int>.generate(32, (_) => secureRandom.nextInt(256));
final key = sha256.convert(bytes).toString();

MASVS-AUTH — Authentifizierung

Checkliste Authentifizierung

  • [ ] Biometrie als zusätzlicher Faktor (nicht alleinig)
  • [ ] Session-Timeout nach Inaktivität
  • [ ] Token-Refresh vor Ablauf
  • [ ] Logout invalidiert Session server-seitig
  • [ ] Keine Passwörter im Auto-Fill ohne Biometrie

Code-Beispiel: Biometric Auth

Future<bool> authenticateWithBiometrics() async {
  final localAuth = LocalAuthentication();

  // 1. Prüfen ob Device biometrisch fähig ist
  final canCheck = await localAuth.canCheckBiometrics;
  if (!canCheck) return false;

  // 2. VerfĂĽgbare Biometrie-Typen abrufen
  final availableBiometrics = await localAuth.getAvailableBiometrics();
  if (availableBiometrics.isEmpty) return false;

  // 3. Authentifizierung durchfĂĽhren
  try {
    final authenticated = await localAuth.authenticate(
      localizedReason: 'Bitte authentifizieren Sie sich fĂĽr den Zugang',
      options: const AuthenticationOptions(
        stickyAuth: true,
        biometricOnly: true,
      ),
    );
    return authenticated;
  } catch (e) {
    SecureLogger.error('Biometric authentication failed', error: e);
    return false;
  }
}

MASVS-NETWORK — Netzwerksicherheit

Checkliste Netzwerk

  • [ ] TLS 1.2+ fĂĽr alle Verbindungen
  • [ ] Certificate Pinning fĂĽr kritische Endpunkte
  • [ ] Kein HTTP in Production (nur HTTPS)
  • [ ] Timeout fĂĽr alle Network-Requests
  • [ ] Retry-Logic mit Exponential Backoff

Code-Beispiel: SSL Pinning

class SSLPinningConfig {
  static Dio createSecureDio() {
    final dio = Dio();

    // SSL Pinning fĂĽr Firebase
    (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = 
      (client) {
        client.badCertificateCallback = (cert, host, port) {
          // Nur Firebase-Domains erlauben
          if (host.endsWith('.googleapis.com') || 
              host.endsWith('.firebaseio.com')) {
            // Certificate Fingerprint validieren
            final certFingerprint = sha256.convert(cert.der).toString();
            return _validFirebaseCertificates.contains(certFingerprint);
          }
          return false;
        };
        return client;
      };

    return dio;
  }
}

MASVS-RESILIENCE — Anti-Tampering

Checkliste Resilience

  • [ ] Jailbreak/Root Detection
  • [ ] Code Obfuscation (ProGuard/R8)
  • [ ] Debug-Erkennung in Release-Builds
  • [ ] Integrity Checks fĂĽr kritische Daten
  • [ ] App-Signatur-Validierung

Code-Beispiel: Jailbreak Detection

Future<void> checkDeviceSecurity() async {
  final isJailbroken = await FlutterJailbreakDetection.jailbroken;
  final isDeveloperMode = await FlutterJailbreakDetection.developerMode;

  if (isJailbroken || isDeveloperMode) {
    // Warnung anzeigen oder App blockieren
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => AlertDialog(
        title: Text('Sicherheitswarnung'),
        content: Text('Diese App kann auf gerooteten/gejailbreakten Geräten '
                     'nicht ausgefĂĽhrt werden.'),
        actions: [
          TextButton(
            onPressed: () => exit(0),
            child: Text('App beenden'),
          ),
        ],
      ),
    );
  }
}

6. Firebase & Cloud Security

Firestore Security Rules — Best Practices

1. Deny-by-Default Prinzip

// ✅ RICHTIG: Alle Zugriffe standardmäßig verweigern
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Explizite Regeln fĂĽr jede Collection
    match /customers/{customerId} {
      allow read: if hasCustomerAccess(customerId);
    }

    // Default: Alles verbieten
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

2. Helper-Funktionen nutzen

// âś… RICHTIG: Wiederverwendbare Funktionen
function isSignedIn() {
  return request.auth != null;
}

function hasCustomerAccess(customerId) {
  return isSignedIn() && 
    request.auth.token.customerId == customerId;
}

function isAdmin() {
  return isSignedIn() && 
    request.auth.token.role == 'admin';
}

3. Rate Limiting in Rules

// âś… RICHTIG: Timestamp-basiertes Rate Limiting
match /orders/{orderId} {
  allow create: if isSignedIn() &&
    !exists(/databases/$(database)/documents/orders/$(request.auth.uid + '_' + request.time.toMillis())) &&
    request.time > resource.data.lastOrderTime + duration.value(1, 'm');
}

Cloud Functions Security

1. Secrets Management

# âś… RICHTIG: Secrets mit Firebase Config
firebase functions:config:set stripe.key="sk_live_xxx"
firebase functions:config:set sendgrid.key="SG.xxx"

# In Function abrufen:
const stripeKey = functions.config().stripe.key;

2. CORS richtig konfigurieren

// âś… RICHTIG: Strict CORS fĂĽr Production
const corsOptions = {
  origin: process.env.NODE_ENV === 'production' 
    ? ['https://shop.easysale.de', 'https://erp.easysale.de']
    : true, // Dev: Allow all
  credentials: true,
};

exports.myFunction = functions.https.onRequest((req, res) => {
  cors(corsOptions)(req, res, () => {
    // Function logic
  });
});

3. Timeout & Memory konfigurieren

// âś… RICHTIG: Resource Limits setzen
exports.heavyFunction = functions
  .runWith({
    timeoutSeconds: 300,
    memory: '1GB',
    maxInstances: 10,
  })
  .https.onCall(async (data, context) => {
    // Heavy processing
  });

7. Incident Response Training

Incident erkennen

Wann sollte ich einen Security Incident melden?

🚨 SOFORT MELDEN (P0/P1): - Unautorisierten Zugriff auf Kundendaten entdeckt - Verdacht auf Datenbank-Leak - Produktionssystem kompromittiert - Credentials in Git committed (auch versehentlich) - Aktiver Exploit-Versuch in Logs erkennbar

⚠️ ZEITNAH MELDEN (P2/P3): - Potenzielle Schwachstelle im Code entdeckt - Verdächtige Aktivitäten in Logs - Dependency mit bekannter Schwachstelle - Security-Tool-Finding (npm audit, Dependabot)

Melde-Workflow

1. ENTDECKUNG
   ↓
2. STOPP: Nicht selbst fixen! (auĂźer Credentials-Leak)
   ↓
3. MELDEN: security@easysale.de mit [INCIDENT] im Betreff
   ↓
4. INFORMATIONEN SAMMELN:
   - Was wurde entdeckt?
   - Wann wurde es entdeckt?
   - Wo (System, File, Line)?
   - Wie kritisch (eigene Einschätzung)?
   ↓
5. WARTEN auf Security Team Response (< 1h bei P0)
   ↓
6. KOORDINIERT HANDELN (keine Solo-Aktionen)

Incident Response Checkliste

Wenn du ein Security Incident meldest, bereite folgende Informationen vor:

  • [ ] Was: Kurze Beschreibung der Schwachstelle/Vorfall
  • [ ] Wo: System (ERP/Shop), File, Line Number, Cloud Function Name
  • [ ] Wann: Zeitpunkt der Entdeckung
  • [ ] Wer: Betroffene Nutzer/Kunden (falls bekannt)
  • [ ] Impact: Potenzielle Auswirkungen
  • [ ] Reproduktion: Minimaler Reproduktionsweg
  • [ ] Logs: Relevante Log-Einträge (ohne sensible Daten!)
  • [ ] Screenshots: Falls visuell relevant

Muster-E-Mail:

Betreff: [INCIDENT P1] Unautorisian Firestore Access

Hallo Security Team,

ich habe eine potenzielle Schwachstelle entdeckt:

WAS: Firestore Query ohne Server-seitige Validierung
WO: apps/shop_system/lib/services/order_service.dart, Zeile 123
WANN: Heute, 10:30 Uhr während Code-Review
WER: Potentiell alle Shop-Kunden
IMPACT: Cross-Tenant-Zugriff auf Bestellungen möglich

REPRODUKTION:
1. Als Nutzer A einloggen
2. Firestore Query manuell senden mit customerId von Nutzer B
3. Daten von Nutzer B werden zurĂĽckgegeben

VORGESCHLAGENER FIX:
Firestore Security Rule hinzufĂĽgen: allow read: if hasCustomerAccess(customerId)

Beste GrĂĽĂźe,
[Dein Name]


8. Security Tools & Resources

Entwickler-Tools

Tool Zweck Installation Verwendung
git-secrets Verhindert Secrets in Commits brew install git-secrets Automatisch bei git commit
Dependabot Dependency Updates GitHub-seitig aktiv PRs automatisch erstellt
firebase emulators Lokales Testing npm i -g firebase-tools firebase emulators:start
SecureLogger Sichere Logs In shared-Package SecureLogger.info()
FlutterSecureStorage VerschlĂĽsselte Speicherung flutter pub add storage.write()

Online-Ressourcen

OWASP: - OWASP Top 10 2021 - OWASP Mobile Security Testing Guide - OWASP Cheat Sheet Series

Firebase Security: - Firebase Security Rules Guide - Cloud Functions Security Best Practices

Flutter Security: - Flutter Security Best Practices - Dart Security Guidelines

Training & Zertifizierungen: - PortSwigger Web Security Academy — Kostenlos - OWASP WebGoat — Hands-on Learning - Hack The Box — Pentesting Practice


9. Quarterly Security Awareness

Q1 2026 — OWASP Top 10 Refresh (abgeschlossen)

Thema: OWASP Top 10 2021 Code-Audit Ergebnisse
Datum: Februar 2026
Format: Team-Workshop (2 Stunden)

Inhalte: - Präsentation aller 37 Findings - Deep-Dive in die 5 CRITICAL Findings - Lessons Learned & Best Practices - Code-Beispiele: Vorher/Nachher

Ergebnis: 35 von 37 Findings behoben (97,3%)


Q2 2026 — Penetration Test Vorbereitung (geplant Mai)

Thema: Vorbereitung auf externen Pentest
Datum: Mai 2026 (vor Pentest-Start)
Format: Workshop (1 Stunde)

Inhalte: - Was ist ein Penetration Test? - Erwartete Findings vs. Code-Audit Findings - Rules of Engagement verstehen - Was passiert bei CRITICAL Findings? - Wie unterstĂĽtzen wir die Pentester?


Q3 2026 — Secure Mobile Development (geplant)

Thema: OWASP MASVS Deep-Dive
Datum: August 2026
Format: Hands-on Workshop (2 Stunden)

Geplante Inhalte: - Mobile-spezifische Angriffe (MITM, Jailbreak, Reverse Engineering) - Praktische Ăśbung: App dekompilieren und analysieren - Certificate Pinning implementieren (Live-Coding) - Secure Storage Best Practices


Q4 2026 — Annual Security Review (geplant)

Thema: JahresrĂĽckblick & 2027 Planning
Datum: November 2026
Format: Retrospektive (1,5 Stunden)

Geplante Inhalte: - Security Incidents 2026 Review - Pentest-Ergebnisse analysieren - Neue OWASP/MASVS-Versionen prĂĽfen - Security Roadmap 2027 - Team-Feedback zu Security-Prozessen


10. Compliance & Zertifizierungen

Empfohlene Zertifizierungen fĂĽr Security Champions

Für Entwickler: - OWASP Top 10 Awareness (kostenlos, online) - Certified Secure Software Lifecycle Professional (CSSLP) — Optional - Google Cloud Certified — Professional Cloud Security Engineer — Optional

Für Security Team: - Offensive Security Certified Professional (OSCP) — Pentest-Fokus - Certified Ethical Hacker (CEH) — Breites Security-Wissen - GIAC Web Application Penetration Tester (GWAPT) — Web-App-Fokus

Internal Security Champion Program (geplant)

Idee: 1-2 Entwickler pro Team als Security Champions ausbilden

Verantwortlichkeiten: - Security-Awareness im Team fördern - Code-Reviews mit Security-Fokus - Erste Ansprechperson bei Security-Fragen - Security-Trainings mitgestalten

Benefits: - Dedizierte Training-Zeit (4h/Monat) - Zugang zu Security-Tools (Burp Suite Pro, etc.) - Zertifizierungs-Budget (bis 1.500 EUR/Jahr) - Sichtbarkeit & Career-Development


Zusammenfassung & Checkliste

Onboarding-Checkliste (fĂĽr neue Team-Mitglieder)

  • [ ] Tag 1: SECURITY.md gelesen
  • [ ] Tag 1: owasp-analyse.md durchgearbeitet
  • [ ] Tag 1: git-secrets installiert
  • [ ] Tag 2: OWASP Top 10 2021 Summary gelesen
  • [ ] Tag 3: Firestore Rules im Emulator getestet
  • [ ] Tag 4: SecureLogger in eigenem Code verwendet
  • [ ] Tag 5: Pair Programming mit Security-Fokus
  • [ ] Woche 2: OWASP Deep-Dive Selbststudium (8h)
  • [ ] Woche 3: Erstes Security Code-Review durchgefĂĽhrt
  • [ ] Monat 1: Security Champion Meeting teilgenommen

Tägliche Security-Praktiken

VOR jedem Commit: - [ ] Keine Secrets/Credentials im Code - [ ] SecureLogger statt print()/debugPrint() fĂĽr sensible Logs - [ ] Input-Validierung fĂĽr neue User-Inputs - [ ] Null-Checks bei currentUser/Auth

VOR jedem PR: - [ ] Security-Checkliste im PR-Template ausgefĂĽllt - [ ] Firestore Rules aktualisiert (falls neue Collections) - [ ] Dependency-Updates (flutter pub outdated / npm audit)

NACH jedem Release: - [ ] Security Smoke-Tests durchgefĂĽhrt - [ ] Monitoring-Dashboards prĂĽfen (Error-Rate, Auth-Failures) - [ ] Dependabot-PRs reviewen


Fragen? Unsicherheiten?
→ security@easysale.de
→ #security Slack-Channel
→ Security Office Hours: Jeden Donnerstag, 15:00-16:00 Uhr

Letzte Aktualisierung: 7. April 2026
Nächste Review: Juli 2026 (nach Q2 Security Awareness Session)
Maintainer: Security Team