← Zurück zum Blog

Sicherheit und Datenschutz in deiner App

Veröffentlicht am 22. Januar 2026

Sicherheit und Datenschutz sind in der heutigen Zeit kritischer denn je. In diesem Artikel zeige ich dir, wie du deine App sicher gestaltest und die Privatsphäre deiner Nutzer schützt – auch ohne unnötige Cookies.

1. Cookie-loses Tracking mit Vercel Analytics

Traditionelles Tracking wie Google Analytics erfordert Cookies und Cookie-Banner. Vercel Analytics bietet eine Alternative:

  • Kein Cookie-Banner erforderlich
  • GDPR/DSGVO-konform out of the box
  • Keine personenbezogenen Daten gespeichert
  • Einfache Integration in Nuxt

Installation

npm install @vercel/analytics

Integration in Nuxt

// plugins/vercel-analytics.client.ts
import { inject } from '@vercel/analytics'

export default defineNuxtPlugin(() => {
  inject()
})

Das war's! Vercel Analytics ist jetzt aktiv und trackt Seitenaufrufe ohne Cookies.

2. Authentifizierung sicher implementieren

Passwort-Hashing mit bcrypt

import bcrypt from 'bcrypt'

// Passwort hashen beim Registrieren
const saltRounds = 10
const hashedPassword = await bcrypt.hash(password, saltRounds)

// In Datenbank speichern
await db.users.create({
  email,
  password: hashedPassword
})

// Passwort verifizieren beim Login
const user = await db.users.findOne({ email })
const isValid = await bcrypt.compare(password, user.password)

if (!isValid) {
  throw new Error('Ungültige Anmeldedaten')
}

JWT-Tokens für Session-Management

import jwt from 'jsonwebtoken'

// server/api/auth/login.post.ts
export default defineEventHandler(async (event) => {
  const { email, password } = await readBody(event)
  
  // User authentifizieren
  const user = await authenticateUser(email, password)
  
  // JWT Token erstellen
  const token = jwt.sign(
    { userId: user.id, email: user.email },
    process.env.JWT_SECRET,
    { expiresIn: '7d' }
  )
  
  // HTTP-only Cookie setzen (sicher vor XSS)
  setCookie(event, 'auth_token', token, {
    httpOnly: true,
    secure: true,
    sameSite: 'strict',
    maxAge: 60 * 60 * 24 * 7 // 7 Tage
  })
  
  return { success: true, user }
})

3. HTTPS und Security Headers

Stelle sicher, dass deine App immer über HTTPS läuft und nutze Security Headers:

// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/**': {
      headers: {
        // XSS-Schutz
        'X-Content-Type-Options': 'nosniff',
        'X-Frame-Options': 'DENY',
        'X-XSS-Protection': '1; mode=block',
        
        // HTTPS erzwingen
        'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
        
        // Referrer-Policy
        'Referrer-Policy': 'strict-origin-when-cross-origin',
        
        // Content Security Policy
        'Content-Security-Policy': 
          "default-src 'self'; " +
          "script-src 'self' 'unsafe-inline' 'unsafe-eval'; " +
          "style-src 'self' 'unsafe-inline'; " +
          "img-src 'self' data: https:; " +
          "font-src 'self' data:; " +
          "connect-src 'self' https://api.example.com;"
      }
    }
  }
})

4. Input-Validierung und Sanitization

Validiere und bereinige IMMER alle User-Inputs:

import { z } from 'zod'

// Schema definieren
const userSchema = z.object({
  email: z.string().email('Ungültige E-Mail'),
  password: z
    .string()
    .min(8, 'Passwort muss mindestens 8 Zeichen haben')
    .regex(/[A-Z]/, 'Passwort muss einen Großbuchstaben enthalten')
    .regex(/[0-9]/, 'Passwort muss eine Zahl enthalten'),
  name: z
    .string()
    .min(2, 'Name muss mindestens 2 Zeichen haben')
    .max(50, 'Name darf maximal 50 Zeichen haben')
})

// In API Route validieren
export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  
  try {
    const validated = userSchema.parse(body)
    // Weiter mit validierten Daten
  } catch (error) {
    throw createError({
      statusCode: 400,
      message: error.errors[0].message
    })
  }
})

XSS-Schutz durch HTML-Escaping

// Nutze v-text statt v-html für User-Content
<template>
  <!-- ❌ Gefährlich -->
  <div v-html='userContent'></div>
  
  <!-- ✅ Sicher -->
  <div v-text='userContent'></div>
  
  <!-- ✅ Oder mit Mustache Syntax -->
  <div>{{ userContent }}</div>
</template>

5. SQL Injection verhindern

Verwende IMMER Prepared Statements oder ORMs:

// ❌ Gefährlich - SQL Injection möglich
const userId = req.query.id
const query = `SELECT * FROM users WHERE id = ${userId}`
const user = await db.query(query)

// ✅ Sicher - Prepared Statement
const userId = req.query.id
const user = await db.query(
  'SELECT * FROM users WHERE id = ?',
  [userId]
)

// ✅ Noch besser - ORM nutzen (z.B. Prisma)
const user = await prisma.user.findUnique({
  where: { id: userId }
})

6. Rate Limiting

Schütze deine API vor Brute-Force-Angriffen:

// server/middleware/rate-limit.ts
import { RateLimiter } from 'limiter'

const limiters = new Map()

export default defineEventHandler((event) => {
  const ip = getRequestIP(event)
  
  if (!limiters.has(ip)) {
    // 10 Requests pro Minute
    limiters.set(ip, new RateLimiter({
      tokensPerInterval: 10,
      interval: 'minute'
    }))
  }
  
  const limiter = limiters.get(ip)
  
  if (!limiter.tryRemoveTokens(1)) {
    throw createError({
      statusCode: 429,
      message: 'Zu viele Anfragen. Bitte versuche es später erneut.'
    })
  }
})

7. Environment-Variablen sicher handhaben

Was gehört in .env?

  • ✅ API-Keys
  • ✅ Datenbank-Credentials
  • ✅ JWT-Secrets
  • ✅ Stripe Secret Keys

Was gehört NICHT in Git?

  • ❌ .env Datei
  • ❌ API-Keys im Code
  • ❌ Passwörter
  • ❌ Private Keys
# .gitignore
.env
.env.local
.env.*.local

# Stattdessen: .env.example committen
# .env.example
DATABASE_URL=postgresql://user:password@localhost:5432/db
JWT_SECRET=your-secret-here
STRIPE_SECRET_KEY=sk_test_...

8. CORS richtig konfigurieren

// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    routeRules: {
      '/api/**': {
        cors: true,
        headers: {
          'Access-Control-Allow-Origin': process.env.ALLOWED_ORIGIN || '*',
          'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
          'Access-Control-Allow-Headers': 'Content-Type, Authorization',
          'Access-Control-Allow-Credentials': 'true'
        }
      }
    }
  }
})

9. Datenschutz-Grundverordnung (DSGVO)

Wichtige Punkte für DSGVO-Compliance:

Datenminimierung

Sammle nur die Daten, die du wirklich brauchst.

Transparenz

Informiere Nutzer, welche Daten du sammelst und warum.

Recht auf Löschung

Implementiere eine Möglichkeit für Nutzer, ihre Daten zu löschen.

Datenexport

Ermögliche Nutzern, ihre Daten herunterzuladen.

10. Security Checklist

  • ✅ HTTPS überall aktiviert
  • ✅ Security Headers konfiguriert
  • ✅ Input-Validierung auf Server-Seite
  • ✅ SQL Injection-Schutz (Prepared Statements/ORM)
  • ✅ XSS-Schutz (keine v-html für User-Content)
  • ✅ CSRF-Schutz aktiviert
  • ✅ Passwörter gehasht (bcrypt/argon2)
  • ✅ JWT-Tokens in HTTP-only Cookies
  • ✅ Rate Limiting implementiert
  • ✅ CORS richtig konfiguriert
  • ✅ Environment-Variablen für Secrets
  • ✅ Keine Secrets im Git Repository
  • ✅ Datenschutzerklärung vorhanden
  • ✅ Logging und Monitoring aktiv
  • ✅ Regelmäßige Dependency-Updates

Fazit

Sicherheit und Datenschutz sind keine optionalen Features, sondern essentiell für jede moderne Webanwendung. Mit den richtigen Tools und Best Practices kannst du eine sichere App bauen, die die Privatsphäre deiner Nutzer respektiert. Vercel Analytics ist ein gutes Beispiel dafür, wie man nützliche Analytics ohne Cookies und Cookie-Banner realisieren kann.

Denke daran: Sicherheit ist ein fortlaufender Prozess. Halte deine Dependencies aktuell, folge Security Best Practices und sei immer auf dem neuesten Stand der Security-Trends.