Skip to main content

Sicherheit & Compliance

🔒 Sicherheitsarchitektur

Verschlüsselung

Transport-Verschlüsselung

  • TLS 1.3 für alle API-Verbindungen
  • HSTS (HTTP Strict Transport Security) aktiviert
  • Perfect Forward Secrecy implementiert
  • Keine Unterstützung für unsichere Protokolle (SSL 2.0/3.0, TLS 1.0/1.1)
# Nginx SSL-Konfiguration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=63072000" always;

Daten-Verschlüsselung

  • AES-256-GCM für ruhende Daten
  • Verschlüsselte Datenbank (Transparent Data Encryption)
  • Verschlüsselte Backups
  • Key Management mit HSM (Hardware Security Module)

Authentifizierung

Multi-Faktor-Authentifizierung (MFA)

// MFA-Implementation
const speakeasy = require('speakeasy');

// Secret generieren
const secret = speakeasy.generateSecret({
name: 'PunchFlow',
issuer: 'PunchFlow GmbH'
});

// Token verifizieren
const verified = speakeasy.totp.verify({
secret: user.mfaSecret,
encoding: 'base32',
token: userProvidedToken,
window: 2
});

OAuth 2.0 / OpenID Connect

# Authelia-Konfiguration für OIDC
identity_providers:
oidc:
hmac_secret: ${OIDC_HMAC_SECRET}
issuer_private_key: |
-----BEGIN RSA PRIVATE KEY-----
${OIDC_PRIVATE_KEY}
-----END RSA PRIVATE KEY-----
clients:
- id: punchflow-app
secret: ${CLIENT_SECRET}
authorization_policy: two_factor
redirect_uris:
- https://app.punchflow.de/callback
scopes:
- openid
- profile
- email

API-Sicherheit

Rate Limiting

# Rate Limiting Implementation
from slowapi import Limiter
from slowapi.util import get_remote_address

limiter = Limiter(
key_func=get_remote_address,
default_limits=["1000/hour", "100/minute"]
)

@app.post("/api/v1/punchout/setup")
@limiter.limit("50/minute")
async def punchout_setup(request: Request):
# Process request
pass

API-Key Management

-- API Key Schema
CREATE TABLE api_keys (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES merchants(id),
key_hash VARCHAR(255) NOT NULL UNIQUE,
name VARCHAR(100),
permissions JSONB DEFAULT '[]',
last_used_at TIMESTAMP,
expires_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
revoked_at TIMESTAMP,
ip_whitelist INET[] DEFAULT NULL
);

-- Audit Log
CREATE TABLE api_key_usage (
id BIGSERIAL PRIMARY KEY,
api_key_id UUID REFERENCES api_keys(id),
endpoint VARCHAR(255),
ip_address INET,
user_agent TEXT,
response_code INT,
timestamp TIMESTAMP DEFAULT NOW()
);

🇪🇺 DSGVO-Compliance

Datenverarbeitung

Rechtmäßigkeit der Verarbeitung

  • Vertragserfüllung (Art. 6 Abs. 1 lit. b DSGVO)
  • Berechtigte Interessen (Art. 6 Abs. 1 lit. f DSGVO)
  • Einwilligung wo erforderlich (Art. 6 Abs. 1 lit. a DSGVO)

Datenkategorien

personal_data:
basic:
- email
- name
- company
optional:
- phone
- address
sensitive: # Besonderer Schutz
- payment_info # Verschlüsselt
- purchase_history # Pseudonymisiert

Betroffenenrechte

Auskunftsrecht (Art. 15 DSGVO)

@app.get("/api/v1/gdpr/data-export")
async def export_user_data(user_id: str, token: str):
"""Export all user data in machine-readable format"""

# Verify request authenticity
if not verify_gdpr_token(user_id, token):
raise HTTPException(401, "Invalid token")

# Collect all user data
data = {
"personal_info": get_user_info(user_id),
"sessions": get_user_sessions(user_id),
"orders": get_user_orders(user_id),
"logs": get_user_activity_logs(user_id)
}

# Return as JSON or CSV
return JSONResponse(
content=data,
headers={"Content-Disposition": f"attachment; filename=user_data_{user_id}.json"}
)

Recht auf Löschung (Art. 17 DSGVO)

@app.delete("/api/v1/gdpr/delete-account")
async def delete_user_account(user_id: str, confirmation: str):
"""Complete account deletion with audit trail"""

# Create deletion record
deletion_id = create_deletion_record(user_id)

# Anonymize data instead of hard delete
anonymize_user_data(user_id)

# Keep legal requirements
archive_for_legal_retention(user_id)

# Notify user
send_deletion_confirmation(user_id)

return {"deletion_id": deletion_id, "status": "completed"}

Datenschutz-Folgenabschätzung

## DSFA für PunchFlow PunchOut-System

### 1. Systematische Beschreibung
- Verarbeitung von B2B-Transaktionsdaten
- Automatisierte Entscheidungsfindung: NEIN
- Profiling: Limitiert auf Geschäftszwecke

### 2. Risikobewertung
| Risiko | Eintrittswahrscheinlichkeit | Schadenshöhe | Maßnahmen |
|--------|---------------------------|--------------|-----------|
| Datenverlust | Niedrig | Hoch | Backups, Verschlüsselung |
| Unbefugter Zugriff | Niedrig | Hoch | MFA, Monitoring |
| Datenleck | Sehr niedrig | Sehr hoch | DLP, Schulungen |

### 3. Technische Maßnahmen
- Ende-zu-Ende-Verschlüsselung
- Zugriffskontrolle (RBAC)
- Audit-Logging
- Penetration Testing

🏛️ Compliance-Standards

ISO 27001

Information Security Management System (ISMS)

isms_controls:
access_control:
- user_access_management
- privileged_access_management
- password_management
- review_of_access_rights

cryptography:
- encryption_policy
- key_management

physical_security:
- secure_areas
- equipment_protection

operations_security:
- change_management
- capacity_management
- malware_protection

incident_management:
- incident_response_plan
- evidence_collection
- lessons_learned

SOC 2 Type II

Trust Service Criteria

  1. Security: Schutz gegen unbefugten Zugriff
  2. Availability: 99.9% SLA
  3. Processing Integrity: Korrekte Verarbeitung
  4. Confidentiality: Vertraulichkeit gewährleistet
  5. Privacy: Datenschutz implementiert

PCI DSS (wenn Zahlungsdaten)

// PCI DSS Compliance für Zahlungsdaten
class PCICompliantHandler {
constructor() {
this.tokenVault = new SecureTokenVault();
}

// Nie Kartendaten speichern, nur Token
async processPayment(cardData) {
// Tokenize immediately
const token = await this.tokenVault.tokenize(cardData);

// Use token for processing
const result = await this.paymentGateway.charge(token);

// Never log sensitive data
this.logger.info('Payment processed', {
token: token.substring(0, 4) + '****',
result: result.status
});

return result;
}
}

🛡️ Security Headers

# Security Headers Konfiguration
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.punchflow.de; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://api.punchflow.de; frame-ancestors 'none';" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

🔍 Security Monitoring

SIEM Integration

# Elasticsearch/Kibana Integration
import elasticsearch
from datetime import datetime

class SecurityEventLogger:
def __init__(self):
self.es = elasticsearch.Elasticsearch(['localhost:9200'])

def log_security_event(self, event_type, details):
doc = {
'timestamp': datetime.now(),
'event_type': event_type,
'severity': self.calculate_severity(event_type),
'details': details,
'source_ip': details.get('ip'),
'user_id': details.get('user_id'),
'session_id': details.get('session_id')
}

self.es.index(
index='security-events',
body=doc
)

# Alert on critical events
if doc['severity'] >= 8:
self.send_security_alert(doc)

Intrusion Detection

# Fail2Ban Konfiguration
[punchflow-api]
enabled = true
port = https
filter = punchflow-api
logpath = /var/log/punchflow/api.log
maxretry = 5
findtime = 600
bantime = 3600
action = iptables-multiport[name=PunchFlow, port="https"]
sendmail-whois[name=PunchFlow, dest=security@punchflow.de]

📝 Audit & Logging

Audit Trail

-- Comprehensive Audit Log
CREATE TABLE audit_log (
id BIGSERIAL PRIMARY KEY,
timestamp TIMESTAMP DEFAULT NOW(),
user_id UUID,
session_id VARCHAR(255),
action VARCHAR(100) NOT NULL,
resource_type VARCHAR(50),
resource_id VARCHAR(255),
old_value JSONB,
new_value JSONB,
ip_address INET,
user_agent TEXT,
result VARCHAR(20),
error_message TEXT
);

-- Indexes for efficient querying
CREATE INDEX idx_audit_timestamp ON audit_log(timestamp);
CREATE INDEX idx_audit_user ON audit_log(user_id);
CREATE INDEX idx_audit_action ON audit_log(action);

Log-Aufbewahrung

log_retention:
security_logs: 2_years
access_logs: 1_year
application_logs: 6_months
debug_logs: 7_days

archival:
method: encrypted_s3
bucket: punchflow-logs-archive
encryption: AES256
lifecycle:
transition_to_glacier: 90_days
expiration: 7_years # Legal requirement

