Security by Design

Von Boris Sander19. November 2025
 Security by Design

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: