Sichere Software-Entwicklung -- Security by Design für dein Startup
Du baust ein Produkt. Du willst schnell sein, Features liefern, Kunden begeistern. Security? "Machen wir später." Das höre ich ständig von Startups -- auch hier im Burgenland. Und es ist einer der teuersten Fehler, den du machen kannst.
Eine Sicherheitslücke nachträglich zu beheben kostet laut IBM-Studien 30 Mal mehr als sie während der Entwicklung zu verhindern. In unserer Cybersecurity-Grundlagen-Serie haben wir die Basics abgedeckt. Jetzt wird es technisch: Wie entwickelst du von Anfang an sichere Software?
Was ist Security by Design?
Security by Design bedeutet, dass Sicherheit kein nachträgliches Feature ist, sondern ein fundamentaler Bestandteil deines Entwicklungsprozesses. Von der Architektur bis zum Deployment -- Sicherheit wird in jeden Schritt integriert.
Die Grundprinzipien
- Least Privilege: Jede Komponente bekommt nur die minimal notwendigen Rechte
- Defense in Depth: Mehrere Sicherheitsschichten statt einer einzigen Barriere
- Fail Secure: Bei Fehlern sicher scheitern, nicht unsicher
- Separation of Concerns: Kritische Funktionen voneinander trennen
- Keep It Simple: Einfache Systeme haben weniger Angriffsfläche
- Zero Trust: Nichts und niemandem standardmässig vertrauen
Die OWASP Top 10 -- Dein Pflichtprogramm
Die OWASP (Open Web Application Security Project) Top 10 sind die häufigsten Sicherheitsrisiken in Webanwendungen. Jeder Entwickler muss sie kennen:
1. Broken Access Control
Nutzer können auf Daten oder Funktionen zugreifen, für die sie keine Berechtigung haben.
Beispiel: Ein Nutzer ändert die URL von /user/123/profil zu /user/124/profil und sieht das Profil eines anderen Nutzers.
Gegenmassnahmen:
- Server-seitige Zugriffskontrolle für jede Anfrage
- Deny by Default -- alles ist verboten, was nicht explizit erlaubt ist
- Automatisierte Tests für Zugriffskontrollen
2. Cryptographic Failures
Sensible Daten werden unzureichend geschützt -- fehlende Verschlüsselung, schwache Algorithmen oder falsche Konfiguration.
Gegenmassnahmen:
- Alle sensiblen Daten verschlüsseln (in Transit und at Rest)
- Aktuelle Algorithmen verwenden (AES-256, RSA-2048+, SHA-256+)
- Keine selbst erfundene Kryptographie (wirklich, nie)
- TLS 1.2+ für alle Verbindungen (siehe HTTPS-Beitrag)
3. Injection
Schadcode wird in Anfragen eingeschleust -- SQL Injection, Command Injection, XSS.
Beispiel SQL Injection:
-- Unsicher:
query = "SELECT * FROM users WHERE email = '" + userInput + "'"
-- Eingabe: ' OR '1'='1
-- Ergebnis: Alle Nutzerdaten werden ausgegeben
-- Sicher (Parameterized Query):
query = "SELECT * FROM users WHERE email = $1"
params = [userInput]
Gegenmassnahmen:
- Immer Parameterized Queries/Prepared Statements verwenden
- Input Validation auf der Serverseite
- Output Encoding für alle dynamischen Inhalte
- Content Security Policy (CSP) gegen XSS
4. Insecure Design
Architektur- und Designfehler, die sich nicht durch bessere Implementierung lösen lassen.
Gegenmassnahmen:
- Threat Modeling vor der Entwicklung
- Sicherheitsanforderungen in User Stories integrieren
- Architektur-Reviews mit Security-Fokus
5. Security Misconfiguration
Unsichere Standardkonfigurationen, offene Cloud-Buckets, unnötige Features aktiviert.
Gegenmassnahmen:
- Härtung aller Systeme nach Deployment
- Default-Passwörter immer ändern
- Unnötige Features, Ports und Dienste deaktivieren
- Automatisierte Konfigurationschecks
6. Vulnerable and Outdated Components
Verwendung von Bibliotheken und Frameworks mit bekannten Schwachstellen.
Gegenmassnahmen:
- Abhängigkeiten regelmässig aktualisieren
- Automatisierte Vulnerability-Scans (Dependabot, Snyk)
- Software Bill of Materials (SBOM) führen
7. Identification and Authentication Failures
Schwächen bei Login, Session-Management und Identitätsprüfung. Mehr dazu in unserem Authentifizierung-Beitrag.
8. Software and Data Integrity Failures
Unsichere CI/CD-Pipelines, nicht verifizierte Updates, Manipulationen an Software oder Daten.
Gegenmassnahmen:
- Code-Signing für Releases
- Integritätschecks für Abhängigkeiten (lockfiles, checksums)
- Sichere CI/CD-Pipeline (separate Secrets, minimale Rechte)
9. Security Logging and Monitoring Failures
Angriffe werden nicht erkannt, weil Logging und Monitoring fehlen oder unzureichend sind.
Gegenmassnahmen:
- Alle sicherheitsrelevanten Events loggen
- Logs zentral sammeln und auswerten
- Alerting bei verdächtigen Aktivitäten
- Logs vor Manipulation schützen
10. Server-Side Request Forgery (SSRF)
Der Server wird dazu gebracht, Anfragen an interne Dienste zu senden.
Gegenmassnahmen:
- URL-Validation und Whitelisting
- Netzwerk-Segmentierung
- Keine internen Dienste über öffentliche Endpunkte erreichbar
Sichere API-Entwicklung
Die meisten Startups bauen APIs. Hier sind die wichtigsten Sicherheitsregeln:
Authentifizierung und Autorisierung
# JWT-basierte Authentifizierung (Beispiel)
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
- OAuth 2.0 / OpenID Connect für Authentifizierung
- JWT mit kurzer Lebensdauer (15-60 Minuten)
- Refresh Tokens sicher speichern (httpOnly Cookie)
- API Keys nur für Server-to-Server-Kommunikation
- Rate Limiting gegen Brute-Force-Angriffe
Input Validation
Validiere jede Eingabe auf der Serverseite:
# Python/FastAPI Beispiel
from pydantic import BaseModel, EmailStr, constr
class UserCreate(BaseModel):
email: EmailStr
name: constr(min_length=2, max_length=100)
age: int = Field(ge=18, le=150)
- Whitelist statt Blacklist
- Typ, Länge und Format prüfen
- Sanitize Output (HTML encoding)
- Content-Type validieren
Rate Limiting und Throttling
Schütze deine API vor Missbrauch:
# Nginx Rate Limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
location /api/ {
limit_req zone=api burst=20 nodelay;
}
- Login-Endpunkte: Max. 5 Versuche pro Minute
- API-Endpunkte: Je nach Usecase, z.B. 100 Requests pro Minute
- Upload-Endpunkte: Dateigrösse und -anzahl begrenzen
API-Versionierung und Deprecation
- Versioniere deine API (z.B.
/api/v1/) - Kommuniziere Deprecation-Zeitpläne
- Alte Versionen zeitnah abschalten -- alte APIs sind oft weniger sicher
Secure Development Lifecycle (SDL)
Integriere Sicherheit in deinen gesamten Entwicklungsprozess:
1. Planung und Design
- Threat Modeling: Identifiziere Bedrohungen bevor du Code schreibst
- Sicherheitsanforderungen: Definiere Security-Anforderungen als Teil der User Stories
- Architektur-Review: Lass die Architektur von jemandem mit Security-Know-how prüfen
2. Entwicklung
- Secure Coding Guidelines: Definiere Regeln für sicheren Code
- Code Reviews mit Security-Fokus: Mindestens ein Reviewer achtet auf Sicherheit
- Pair Programming: Für sicherheitskritische Komponenten
3. Testing
- Unit Tests für Security-Funktionen: Testen deine Zugriffskontrollen wirklich?
- Statische Code-Analyse (SAST): Tools wie SonarQube, Semgrep, CodeQL
- Dynamische Analyse (DAST): Tools wie OWASP ZAP, Burp Suite
- Dependency Scanning: Snyk, Dependabot, npm audit
4. Deployment
- Infrastructure as Code: Reproduzierbare, überprüfbare Deployments
- Secrets Management: Keine Secrets im Code oder in Umgebungsvariablen der CI/CD
- Container-Security: Base Images aktuell halten, minimal halten
- Automated Security Gates: Deployments blockieren bei kritischen Findings
5. Betrieb und Monitoring
- Logging: Alle sicherheitsrelevanten Events
- Monitoring: Anomalie-Erkennung
- Incident Response: Plan für den Ernstfall (siehe Incident Response Plan)
Secrets Management -- Geheimnisse richtig verwalten
Eines der häufigsten Probleme bei Startups: Secrets (API-Keys, Passwörter, Tokens) landen im Code.
Was du NICHT tun solltest
# NIEMALS!
DB_PASSWORD = "mein-super-geheimes-passwort"
API_KEY = "sk-1234567890abcdef"
# NIEMALS im Git-Repository!
# .env Datei mit echten Credentials committen
Was du stattdessen tun solltest
Umgebungsvariablen (Minimum):
export DB_PASSWORD=$(cat /run/secrets/db_password)
Secrets Manager (Empfohlen):
- HashiCorp Vault: Open Source, sehr mächtig
- AWS Secrets Manager: Wenn du auf AWS bist
- Google Secret Manager: Für Google Cloud
- Doppler: Einfacher, startup-freundlicher Dienst
Git-Schutz:
# .gitignore
.env
.env.*
*.pem
*.key
credentials.json
# Pre-commit Hook mit git-secrets oder gitleaks
gitleaks detect --source . --verbose
Secrets Rotation
- Rotiere Secrets regelmässig (mindestens vierteljährlich)
- Automatisiere die Rotation wo möglich
- Nutze kurzlebige Tokens statt langlebiger API-Keys
Container-Security
Wenn du Docker oder Kubernetes nutzt:
Docker Best Practices
# Minimales Base Image verwenden
FROM node:20-alpine
# Nicht als root laufen
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# Multi-stage Build fuer kleinere Images
FROM node:20-alpine AS builder
COPY . .
RUN npm ci && npm run build
FROM node:20-alpine
COPY --from=builder /app/dist /app/dist
- Minimale Base Images: Alpine oder Distroless
- Nicht als root: Eigenen User erstellen
- Multi-stage Builds: Nur das Nötige im finalen Image
- Image Scanning: Trivy, Snyk Container, Docker Scout
- Signierte Images: Docker Content Trust
Kubernetes-Security
- Network Policies: Kommunikation zwischen Pods einschränken
- RBAC: Minimale Berechtigungen für Service Accounts
- Pod Security Standards: Restricted-Profil verwenden
- Secrets: Kubernetes Secrets sind base64-encoded, nicht verschlüsselt! Nutze External Secrets Operator
Abhängigkeiten managen
Dein Code ist nur so sicher wie deine Abhängigkeiten:
Automatisierte Vulnerability-Scans
# npm
npm audit
# Python
pip-audit
# Go
govulncheck ./...
# Allgemein
snyk test
Dependabot / Renovate einrichten
Automatisierte Updates für Abhängigkeiten:
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
Supply Chain Security
- Prüfe neue Abhängigkeiten vor der Installation (Downloads, Maintainer, Issues)
- Nutze Lock-Files (package-lock.json, Pipfile.lock, go.sum)
- Aktiviere Signaturen-Prüfung wo möglich
- Halte die Anzahl der Abhängigkeiten minimal
Security für Frontend-Anwendungen
Content Security Policy (CSP)
Schon in unserem HTTPS-Beitrag erwähnt, hier nochmal im Detail:
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' https://trusted-cdn.com;">
Cross-Site Scripting (XSS) verhindern
- Alle User-Inputs escapen
- React, Vü und Angular escapen standardmässig -- aber Vorsicht bei
dangerouslySetInnerHTML(React) oderv-html(Vü) - Keine Inline-Scripts verwenden
- CSP ohne
unsafe-inline
Cross-Site Request Forgery (CSRF)
- Anti-CSRF-Tokens für zustandsändernde Anfragen
- SameSite-Attribut für Cookies setzen
- Double Submit Cookie Pattern als Alternative
Entwickler-Toolchain für Security
Hier die wichtigsten Tools, die du in deinen Workflow integrieren solltest:
| Tool | Kategorie | Kosten |
|---|---|---|
| SonarQube Community | SAST | Kostenlos |
| Semgrep | SAST | Kostenlos (Open Source) |
| OWASP ZAP | DAST | Kostenlos |
| Snyk | Dependency Scanning | Free Tier verfügbar |
| Trivy | Container Scanning | Kostenlos |
| gitleaks | Secrets Detection | Kostenlos |
| Dependabot | Dependency Updates | Kostenlos (GitHub) |
| Checkov | IaC Scanning | Kostenlos |
Für ein Startup reichen die kostenlosen Optionen völlig aus. Integriere sie in deine CI/CD-Pipeline und du bist den meisten Startups meilenweit voraus.
Security Champions im Team
Du brauchst kein dediziertes Security-Team, aber du brauchst Security Champions:
- Was ist ein Security Champion? Ein Entwickler, der besonderes Interesse an Security hat und als Ansprechpartner dient
- Aufgaben: Code Reviews mit Security-Fokus, Schulungen organisieren, neue Tools evaluieren
- Weiterbildung: OWASP-Trainings, Security-Konferenzen, Bug-Bounty-Programme zum Üben
Checkliste: Sichere Software-Entwicklung
- OWASP Top 10 im Team bekannt machen
- Secure Coding Guidelines erstellen
- Input Validation für alle Endpunkte implementieren
- Secrets aus dem Code entfernen und Secrets Manager nutzen
- Automatisierte Security-Scans in CI/CD integrieren (SAST, DAST, Dependency Scanning)
- .gitignore und Pre-commit Hooks für Secrets-Erkennung einrichten
- Abhängigkeiten automatisiert aktualisieren (Dependabot/Renovate)
- Code Reviews mit Security-Fokus etablieren
- Container-Images minimal und aktuell halten
- Security Champion im Team bestimmen
- Rate Limiting für alle APIs konfigurieren
- Logging und Monitoring für Security-Events einrichten
Fazit
Sichere Software-Entwicklung muss nicht kompliziert sein. Mit den richtigen Grundprinzipien, automatisierten Tools und einem Security-bewussten Team kannst du von Anfang an sicher entwickeln. Der Aufwand ist minimal verglichen mit den Kosten einer Sicherheitslücke in Produktion.
Fang mit den Basics an: Input Validation, Secrets Management, automatisierte Scans. Dann arbeite dich schrittweise vor. Security ist kein Zustand, sondern ein Prozess.
Im nächsten Beitrag gehen wir auf ein Thema ein, das für fast jedes moderne Startup relevant ist: Cloud-Security.
Dieser Beitrag ist Teil der Serie "Cybersecurity für Startups" auf dem Startup Burgenland Blog. Du baust gerade dein Startup auf und brauchst Unterstützung? Startup Burgenland bietet dir Beratung, Förderungen und ein starkes Netzwerk -- von der Idee bis zum Markteintritt. Melde dich bei uns und werde Teil der wachsenden Startup-Community im Burgenland!
Dies ist Beitrag 6 von 10 der Serie "Cybersecurity für Startups" in der Kategorie Produkt und Technologie.
Über den Autor: Felix Lenhard ist Program Director und Startup Coach bei Startup Burgenland. Zuvor Managing Director beim 360 Innovation Lab, Innovation Manager bei RHI Magnesita und Serial Entrepreneur mit internationalen Exits. Über 15 Jahre Erfahrung in Innovation und Unternehmensaufbau.