🚨 Incident Response

Incident Response Plan

## Stufe 1: Erkennung (< 15 Minuten)
1. Automatische Alerts evaluieren
2. Schweregrad bestimmen
3. Incident-Team aktivieren

## Stufe 2: Eindämmung (< 1 Stunde)
1. Betroffene Systeme isolieren
2. Weitere Ausbreitung verhindern
3. Beweise sichern

## Stufe 3: Untersuchung (< 4 Stunden)
1. Root Cause Analysis
2. Auswirkungsanalyse
3. Timeline erstellen

## Stufe 4: Behebung (< 24 Stunden)
1. Schwachstelle patchen
2. Systeme wiederherstellen
3. Zusätzliche Kontrollen implementieren

## Stufe 5: Nachbereitung (< 1 Woche)
1. Post-Mortem durchführen
2. Lessons Learned dokumentieren
3. Prozesse verbessern
4. Stakeholder informieren

🔐 Verschlüsselung

Encryption at Rest

# Database Encryption
from cryptography.fernet import Fernet
import base64

class FieldEncryption:
def __init__(self, key: str):
self.cipher = Fernet(base64.b64encode(key.encode()).decode())

def encrypt(self, plaintext: str) -> str:
return self.cipher.encrypt(plaintext.encode()).decode()

def decrypt(self, ciphertext: str) -> str:
return self.cipher.decrypt(ciphertext.encode()).decode()

# Usage in SQLAlchemy
class User(Base):
__tablename__ = 'users'

id = Column(UUID, primary_key=True)
email = Column(EncryptedType(String, encryption_key))
phone = Column(EncryptedType(String, encryption_key))

Key Management

# HashiCorp Vault Configuration
storage "postgresql" {
connection_url = "postgres://vault:password@localhost:5432/vault"
}

listener "tcp" {
address = "127.0.0.1:8200"
tls_cert_file = "/opt/vault/tls/cert.pem"
tls_key_file = "/opt/vault/tls/key.pem"
}

# Key Rotation Policy
path "secret/data/punchflow/*" {
capabilities = ["create", "read", "update", "delete"]
}

path "transit/encrypt/punchflow" {
capabilities = ["update"]
}

path "transit/decrypt/punchflow" {
capabilities = ["update"]
}

🌍 Hosting & Infrastruktur

Deutsche Server-Standorte

infrastructure:
primary_datacenter:
provider: Hetzner
location: Nürnberg, Deutschland
tier: Tier III+
certifications:
- ISO_27001
- DIN_EN_50600

backup_datacenter:
provider: Hetzner
location: Falkenstein, Deutschland
tier: Tier III

cdn:
provider: Cloudflare
locations:
- Frankfurt
- Berlin
- München

Disaster Recovery

disaster_recovery:
rpo: 1_hour # Recovery Point Objective
rto: 4_hours # Recovery Time Objective

backup_strategy:
frequency: hourly
retention:
hourly: 24
daily: 30
weekly: 12
monthly: 12
yearly: 7

replication:
type: asynchronous
lag: < 5_minutes

testing:
frequency: quarterly
type: full_failover_test

📋 Compliance-Checkliste

DSGVO

  • ✅ Datenschutzerklärung aktuell
  • ✅ Cookie-Banner implementiert
  • ✅ Auftragsverarbeitungsverträge (AVV)
  • ✅ Technische und organisatorische Maßnahmen (TOM)
  • ✅ Verzeichnis von Verarbeitungstätigkeiten
  • ✅ Datenschutz-Folgenabschätzung
  • ✅ Meldung bei Datenpannen (72h)
  • ✅ Datenschutzbeauftragter benannt

IT-Sicherheit

  • ✅ Penetration Testing (jährlich)
  • ✅ Vulnerability Scanning (monatlich)
  • ✅ Security Patches (< 24h kritisch)
  • ✅ Web Application Firewall (WAF)
  • ✅ DDoS-Schutz
  • ✅ Backup-Tests (monatlich)
  • ✅ Incident Response Plan
  • ✅ Security Awareness Training

Zertifizierungen

  • ✅ SSL/TLS-Zertifikate
  • ✅ ISO 27001 (in Vorbereitung)
  • ✅ SOC 2 Type II (geplant)
  • ✅ Trusted Shops (optional)

📞 Sicherheitskontakte

Security Team

Responsible Disclosure

Datenschutzbeauftragter

Dr. Max Mustermann
Datenschutzbeauftragter
PunchFlow GmbH
Beispielstraße 123
10115 Berlin
datenschutz@punchflow.de