Initial commit from template

This commit is contained in:
Lumina
2025-12-23 04:19:57 +01:00
commit b3d8fe8dfe
76 changed files with 10491 additions and 0 deletions

View File

@@ -0,0 +1,148 @@
---
name: semgrep-security
description: Security Scanner mit Semgrep. WICHTIG - Dieser Skill wird automatisch bei JEDER Code-Implementierung aktiviert. Scannt neuen und geaenderten Code auf Sicherheitsluecken, Vulnerabilities und Best Practice Verstoesse. Aktiviert bei Begriffen wie "implementieren", "code schreiben", "feature erstellen", "komponente bauen", "funktion erstellen", "api route", "fertig", "done", "commit", "security", "scan", "vulnerabilities", "sicherheit".
---
# Semgrep Security Scanner
Dieser Skill scannt automatisch Code auf Sicherheitsprobleme nach jeder Implementierung.
## WICHTIG: Automatische Ausfuehrung
Nach JEDER Code-Implementierung fuehre folgende Schritte aus:
1. **Semgrep installieren** (falls nicht vorhanden)
2. **Geaenderte Dateien scannen**
3. **Probleme fixen oder reporten**
## Scripts
### Installation pruefen und durchfuehren
```bash
bash install-semgrep.sh
```
### Scan durchfuehren
```bash
# Alle Dateien scannen
bash scan.sh
# Nur bestimmte Dateien scannen
bash scan.sh app/api/users/route.ts components/UserForm.tsx
```
### Autofix anwenden
```bash
bash autofix.sh
```
## Workflow nach Implementierung
### 1. Installation sicherstellen
```bash
# Pruefen ob semgrep installiert ist
which semgrep || bash install-semgrep.sh
```
### 2. Geaenderte Dateien ermitteln
```bash
# Untracked und modified files
git status --porcelain | grep -E '^\?\?|^ M|^M' | cut -c4-
```
### 3. Security Scan ausfuehren
```bash
# Mit Auto-Config (empfohlen)
semgrep --config=auto --json .
# Fuer TypeScript/React spezifisch
semgrep --config=p/typescript --config=p/react --json .
# OWASP Top 10
semgrep --config=p/owasp-top-ten --json .
```
### 4. Ergebnisse analysieren und fixen
```bash
# Mit Autofix
semgrep --config=auto --autofix .
# Nur Report ohne Fix
semgrep --config=auto --sarif -o results.sarif .
```
## Haeufige Security Issues und Fixes
### SQL Injection
```typescript
// SCHLECHT
const query = `SELECT * FROM users WHERE id = ${userId}`;
// GUT
const { data } = await supabase.from('users').select('*').eq('id', userId);
```
### XSS (Cross-Site Scripting)
```typescript
// SCHLECHT
<div dangerouslySetInnerHTML={{ __html: userInput }} />
// GUT
<div>{sanitize(userInput)}</div>
```
### Hardcoded Secrets
```typescript
// SCHLECHT
const apiKey = "sk-1234567890";
// GUT
const apiKey = process.env.API_KEY;
```
### Insecure Direct Object Reference
```typescript
// SCHLECHT - Keine Auth-Pruefung
const user = await getUser(req.query.id);
// GUT - Mit RLS oder Auth-Check
const { data: { user } } = await supabase.auth.getUser();
const profile = await supabase.from('profiles').select().eq('user_id', user.id);
```
## Report Format
Nach jedem Scan zeige:
```markdown
## Security Scan Ergebnisse
**Score**: 85/100
| Severity | Count |
|----------|-------|
| Critical | 0 |
| High | 1 |
| Medium | 3 |
| Low | 5 |
### Gefundene Issues
1. **[HIGH] Potential XSS** in `components/Comment.tsx:42`
- Problem: Unescaped user input
- Fix: Verwende DOMPurify oder sanitize-html
### Automatisch gefixt
- 2 Issues wurden automatisch behoben
### Naechste Schritte
- [ ] Issue #1 manuell pruefen
```
## Best Practices
1. **Immer scannen** nach Code-Aenderungen
2. **Autofix nutzen** fuer einfache Issues
3. **Kritische Issues** sofort beheben
4. **False Positives** in `.semgrepignore` ausschliessen
5. **CI/CD Integration** fuer automatische Scans

View File

