Security by Design
„Security von Anfang an einbauen. Nicht am Ende draufkleben."
Sinn & Zweck
Security by Design bedeutet, Sicherheit als fundamentales Designprinzip zu behandeln – nicht als nachträgliche Ergänzung. Statt Vulnerabilities zu finden und zu fixen, werden sie von vornherein verhindert.
Der Unterschied:
Traditionell:
Requirements → Design → Code → Test → "Oh, Security?" → Fixes → Deploy
Security by Design:
Security Requirements → Secure Design → Secure Code → Security Tests → Deploy
↑ ↑ ↑ ↑
Threat Model Patterns Guidelines Automation
Grundprinzipien
1. Least Privilege
principle: "Nur die minimal nötigen Rechte"
examples:
user_rights:
bad: "Alle User haben Admin-Rechte"
good: "User haben nur Rechte für ihre Aufgaben"
service_accounts:
bad: "Lambda hat AdministratorAccess"
good: "Lambda hat nur s3:GetObject für einen Bucket"
database:
bad: "App-User hat DBA-Rechte"
good: "App-User hat SELECT/INSERT auf bestimmte Tabellen"
2. Defense in Depth
┌─────────────────────────────────────┐
│ Layer 1: Perimeter │
│ (Firewall, WAF, DDoS) │
├─────────────────────────────────────┤
│ Layer 2: Network │
│ (Segmentation, VLAN, VPN) │
├─────────────────────────────────────┤
│ Layer 3: Application │
│ (Auth, AuthZ, Input Validation) │
├─────────────────────────────────────┤
│ Layer 4: Data │
│ (Encryption, Access Control) │
└─────────────────────────────────────┘
3. Fail Secure
# SCHLECHT: Fail Open
def authorize(user, resource):
try:
return check_permission(user, resource)
except Exception:
return True # Im Zweifel erlauben? NEIN!
# GUT: Fail Secure
def authorize(user, resource):
try:
return check_permission(user, resource)
except Exception:
log_security_event("Authorization check failed")
return False # Im Zweifel verweigern
4. Separation of Duties
principle: "Keine Person/System hat alle Schlüssel"
examples:
deployment:
- Dev schreibt Code
- Reviewer approved
- CI/CD deployed (automatisch)
- Ops überwacht
secrets:
- Key Generation: Security Team
- Key Usage: Application
- Key Rotation: Automated System
database_admin:
- Schema changes: DBA
- Data access: Application
- Backups: Automated System
5. Don't Trust Input
# ALLES ist potenziell bösartig
# User Input
name = request.form.get("name") # Böse!
# API Response
data = external_api.get_data() # Böse!
# Database
record = db.get_user(id) # Möglicherweise manipuliert!
# Environment Variable
config = os.environ.get("CONFIG") # Könnte gesetzt worden sein!
# File Content
content = open("data.json").read() # Wer hat das geschrieben?
# IMMER validieren, sanitizen, escapen
6. Secure by Default
# Die sichere Option ist die Standard-Option
authentication:
default: MFA enabled
opt_out: Requires explicit disable + risk acceptance
encryption:
default: AES-256-GCM
opt_out: Not possible
passwords:
default: 14 characters minimum, complexity required
opt_out: Not possible
logging:
default: All security events logged
opt_out: Not for security-relevant events
7. Keep It Simple
principle: "Komplexität ist der Feind der Sicherheit"
complexity_reduction:
- Weniger Code = weniger Bugs
- Weniger Komponenten = weniger Angriffsfläche
- Einfache Architektur = einfacher zu sichern
anti_patterns:
- "Wir bauen unsere eigene Crypto"
- "Diese 47 Microservices sind total notwendig"
- "Das Berechtigungssystem hat nur 500 Rollen"
Security Requirements
Kategorien
security_requirements:
authentication:
- Multi-factor authentication available
- Password policy enforced
- Session management secure
authorization:
- Role-based access control
- Least privilege enforced
- Access decisions logged
data_protection:
- Encryption at rest
- Encryption in transit
- PII handling compliant
audit:
- Security events logged
- Logs tamper-proof
- Retention period defined
resilience:
- Rate limiting
- DoS protection
- Graceful degradation
Ableitung aus Compliance
gdpr_derived:
- Privacy by Design
- Data minimization
- Right to deletion
- Access logging
pci_dss_derived:
- Cardholder data encryption
- Network segmentation
- Vulnerability management
- Access control
hipaa_derived:
- PHI encryption
- Audit trails
- Access controls
- Integrity controls
Secure Design Patterns
Authentication
pattern: Token-Based Authentication (JWT)
implementation:
- Access Token: Short-lived (15 min)
- Refresh Token: Longer-lived, rotating
- Token Storage: HttpOnly, Secure Cookie (Web) / Secure Storage (Mobile)
- Token Validation: Signature + Expiry + Claims
anti_patterns:
- Session ID in URL
- Long-lived tokens without rotation
- Tokens in localStorage
Authorization
pattern: Attribute-Based Access Control (ABAC)
components:
subject: Who is requesting? (User, Role, Department)
resource: What is being accessed? (Document, API, Feature)
action: What operation? (Read, Write, Delete)
environment: Context (Time, Location, Device)
policy_example:
rule: "Allow if user.department == resource.owner_department
AND action == 'read'
AND environment.time in business_hours"
Data Protection
pattern: Encryption Architecture
at_rest:
- Database: Transparent Data Encryption (TDE)
- Files: AES-256-GCM
- Keys: HSM/KMS managed
in_transit:
- TLS 1.3 minimum
- Certificate pinning (mobile)
- mTLS for service-to-service
key_management:
- Rotation: Automated, regular
- Access: Strictly limited
- Backup: Secure, tested
Input Handling
pattern: Defense in Depth for Input
layers:
1_waf: Block known attack patterns
2_validation: Type, format, length checks
3_sanitization: Remove dangerous characters
4_parameterization: Prepared statements, encoding
5_output_encoding: Context-aware escaping
implementation:
validation:
email: regex + DNS check
id: integer, positive, within range
name: alphanumeric, max 100 chars
parameterization:
sql: Prepared statements ALWAYS
html: Context-aware encoding
shell: Avoid; if must, parameterize
Secure Architecture Patterns
Zero Trust
principle: "Never trust, always verify"
implementation:
- No implicit trust based on network location
- Every request authenticated and authorized
- Least privilege access
- Micro-segmentation
- Continuous validation
architecture:
┌─────────────────────────────────────────────────────┐
│ Identity Provider │
│ (Verify every request) │
└───────────────────────┬─────────────────────────────┘
│
┌─────────────┼─────────────┐
↓ ↓ ↓
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Service A│ │ Service B│ │ Service C│
│ (mTLS) │ │ (mTLS) │ │ (mTLS) │
└─────┬────┘ └────┬─────┘ └────┬─────┘
│ │ │
└────────────┼─────────────┘
↓
┌────────────────────────┐
│ Policy Engine │
│ (Every access checked) │
└────────────────────────┘
Microservices Security
patterns:
api_gateway:
- Single entry point
- Authentication at gateway
- Rate limiting
- Request validation
service_mesh:
- mTLS between services
- Service identity
- Traffic policies
- Observability
secrets_management:
- External secrets (Vault)
- Short-lived credentials
- Automatic rotation
Secure Data Flow
┌──────────────────────────────────────────────────┐
│ Secure Zone │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
Internet ─│─→│ WAF/LB │───→│ API │───→│ Service │ │
│ └─────────┘ └─────────┘ └────┬────┘ │
│ ↓ ↓ ↓ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Logs │ │ Logs │ │ Logs │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ └──────────────┼──────────────┘ │
│ ↓ │
│ ┌───────────┐ │
│ │ SIEM │ │
│ └───────────┘ │
└──────────────────────────────────────────────────┘
Implementation Guidelines
Secure Coding Standards
language_specific:
java:
- Use OWASP ESAPI for encoding
- PreparedStatement for SQL
- Input validation with Bean Validation
python:
- Use Pydantic for validation
- Parameterized queries (SQLAlchemy ORM)
- secrets module for crypto-random
javascript:
- DOMPurify for HTML sanitization
- Helmet.js for HTTP headers
- bcrypt for password hashing
go:
- html/template for HTML (auto-escaping)
- crypto/rand for randomness
- Context-based timeouts
Security Headers
# Must-have HTTP Security Headers
headers = {
"Strict-Transport-Security": "max-age=31536000; includeSubDomains",
"Content-Security-Policy": "default-src 'self'; script-src 'self'",
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "strict-origin-when-cross-origin",
"Permissions-Policy": "geolocation=(), microphone=(), camera=()"
}
Error Handling
# Secure Error Handling
# SCHLECHT
@app.errorhandler(Exception)
def handle_error(error):
return {
"error": str(error),
"stack_trace": traceback.format_exc(),
"query": request.args.get("q")
}
# GUT
@app.errorhandler(Exception)
def handle_error(error):
error_id = str(uuid.uuid4())
# Log mit Details (intern)
logger.error(f"Error {error_id}: {error}", exc_info=True)
# Response ohne Details (extern)
return {
"error": "An error occurred",
"error_id": error_id, # Für Support
"support": "Contact support@example.com with error ID"
}, 500
Security in SDLC
Requirements Phase
activities:
- Security Requirements Workshop
- Compliance Mapping
- Risk Assessment (initial)
- Abuse Cases / Evil User Stories
output:
- Security Requirements Document
- Compliance Checklist
- Initial Threat Model
Design Phase
activities:
- Threat Modeling (STRIDE)
- Security Architecture Review
- Attack Surface Analysis
- Design Pattern Selection
output:
- Security Design Document
- Threat Model (detailed)
- Mitigation Strategies
Development Phase
activities:
- Secure Coding Training
- Code Reviews (security focus)
- SAST in IDE
- SCA for Dependencies
output:
- Secure Code
- Addressed Findings
- Security Debt documented
Testing Phase
activities:
- SAST (automated)
- DAST (automated)
- Security Unit Tests
- Penetration Testing
output:
- Security Test Results
- Remediated Findings
- Accepted Risks (documented)
Deployment Phase
activities:
- Secure Configuration Review
- Secrets Management Verification
- Security Monitoring Setup
output:
- Deployed with Security Controls
- Monitoring Active
- Incident Response Ready
Metriken für Security by Design
Leading Indicators
# Zeigen, ob Security eingebaut wird
metrics:
- % Requirements mit Security-Komponente
- % Designs mit Threat Model
- % Code Reviews mit Security-Fokus
- Security Training Completion Rate
- Time Security involved before first code
Lagging Indicators
# Zeigen, ob es funktioniert
metrics:
- Vulnerabilities per Release (trending down?)
- Time to Fix Security Issues
- Security Defects in Production
- Incidents caused by Design Flaws
Anti-Patterns
"Security Later"
anti_pattern: "Wir kümmern uns um Security nach dem MVP"
reality:
- MVP wird zu Production
- Security Debt akkumuliert
- Refactoring wird teurer
- "Später" kommt nie
solution:
- Security von Tag 1
- Auch MVP braucht Basics (Auth, Encryption, Validation)
"Security by Obscurity"
anti_pattern: "Niemand weiß, dass /admin/secret-panel existiert"
reality:
- Scanner finden alles
- Logs verraten Pfade
- Mitarbeiter reden
solution:
- Proper Authentication
- Authorization Checks
- Assume everything is known
"Roll Your Own Crypto"
anti_pattern: "Wir haben unsere eigene Verschlüsselung entwickelt"
reality:
- Crypto ist SCHWER
- Subtile Fehler sind fatal
- Keine Peer Review
solution:
- Use established libraries (libsodium, OpenSSL)
- Use established protocols (TLS, JWT)
- Never invent crypto
Fazit
Security by Design ist keine Methodik, die man "implementiert" – es ist ein Mindset, das die gesamte Organisation durchdringen muss. Es bedeutet, bei jeder Entscheidung zu fragen: "Was könnte hier schiefgehen? Wie können wir das von vornherein verhindern?"
Die Investition am Anfang zahlt sich hundertfach aus: Weniger Vulnerabilities, weniger Incidents, weniger panische Patches um 3 Uhr nachts.
Security ist keine Feature – es ist eine Eigenschaft. Und Eigenschaften muss man einbauen, nicht draufkleben.
Weiterführende Ressourcen: