🎓 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¶
- Ăśberblick
- Onboarding Security Training
- OWASP Top 10 2021 — Developer Guide
- Secure Coding Guidelines
- Mobile Security (OWASP MASVS)
- Firebase & Cloud Security
- Incident Response Training
- Security Tools & Resources
- Quarterly Security Awareness
- 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?
- Security Policies kennenlernen
- SECURITY.md durchlesen (20 Sektionen)
- Responsible Disclosure Policy verstehen
-
Incident Response Workflow (6 Stufen)
-
Compliance-Anforderungen
- GDPR (DSGVO) Basics fĂĽr Entwickler
- OWASP Top 10 2021 Ăśberblick
- 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:
-
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 -
Security Rules testen (20 Min)
- Firestore Rules im Emulator laden
- Versuchen, ohne Auth auf Daten zuzugreifen (sollte fehlschlagen)
-
Versuchen, Cross-Tenant-Zugriff (sollte fehlschlagen)
-
SecureLogger in Action (10 Min)
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