@@ -0,0 +1,54 @@
#!/bin/bash
# Fuehrt Semgrep Autofix durch
set -e
# Farben
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Pruefen ob Semgrep installiert ist
if ! command -v semgrep &> /dev/null; then
echo -e "${YELLOW}Semgrep nicht gefunden. Installiere...${NC}"
bash "$(dirname "$0")/install-semgrep.sh"
fi
# Argumente
if [ $# -gt 0 ]; then
SCAN_TARGET="$@"
else
SCAN_TARGET="."
fi
echo "Starte Semgrep Autofix..."
echo "========================="
echo ""
# Autofix durchfuehren
# Nur Rules mit Autofix-Support
semgrep \
--config=auto \
--autofix \
--dryrun \
$SCAN_TARGET 2>&1 | head -50
echo ""
read -p "Fixes anwenden? (y/n) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Wende Fixes an..."
semgrep \
--config=auto \
--autofix \
$SCAN_TARGET
echo ""
echo -e "${GREEN}Fixes angewendet!${NC}"
echo ""
echo "Bitte pruefen Sie die Aenderungen:"
echo " git diff"
else
echo "Autofix abgebrochen."
fi

View File

@@ -0,0 +1,86 @@
#!/bin/bash
# Installiert Semgrep basierend auf dem Betriebssystem
set -e
echo "Pruefe Semgrep Installation..."
# Pruefen ob bereits installiert
if command -v semgrep &> /dev/null; then
echo "Semgrep ist bereits installiert: $(semgrep --version)"
exit 0
fi
echo "Semgrep nicht gefunden. Starte Installation..."
# OS erkennen
OS_TYPE=$(uname -s)
case "$OS_TYPE" in
"Darwin")
# macOS
echo "macOS erkannt - nutze Homebrew"
if command -v brew &> /dev/null; then
brew install semgrep
else
echo "Homebrew nicht gefunden - nutze pip3"
pip3 install semgrep
fi
;;
"Linux")
echo "Linux erkannt"
# Versuche verschiedene Paketmanager
if command -v apt-get &> /dev/null; then
echo "Nutze apt-get..."
# Semgrep via Python da apt Version oft veraltet
pip3 install semgrep
elif command -v apk &> /dev/null; then
echo "Alpine erkannt - nutze pip3"
apk add --no-cache python3 py3-pip
pip3 install semgrep
elif command -v yum &> /dev/null; then
echo "RHEL/CentOS erkannt - nutze pip3"
pip3 install semgrep
else
echo "Nutze pip3 als Fallback"
pip3 install semgrep
fi
;;
"MINGW"*|"MSYS"*|"CYGWIN"*)
# Windows
echo "Windows erkannt"
if command -v choco &> /dev/null; then
choco install semgrep -y
elif command -v pip3 &> /dev/null; then
pip3 install semgrep
elif command -v pip &> /dev/null; then
pip install semgrep
else
echo "Bitte installiere Python und pip: https://www.python.org/downloads/"
exit 1
fi
;;
*)
echo "Unbekanntes OS: $OS_TYPE - nutze pip3"
pip3 install semgrep
;;
esac
# Verifizieren
if command -v semgrep &> /dev/null; then
echo ""
echo "Installation erfolgreich!"
semgrep --version
else
echo ""
echo "Installation fehlgeschlagen."
echo "Bitte manuell installieren: https://semgrep.dev/docs/getting-started/"
exit 1
fi

View File

@@ -0,0 +1,91 @@
# Custom Semgrep Rules fuer Next.js Security
rules:
# Verhindere dangerouslySetInnerHTML ohne Sanitization
- id: next-xss-dangerous-html
patterns:
- pattern: dangerouslySetInnerHTML={{ __html: $VAR }}
- pattern-not: dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize($VAR) }}
- pattern-not: dangerouslySetInnerHTML={{ __html: sanitize($VAR) }}
message: "XSS Risiko: Verwende DOMPurify.sanitize() bevor du dangerouslySetInnerHTML nutzt"
severity: ERROR
languages: [typescript, javascript]
# Verhindere hardcoded API Keys
- id: next-hardcoded-api-key
patterns:
- pattern-either:
- pattern: |
$KEY = "sk-..."
- pattern: |
$KEY = "pk_..."
- pattern: |
apiKey: "..."
- pattern: |
api_key = "..."
message: "Hardcoded API Key gefunden. Verwende Environment Variables."
severity: ERROR
languages: [typescript, javascript]
# Verhindere ungeschuetzte API Routes
- id: next-unprotected-api-route
patterns:
- pattern: |
export async function $METHOD(request: NextRequest) {
...
$DB.$OPERATION(...)
...
}
- pattern-not: |
export async function $METHOD(request: NextRequest) {
...
auth.getUser()
...
}
- pattern-not: |
export async function $METHOD(request: NextRequest) {
...
getSession()
...
}
message: "API Route ohne Authentication. Fuege Auth-Check hinzu."
severity: WARNING
languages: [typescript]
paths:
include:
- "app/api/**"
# Verhindere Secrets in Client Components
- id: next-secret-in-client
patterns:
- pattern-inside: |
"use client"
...
- pattern-either:
- pattern: process.env.SUPABASE_SERVICE_ROLE_KEY
- pattern: process.env.DATABASE_URL
- pattern: process.env.$SECRET_KEY
message: "Server-only Secret in Client Component. Verschiebe in Server Component oder API Route."
severity: ERROR
languages: [typescript, javascript]
# Verhindere eval und new Function
- id: next-no-eval
patterns:
- pattern-either:
- pattern: eval(...)
- pattern: new Function(...)
message: "eval() und new Function() sind Sicherheitsrisiken. Finde eine Alternative."
severity: ERROR
languages: [typescript, javascript]
# Supabase RLS Check
- id: supabase-rls-bypass
patterns:
- pattern: supabaseAdmin.from($TABLE)
- pattern-not-inside: |
// RLS bypassed intentionally
...
message: "supabaseAdmin umgeht RLS. Stelle sicher dass dies beabsichtigt ist."
severity: WARNING
languages: [typescript, javascript]

