Zum Inhalt springen

Sichere Software-Entwicklung -- Security by Design für dein Startup

Felix Lenhard 13 min
Zurück zum Blog

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

  1. Least Privilege: Jede Komponente bekommt nur die minimal notwendigen Rechte
  2. Defense in Depth: Mehrere Sicherheitsschichten statt einer einzigen Barriere
  3. Fail Secure: Bei Fehlern sicher scheitern, nicht unsicher
  4. Separation of Concerns: Kritische Funktionen voneinander trennen
  5. Keep It Simple: Einfache Systeme haben weniger Angriffsfläche
  6. 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) oder v-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:

ToolKategorieKosten
SonarQube CommunitySASTKostenlos
SemgrepSASTKostenlos (Open Source)
OWASP ZAPDASTKostenlos
SnykDependency ScanningFree Tier verfügbar
TrivyContainer ScanningKostenlos
gitleaksSecrets DetectionKostenlos
DependabotDependency UpdatesKostenlos (GitHub)
CheckovIaC ScanningKostenlos

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.

Erstgespräch vereinbaren

Du überlegst zu gründen oder bist schon mittendrin? Schreib uns ein formloses E-Mail -- wir melden uns innerhalb weniger Tage.

E-Mail schreiben