View File

@@ -0,0 +1,29 @@
#!/bin/bash
# Scannt nur geaenderte Dateien (staged + unstaged)
set -e
# Farben
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo "Ermittle geaenderte Dateien..."
# Geaenderte Dateien ermitteln (TypeScript/JavaScript)
CHANGED_FILES=$(git status --porcelain 2>/dev/null | \
grep -E '\.(ts|tsx|js|jsx)$' | \
sed 's/^...//' | \
tr '\n' ' ')
if [ -z "$CHANGED_FILES" ]; then
echo -e "${GREEN}Keine geaenderten TypeScript/JavaScript Dateien gefunden.${NC}"
exit 0
fi
echo "Geaenderte Dateien:"
echo "$CHANGED_FILES" | tr ' ' '\n' | grep -v '^$'
echo ""
# Scan durchfuehren
bash "$(dirname "$0")/scan.sh" $CHANGED_FILES

View File

@@ -0,0 +1,89 @@
#!/bin/bash
# Fuehrt Semgrep Security Scan durch
set -e
# Farben fuer Output
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
# Pruefen ob Semgrep installiert ist
if ! command -v semgrep &> /dev/null; then
echo -e "${YELLOW}Semgrep nicht gefunden. Installiere...${NC}"
bash "$(dirname "$0")/install-semgrep.sh"
fi
# Argumente: spezifische Dateien oder alles scannen
if [ $# -gt 0 ]; then
SCAN_TARGET="$@"
echo "Scanne spezifische Dateien: $SCAN_TARGET"
else
SCAN_TARGET="."
echo "Scanne gesamtes Projekt..."
fi
# Temporaere Datei fuer JSON Output
RESULT_FILE=$(mktemp)
# Scan durchfuehren
echo ""
echo "Starte Security Scan..."
echo "========================"
semgrep \
--config=auto \
--config=p/security-audit \
--config=p/typescript \
--json \
--output="$RESULT_FILE" \
$SCAN_TARGET 2>/dev/null || true
# Ergebnisse parsen
if [ -f "$RESULT_FILE" ]; then
# Anzahl der Findings zaehlen
TOTAL=$(jq '.results | length' "$RESULT_FILE" 2>/dev/null || echo "0")
ERRORS=$(jq '[.results[] | select(.extra.severity == "ERROR")] | length' "$RESULT_FILE" 2>/dev/null || echo "0")
WARNINGS=$(jq '[.results[] | select(.extra.severity == "WARNING")] | length' "$RESULT_FILE" 2>/dev/null || echo "0")
INFO=$(jq '[.results[] | select(.extra.severity == "INFO")] | length' "$RESULT_FILE" 2>/dev/null || echo "0")
echo ""
echo "========================"
echo "Scan Ergebnisse"
echo "========================"
echo ""
if [ "$TOTAL" -eq 0 ]; then
echo -e "${GREEN}Keine Sicherheitsprobleme gefunden!${NC}"
else
echo -e "Gefunden: ${RED}$ERRORS Critical/High${NC}, ${YELLOW}$WARNINGS Medium${NC}, $INFO Low"
echo ""
# Details ausgeben
echo "Details:"
echo "--------"
jq -r '.results[] | "[\(.extra.severity)] \(.check_id)\n File: \(.path):\(.start.line)\n Message: \(.extra.message)\n"' "$RESULT_FILE" 2>/dev/null || true
fi
# Score berechnen
SCORE=$((100 - (ERRORS * 10) - (WARNINGS * 3) - (INFO * 1)))
if [ $SCORE -lt 0 ]; then SCORE=0; fi
echo ""
echo "========================"
echo -e "Security Score: ${GREEN}$SCORE/100${NC}"
echo "========================"
# Cleanup
rm -f "$RESULT_FILE"
# Exit mit Fehler wenn kritische Issues
if [ "$ERRORS" -gt 0 ]; then
echo ""
echo -e "${RED}WARNUNG: Es wurden kritische Sicherheitsprobleme gefunden!${NC}"
exit 1
fi
else
echo -e "${GREEN}Scan abgeschlossen - keine Ergebnisdatei erstellt${NC}"
fi