diff --git a/RESET_DATABASE.sh b/RESET_DATABASE.sh new file mode 100755 index 0000000..7f1ad22 --- /dev/null +++ b/RESET_DATABASE.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +echo "🗑️ Stopping containers..." +sudo docker compose down + +echo "🗑️ Removing PostgreSQL volume..." +sudo docker volume rm medienkompetenz-lernplattform_postgres_data + +echo "🚀 Starting containers with fresh database..." +sudo docker compose up -d + +echo "⏳ Waiting for database to initialize (20 seconds)..." +sleep 20 + +echo "✅ Database has been reset and reseeded!" +echo "" +echo "Verify with:" +echo " sudo docker compose exec database psql -U lernplattform_user -d lernplattform -c \"SELECT lesson_key, title FROM lessons;\"" +echo "" +echo "Check logs:" +echo " sudo docker compose logs database" +echo " sudo docker compose logs backend" diff --git a/XSS_ENHANCEMENTS.md b/XSS_ENHANCEMENTS.md new file mode 100644 index 0000000..d30775a --- /dev/null +++ b/XSS_ENHANCEMENTS.md @@ -0,0 +1,161 @@ +# XSS Lesson Enhancements - Implementation Summary + +## Features Implemented + +### Backend (✅ Complete) +**File:** `/backend/lessons/modules/xss-comprehensive/index.js` + +1. **Variant Discovery Tracking** + - Tracks 9 unique XSS variants per participant + - Returns progress: `{ discovered: X, total: 9, remaining: Y }` + - Variants: Script Tag, Event Handlers (quoted/unquoted), JavaScript Protocol, IFrame, Image Error, SVG Onload, Object, Embed + +2. **Timer System** + - 15-minute countdown per interactive step + - `startStepTimer()` - Initializes timer when step starts + - `isTimeExpired()` - Checks if time limit exceeded + - `getRemainingTime()` - Returns milliseconds remaining + - `canEarnPoints: false` after time expires + +3. **Hint System** + - Progressive hints (4 levels per step) + - 5 points deducted per hint requested + - `getHint(participantId, stepId, level)` returns hint text and penalty + - Tracks hints used per participant per step + +4. **Free Hints** + - Provided in `getInteractiveData()` without penalty + - General guidance hints displayed at start + +### Frontend (🚧 Needs Implementation) + +#### Components to Update: +1. **XSSDeeplinkDemo.jsx** - Reflected XSS demo +2. **ForumScriptDemo.jsx** - Stored XSS demo +3. **LessonView.jsx** - Lock previous button after interactive steps + +#### Required Features: + +**1. Remove Example Buttons** +- ❌ Remove `examples.map()` button rendering +- ❌ Remove `loadExample()` function +- Students must discover payloads themselves + +**2. Add Progress Tracker** +```jsx +
+

🎯 Fortschritt

+

{progress.discovered} von {progress.total} Varianten entdeckt

+ +
+``` + +**3. Add Timer Display** +```jsx +const [remainingTime, setRemainingTime] = useState(900000); // 15 min + +useEffect(() => { + const timer = setInterval(() => { + setRemainingTime(prev => Math.max(0, prev - 1000)); + }, 1000); + return () => clearInterval(timer); +}, []); + +
+ ⏱️ Verbleibende Zeit: {formatTime(remainingTime)} + {remainingTime === 0 && ⚠️ Keine Punkte mehr verfügbar} +
+``` + +**4. Add Free Hints Display** +```jsx +
+

💡 Hinweise (kostenlos)

+ {freeHints.map((hint, i) => ( +
  • {hint}
  • + ))} +
    +``` + +**5. Add Hint Request Button** +```jsx + +{currentHint && ( +
    +

    {currentHint.hint}

    + Hinweise verwendet: {currentHint.hintsUsed} | Abzug: {currentHint.totalPointsDeducted} Punkte +
    +)} +``` + +**6. Start Timer on Mount** +```jsx +useEffect(() => { + participantAPI.executeLessonAction(eventLessonId, 'start-timer', { + stepId: 'xss-demo' + }); +}, []); +``` + +**7. Lock Previous Button (LessonView.jsx)** +```jsx +const [completedInteractive, setCompletedInteractive] = useState(false); + +// After interactive step +if (currentStep.type === 'interactive' && !completedInteractive) { + setCompletedInteractive(true); +} + + +``` + +## API Endpoints to Add + +The backend module methods need to be exposed via `executeLessonAction`: + +### In lesson controller (already supports executeLessonAction): +```javascript +// Actions to handle: +- 'start-timer' → module.startStepTimer(participantId, stepId) +- 'get-hint' → module.getHint(participantId, stepId) +- 'test-xss' → module.testXSSPayload(participantId, payload, stepId) +- 'add-comment' → module.addComment(participantId, author, content, stepId) +``` + +## Testing Steps + +1. ✅ Backend module created with all tracking +2. ⏳ Rebuild backend container +3. ⏳ Update XSSDeeplinkDemo.jsx +4. ⏳ Update ForumScriptDemo.jsx +5. ⏳ Update LessonView.jsx +6. ⏳ Rebuild frontend container +7. ⏳ Test in browser: + - Timer counts down + - Progress updates when discovering variants + - Hints work with point deduction + - Free hints visible + - Previous button locks after interactive step + +## File Locations + +- Backend: `/backend/lessons/modules/xss-comprehensive/index.js` ✅ +- Frontend Demos: + - `/frontend/src/components/lessons/InteractiveContent/XSSDeeplinkDemo.jsx` ⏳ + - `/frontend/src/components/lessons/InteractiveContent/ForumScriptDemo.jsx` ⏳ +- Lesson View: `/frontend/src/pages/LessonView.jsx` ⏳ + +## Next Steps + +1. Update controller to expose hint and timer endpoints +2. Implement frontend components with new UI +3. Test complete workflow +4. Verify point deductions work correctly +5. Confirm timer enforcement diff --git a/XSS_LESSON_MERGE.md b/XSS_LESSON_MERGE.md new file mode 100644 index 0000000..1388f93 --- /dev/null +++ b/XSS_LESSON_MERGE.md @@ -0,0 +1,128 @@ +# XSS Lessons Merge - Summary + +## Changes Made + +Successfully combined the two XSS lessons into a single comprehensive lesson: + +### New Files Created + +1. **Backend Config:** + - `/backend/lessons/configs/xss-comprehensive.yaml` + - Combines content from both `xss-deeplink-demo.yaml` and `script-injection-forum.yaml` + - Duration: 35 minutes (combined from 20 + 25) + - Total points: 100 (distributed across 4 questions) + +2. **Backend Module:** + - `/backend/lessons/modules/xss-comprehensive/index.js` + - Merges functionality from both XSS modules + - Handles both interactive components: + - `testXSSPayload()` for reflected XSS demo (XSSDeeplinkDemo) + - `addComment()` for stored XSS demo (ForumScriptDemo) + +### Lesson Structure + +The combined lesson flows as follows: + +1. **Introduction** - What is XSS? (covers both reflected and stored) +2. **Reflected XSS** - URL parameter injection explanation +3. **Interactive Demo 1** - XSSDeeplinkDemo (reflected XSS) +4. **Question 1** - Multiple choice (25 pts): Identify reflected XSS payloads +5. **Stored XSS** - Persistent attacks explanation +6. **Real-World Examples** - Samy Worm, TweetDeck, eBay, British Airways +7. **Interactive Demo 2** - ForumScriptDemo (stored XSS) +8. **Question 2** - Multiple choice (25 pts): Identify stored XSS payloads +9. **Attack Vectors** - Common XSS techniques +10. **Question 3** - Single choice (30 pts): Why stored XSS is more dangerous +11. **Prevention** - Defense-in-depth approach +12. **Question 4** - Single choice (20 pts): Most effective prevention method + +### Content Removed + +✅ **Free text questions removed:** +- Old Question 3 from xss-deeplink-demo (30 pts) +- Old Question 3 from script-injection-forum (30 pts) + +✅ **Developer-specific content removed:** +- Framework security features (React, Angular, Vue) +- Dangerous functions to avoid (dangerouslySetInnerHTML, bypassSecurityTrust, v-html) +- Framework-specific implementation details + +### Content Retained + +✅ **User-focused prevention techniques:** +- Output encoding (HTML, JavaScript, URL, CSS contexts) +- Content Security Policy (CSP) +- Input validation +- HTTPOnly and Secure cookies +- Web Application Firewall (WAF) +- Regular security audits + +## Old Files + +The following files are now **deprecated** but kept for reference: + +- `/backend/lessons/configs/xss-deeplink-demo.yaml` (deprecated) +- `/backend/lessons/configs/script-injection-forum.yaml` (deprecated) +- `/backend/lessons/modules/xss-deeplink-demo/index.js` (deprecated) +- `/backend/lessons/modules/script-injection-forum/index.js` (deprecated) + +**Note:** The frontend components are still used and should NOT be removed: +- `/frontend/src/components/lessons/InteractiveContent/XSSDeeplinkDemo.jsx` (ACTIVE) +- `/frontend/src/components/lessons/InteractiveContent/ForumScriptDemo.jsx` (ACTIVE) + +## How to Use the New Lesson + +### 1. Add to Database + +If you have a seed script, add the new lesson: + +```javascript +// In your seed script +const xssComprehensive = await Lesson.create({ + lessonKey: 'xss-comprehensive', + title: 'Cross-Site Scripting (XSS) - Reflected & Stored Angriffe', + description: 'Lernen Sie, wie XSS-Angriffe durch URL-Manipulation und benutzergenerierte Inhalte funktionieren und wie man sie erkennt', + difficultyLevel: 'intermediate', + estimatedDuration: 35, + configPath: 'backend/lessons/configs/xss-comprehensive.yaml', + modulePath: 'backend/lessons/modules/xss-comprehensive' +}); +``` + +### 2. Remove Old Lessons (Optional) + +If desired, you can remove the old separate XSS lessons from the database: + +```sql +-- Mark old lessons as inactive or delete them +UPDATE lessons SET is_active = false +WHERE lesson_key IN ('xss-deeplink-demo', 'script-injection-forum'); +``` + +### 3. Assign to Events + +The new comprehensive lesson can now be assigned to events just like any other lesson. + +## Testing Checklist + +- [ ] Backend module loads correctly +- [ ] XSSDeeplinkDemo interactive component works +- [ ] ForumScriptDemo interactive component works +- [ ] All 4 questions validate correctly +- [ ] Scoring totals to 100 points +- [ ] 70% passing score works (70 out of 100) +- [ ] No developer-specific content visible to users +- [ ] No free text questions present +- [ ] All content is in German + +## Point Distribution + +| Question | Type | Points | Topic | +|----------|------|--------|-------| +| Q1 | Multiple Choice | 25 | Identify reflected XSS payloads | +| Q2 | Multiple Choice | 25 | Identify stored XSS payloads | +| Q3 | Single Choice | 30 | Why stored XSS is more dangerous | +| Q4 | Single Choice | 20 | Most effective prevention method | +| **Total** | | **100** | | + +**Passing Score:** 70 points (70%) diff --git a/backend/lessons/configs/browser-in-browser-attack.yaml b/backend/lessons/configs/browser-in-browser-attack.yaml index e3cec24..f075649 100644 --- a/backend/lessons/configs/browser-in-browser-attack.yaml +++ b/backend/lessons/configs/browser-in-browser-attack.yaml @@ -1,6 +1,6 @@ lessonKey: "browser-in-browser-attack" -title: "Browser-in-the-Browser (BitB) Attack" -description: "Learn to identify sophisticated phishing attacks that mimic legitimate browser windows" +title: "Browser-in-the-Browser (BitB) Angriff" +description: "Lernen Sie, ausgeklügelte Phishing-Angriffe zu erkennen, die legitime Browserfenster nachahmen" difficultyLevel: "advanced" estimatedDuration: 25 module: "browser-in-browser-attack" @@ -8,167 +8,153 @@ module: "browser-in-browser-attack" steps: - id: "intro" type: "content" - title: "What is Browser-in-the-Browser?" + title: "Was ist Browser-in-the-Browser?" content: | - Browser-in-the-Browser (BitB) is an advanced phishing technique that creates a fake browser window inside a webpage. It's designed to trick users into thinking they're interacting with a legitimate OAuth/SSO login popup. + Browser-in-the-Browser (BitB) ist eine fortgeschrittene Phishing-Technik, die ein gefälschtes Browserfenster innerhalb einer Webseite erstellt. Sie ist darauf ausgelegt, Benutzer dazu zu bringen, zu glauben, sie würden mit einem legitimen OAuth/SSO-Login-Popup interagieren. - Why it's dangerous: - • Looks identical to real browser popup windows - • Shows a fake address bar with HTTPS lock icon - • Mimics trusted services (Google, Microsoft, Facebook) - • Can steal credentials even from security-aware users - • Bypasses traditional phishing detection + Warum es gefährlich ist: + • Sieht identisch aus wie echte Browser-Popup-Fenster + • Zeigt eine gefälschte Adressleiste mit HTTPS-Schloss-Symbol + • Imitiert vertrauenswürdige Dienste (Google, Microsoft, Facebook) + • Kann Anmeldedaten auch von sicherheitsbewussten Benutzern stehlen + • Umgeht traditionelle Phishing-Erkennung - This attack gained prominence in 2022 and has been used in targeted attacks against organizations. + Dieser Angriff wurde 2022 bekannt und wurde in gezielten Angriffen gegen Organisationen eingesetzt. - id: "how-it-works" type: "content" - title: "How the Attack Works" + title: "Wie der Angriff funktioniert" content: | - Traditional OAuth Flow: - 1. User clicks "Sign in with Google" on a website - 2. Browser opens a REAL popup to google.com - 3. User enters credentials on Google's actual site - 4. Google redirects back with authentication token + Traditioneller OAuth-Ablauf: + 1. Benutzer klickt auf "Mit Google anmelden" auf einer Website + 2. Browser öffnet ein ECHTES Popup zu google.com + 3. Benutzer gibt Anmeldedaten auf der tatsächlichen Google-Seite ein + 4. Google leitet mit Authentifizierungstoken zurück - BitB Attack Flow: - 1. User clicks "Sign in with Google" on malicious site - 2. Site creates a FAKE popup using HTML/CSS/JavaScript - 3. Fake popup shows fake address bar displaying "accounts.google.com" - 4. User enters credentials on attacker's fake page - 5. Attacker captures credentials and simulates success + BitB-Angriff-Ablauf: + 1. Benutzer klickt auf "Mit Google anmelden" auf bösartiger Seite + 2. Seite erstellt ein GEFÄLSCHTES Popup mit HTML/CSS/JavaScript + 3. Gefälschtes Popup zeigt gefälschte Adressleiste mit "accounts.google.com" + 4. Benutzer gibt Anmeldedaten auf der gefälschten Seite des Angreifers ein + 5. Angreifer erfasst Anmeldedaten und simuliert Erfolg - The entire "browser window" is actually just HTML elements styled to look like a browser! + Das gesamte "Browserfenster" ist eigentlich nur HTML-Elemente, die so gestaltet sind, dass sie wie ein Browser aussehen! - id: "bitb-demo" type: "interactive" - title: "Interactive BitB Demo" + title: "Interaktive BitB-Demo" interactiveComponent: "BitBDemo" content: | - Below you'll see two login scenarios. One uses a REAL browser popup (secure), and one uses a BitB attack (malicious). + Unten sehen Sie zwei Login-Szenarien. Eines verwendet ein ECHTES Browser-Popup (sicher), und eines verwendet einen BitB-Angriff (bösartig). - Can you identify the fake? Pay close attention to the details! + Können Sie die Fälschung erkennen? Achten Sie genau auf die Details! - id: "question-1" type: "question" questionType: "multiple_choice" - question: "What are the key indicators that can help identify a Browser-in-the-Browser attack?" + question: "Was sind die wichtigsten Indikatoren, die helfen können, einen Browser-in-the-Browser-Angriff zu erkennen?" options: - id: "https-lock" - text: "The presence of HTTPS and a lock icon in the address bar" + text: "Das Vorhandensein von HTTPS und einem Schloss-Symbol in der Adressleiste" isCorrect: false points: 0 - id: "window-behavior" - text: "The popup window cannot be dragged outside the main browser window" + text: "Das Popup-Fenster kann nicht außerhalb des Hauptbrowserfensters gezogen werden" isCorrect: true points: 20 - id: "inspect-element" - text: "Right-clicking allows you to 'Inspect Element' on the address bar" + text: "Rechtsklick ermöglicht 'Element untersuchen' auf der Adressleiste" isCorrect: true points: 20 - id: "domain-name" - text: "The domain name shown in the address bar" + text: "Der in der Adressleiste angezeigte Domainname" isCorrect: false points: 0 maxPoints: 40 feedback: - correct: "Excellent! Real browser windows can be moved anywhere and their UI cannot be inspected as HTML elements." - incorrect: "Think about what differentiates a real browser window from HTML/CSS elements on a webpage. The lock icon and domain can both be faked!" + correct: "Ausgezeichnet! Echte Browserfenster können überall hin bewegt werden und ihre Benutzeroberfläche kann nicht als HTML-Elemente untersucht werden." + incorrect: "Denken Sie darüber nach, was ein echtes Browserfenster von HTML/CSS-Elementen auf einer Webseite unterscheidet. Das Schloss-Symbol und die Domain können beide gefälscht werden!" - id: "detection-techniques" type: "content" - title: "Detecting BitB Attacks" + title: "BitB-Angriffe erkennen" content: | - How to spot a Browser-in-the-Browser attack: + Wie man einen Browser-in-the-Browser-Angriff erkennt: - 1. **Try to Drag the Window** - • Real popups can be dragged outside the browser - • Fake popups are trapped within the main window + 1. **Versuchen Sie, das Fenster zu ziehen** + • Echte Popups können außerhalb des Browsers gezogen werden + • Gefälschte Popups sind im Hauptfenster gefangen - 2. **Check if Address Bar is Selectable** - • Real address bars: text is selectable - • Fake address bars: usually just an image or styled div + 2. **Prüfen Sie, ob die Adressleiste auswählbar ist** + • Echte Adressleisten: Text ist auswählbar + • Gefälschte Adressleisten: normalerweise nur ein Bild oder gestyltes div - 3. **Right-Click the Address Bar** - • Real browser: no "Inspect Element" option - • Fake browser: shows HTML inspection menu + 3. **Klicken Sie mit der rechten Maustaste auf die Adressleiste** + • Echter Browser: keine "Element untersuchen"-Option + • Gefälschter Browser: zeigt HTML-Inspektionsmenü - 4. **Look for Pixel-Perfect Details** - • Fake windows may have slight styling differences - • Shadow effects, fonts, or spacing might be off + 4. **Achten Sie auf pixelgenaue Details** + • Gefälschte Fenster können leichte Styling-Unterschiede haben + • Schatteneffekte, Schriftarten oder Abstände könnten abweichen - 5. **Check Your Browser's Task Bar** - • Real popups appear as separate windows in taskbar - • Fake popups don't create new window entries + 5. **Überprüfen Sie die Taskleiste Ihres Browsers** + • Echte Popups erscheinen als separate Fenster in der Taskleiste + • Gefälschte Popups erstellen keine neuen Fenstereinträge - 6. **Use Browser Extensions** - • Some extensions can detect fake browser UI + 6. **Verwenden Sie Browser-Erweiterungen** + • Einige Erweiterungen können gefälschte Browser-Benutzeroberflächen erkennen - id: "question-2" type: "question" questionType: "single_choice" - question: "A website asks you to 'Sign in with Microsoft' and a popup appears. What is the SAFEST approach?" + question: "Eine Website fordert Sie auf, sich 'Mit Microsoft anmelden' und ein Popup erscheint. Was ist der SICHERSTE Ansatz?" options: - id: "trust-https" - text: "Check for HTTPS in the address bar and proceed if present" + text: "In der Adressleiste nach HTTPS suchen und fortfahren, wenn vorhanden" isCorrect: false points: 0 - id: "test-window" - text: "Try to drag the popup outside the browser window to verify it's real" + text: "Versuchen, das Popup außerhalb des Browserfensters zu ziehen, um zu überprüfen, ob es echt ist" isCorrect: true points: 35 - id: "check-domain" - text: "Carefully read the domain name to ensure it's Microsoft's real domain" + text: "Den Domainnamen sorgfältig lesen, um sicherzustellen, dass es Microsofts echte Domain ist" isCorrect: false points: 0 - id: "close-and-manual" - text: "Close the popup and manually navigate to Microsoft's site" + text: "Das Popup schließen und manuell zur Microsoft-Seite navigieren" isCorrect: false points: 10 maxPoints: 35 feedback: - correct: "Perfect! Testing if the window can be dragged outside the browser is the most reliable quick check. Though manually navigating is also very safe!" - incorrect: "While checking the domain helps, it can be faked in a BitB attack. The physical behavior of the window (can it be dragged out?) reveals the truth." + correct: "Perfekt! Zu testen, ob das Fenster außerhalb des Browsers gezogen werden kann, ist die zuverlässigste Schnellprüfung. Obwohl manuelle Navigation auch sehr sicher ist!" + incorrect: "Während die Überprüfung der Domain hilft, kann sie bei einem BitB-Angriff gefälscht werden. Das physische Verhalten des Fensters (kann es herausgezogen werden?) offenbart die Wahrheit." - id: "prevention" type: "content" - title: "Protecting Against BitB Attacks" + title: "Schutz vor BitB-Angriffen" content: | - For Users: - • Always test if popup windows can be moved freely - • Use password managers (they check actual domains) - • Enable 2FA/MFA for additional security layer - • Be suspicious of unexpected login prompts - • Manually navigate to sites instead of clicking links + Für Benutzer: + • Testen Sie immer, ob Popup-Fenster frei bewegt werden können + • Verwenden Sie Passwort-Manager (sie prüfen tatsächliche Domains) + • Aktivieren Sie 2FA/MFA für zusätzliche Sicherheitsebene + • Seien Sie misstrauisch bei unerwarteten Login-Aufforderungen + • Navigieren Sie manuell zu Seiten, anstatt auf Links zu klicken - For Developers: - • Educate users about OAuth popup behavior - • Use OAuth redirect flow instead of popups when possible - • Implement additional verification steps - • Consider passwordless authentication methods - • Show clear security indicators in your app + Für Entwickler: + • Schulen Sie Benutzer über OAuth-Popup-Verhalten + • Verwenden Sie OAuth-Redirect-Flow statt Popups, wenn möglich + • Implementieren Sie zusätzliche Verifizierungsschritte + • Erwägen Sie passwortlose Authentifizierungsmethoden + • Zeigen Sie klare Sicherheitsindikatoren in Ihrer App - For Organizations: - • Train employees to recognize advanced phishing - • Deploy anti-phishing browser extensions - • Use hardware security keys (FIDO2/WebAuthn) - • Monitor for suspicious authentication attempts - • Implement conditional access policies - - - id: "question-3" - type: "question" - questionType: "free_text" - question: "Why are password managers particularly effective at protecting against BitB attacks?" - validationRules: - keywords: - required: ["domain", "autofill", "real"] - partialCredit: 8 - minLength: 40 - maxPoints: 25 - feedback: - correct: "Excellent! Password managers check the actual domain of the page and won't autofill credentials on fake domains, even if they look legitimate." - incorrect: "Think about how password managers verify which site they're on before filling in credentials. They check the real URL, not what's displayed visually." + Für Organisationen: + • Schulen Sie Mitarbeiter, fortgeschrittenes Phishing zu erkennen + • Setzen Sie Anti-Phishing-Browser-Erweiterungen ein + • Verwenden Sie Hardware-Sicherheitsschlüssel (FIDO2/WebAuthn) + • Überwachen Sie verdächtige Authentifizierungsversuche + • Implementieren Sie bedingte Zugriffsrichtlinien scoring: - passingScore: 75 - maxTotalPoints: 100 + passingScore: 55 + maxTotalPoints: 75 diff --git a/backend/lessons/configs/idor-demo.yaml b/backend/lessons/configs/idor-demo.yaml new file mode 100644 index 0000000..835dc1d --- /dev/null +++ b/backend/lessons/configs/idor-demo.yaml @@ -0,0 +1,426 @@ +lessonKey: "idor-demo" +title: "IDOR - Unsichere direkte Objektreferenz" +description: "Erfahre, wie unsichere direkte Objektreferenzen durch URL-Manipulation den unbefugten Zugriff auf Daten anderer Benutzer ermöglichen" +difficultyLevel: "intermediate" +estimatedDuration: 22 +module: "idor-demo" + +steps: + - id: "intro" + type: "content" + title: "Was ist IDOR?" + content: | + IDOR (Insecure Direct Object Reference - Unsichere direkte Objektreferenz) ist eine Sicherheitslücke, die auftritt, wenn eine Anwendung direkten Zugriff auf Objekte basierend auf vom Benutzer bereitgestellten Eingaben ermöglicht. Wenn die Anwendung nicht ordnungsgemäß überprüft, ob der Benutzer berechtigt ist, auf das angeforderte Objekt zuzugreifen, können Angreifer auf unbefugte Daten zugreifen. + + **Wie IDOR funktioniert:** + + Eine anfällige URL könnte so aussehen: + https://bank.com/profile?userId=123 + + Wenn die Anwendung nicht prüft, ob der angemeldete Benutzer auf die Daten von Benutzer 123 zugreifen darf, kann ein Angreifer einfach den Parameter ändern: + https://bank.com/profile?userId=124 ← Zugriff auf die Daten eines anderen Benutzers! + + **IDOR in den OWASP Top 10:** + IDOR fällt unter **A01:2021 - Fehlerhafte Zugriffskontrolle**, das kritischste Sicherheitsrisiko für Webanwendungen. + + **Häufige IDOR-Ziele:** + • Benutzerprofile und Kontodaten + • Private Nachrichten und E-Mails + • Finanzdaten und Transaktionen + • Medizinische Aufzeichnungen + • Bestellhistorien + • Private Dateien und Dokumente + • Verwaltungsfunktionen + + **Warum es gefährlich ist:** + • Einfach auszunutzen (nur einen URL-Parameter ändern) + • Bleibt oft unentdeckt + • Kann sensible persönliche Daten offenlegen + • Kann Datenschutzgesetze verletzen (DSGVO, HIPAA, etc.) + • Kann zu Identitätsdiebstahl führen + • Keine speziellen Werkzeuge erforderlich + + - id: "auth-vs-authz" + type: "content" + title: "Authentifizierung vs. Autorisierung" + content: | + Das Verständnis des Unterschieds zwischen Authentifizierung und Autorisierung ist entscheidend zur Verhinderung von IDOR: + + **Authentifizierung (AuthN):** + "Wer bist du?" + + • Verifiziert die Benutzeridentität + • Verwendet Anmeldedaten (Benutzername/Passwort, Tokens, etc.) + • Bestätigt, dass du die Person bist, für die du dich ausgibst + • Beispiel: Anmeldung in deinem Konto + + **Autorisierung (AuthZ):** + "Was darfst du tun?" + + • Verifiziert Benutzerberechtigungen + • Prüft, ob du auf bestimmte Ressourcen zugreifen kannst + • Bestimmt, was du sehen oder ändern kannst + • Beispiel: Überprüfung, ob du ein bestimmtes Profil ansehen darfst + + **Das IDOR-Problem:** + + Viele Anwendungen implementieren Authentifizierung, vergessen aber die Autorisierung! + + ✅ Benutzer ist authentifiziert (angemeldet) + ❌ Anwendung prüft nicht, ob der Benutzer auf diese spezifische Ressource zugreifen darf + = IDOR-Sicherheitslücke + + **Analogie aus der realen Welt:** + + Authentifizierung = Einen Schlüssel zum Betreten des Gebäudes haben + Autorisierung = Die Erlaubnis haben, bestimmte Räume zu betreten + + Bei IDOR hast du einen Schlüssel zum Gebäude (du bist angemeldet), aber die Anwendung prüft nicht, welche Räume du betreten darfst. Du kannst jede Tür öffnen, indem du verschiedene Raumnummern ausprobierst! + + **Beispielszenarien:** + + **Szenario 1: Soziale Medien** + • Du bist angemeldet (authentifiziert ✅) + • Du versuchst, eine Nachricht anzusehen: /messages/12345 + • App prüft nicht, ob Nachricht 12345 dir gehört (keine Autorisierung ❌) + • Du kannst private Nachrichten von jedem lesen, indem du die ID änderst + + **Szenario 2: E-Commerce** + • Du bist angemeldet (authentifiziert ✅) + • Du siehst deine Bestellung: /orders/5001 + • App überprüft nicht den Bestellbesitz (keine Autorisierung ❌) + • Du kannst die Bestellungen, Adressen und Kaufhistorie von jedem sehen + + **Szenario 3: Gesundheitswesen** + • Du bist als Patient angemeldet (authentifiziert ✅) + • Du siehst Laborergebnisse: /results/patient/789 + • App prüft nicht, ob du Patient 789 bist (keine Autorisierung ❌) + • Du kannst auf medizinische Aufzeichnungen von jedem zugreifen, indem du die ID änderst + + - id: "idor-demo" + type: "interactive" + title: "IDOR-Sicherheitslücken-Demo" + interactiveComponent: "IDORDemo" + content: | + Unten ist eine simulierte Online-Banking-Anwendung mit einer IDOR-Sicherheitslücke. Du bist als "Max Mustermann" (Benutzer-ID 55) angemeldet. + + Die Anwendung verwendet einen URL-Parameter zum Abrufen von Benutzerprofilen: + + `https://securebank.example/profile?ref=dashboard&userId=55` + + **Deine Aufgabe:** + + 1. Untersuche die URL-Struktur und identifiziere den anfälligen Parameter + + 2. Versuche, den userId-Parameter zu ändern, um auf andere Benutzer zuzugreifen + + 3. Beobachte, wie du auf private Informationen zugreifen kannst, die du nicht sehen solltest + + 4. Finde versteckte Benutzer durch systematisches Testen verschiedener IDs + + 5. Du hast 5 Minuten Zeit - versuche so viele Benutzer wie möglich zu entdecken! + + **Hinweise:** + + - Nicht alle IDs existieren - manche Benutzer wurden gelöscht + + - Es gibt besondere Belohnungen für bestimmte Entdeckungen + + - Achte auf die Entdeckungsanzeige oben + + Dies demonstriert, warum Anwendungen Autorisierung überprüfen müssen, nicht nur Authentifizierung. + + - id: "question-1" + type: "question" + questionType: "multiple_choice" + question: "Welche der folgenden URL-Muster deuten auf potenzielle IDOR-Sicherheitslücken hin?" + options: + - id: "user-id-param" + text: "/api/user?id=123" + isCorrect: true + points: 10 + - id: "order-id-param" + text: "/orders/view?orderId=5001" + isCorrect: true + points: 10 + - id: "document-id-param" + text: "/documents/download/42" + isCorrect: true + points: 10 + - id: "session-token" + text: "/profile (verwendet Session-Token im Header)" + isCorrect: false + points: 0 + - id: "message-id-param" + text: "/messages/inbox/msg_789" + isCorrect: true + points: 10 + maxPoints: 40 + feedback: + correct: "Ausgezeichnet! All diese Muster mit direkten Objekt-IDs in URLs oder Parametern sind potenzielle IDOR-Ziele, wenn keine ordnungsgemäße Autorisierung implementiert ist." + partial: "Gut! Du hast einige IDOR-Muster erkannt. Jede URL, die Ressourcen-IDs (Benutzer, Bestellungen, Dokumente, Nachrichten) enthält, benötigt Autorisierungsprüfungen." + incorrect: "Suche nach URLs, die identifizierbare Ressourcen-IDs (Zahlen oder Kennungen) enthalten. Diese benötigen alle eine ordnungsgemäße Autorisierung, um IDOR zu verhindern. Session-Tokens sind sicher, weil sie serverseitig verifiziert werden." + + - id: "real-world-impact" + type: "content" + title: "IDOR-Datenlecks in der realen Welt" + content: | + IDOR-Sicherheitslücken haben zu massiven Datenlecks und Datenschutzverletzungen geführt: + + **Facebook (2019) - 419 Millionen Datensätze** + • Telefonnummern durch IDOR offengelegt + • Angreifer konnten Benutzer-IDs aufzählen + • Datenbank enthielt Facebook-IDs und Telefonnummern + • Betraf Benutzer weltweit + • Führte zu erheblichen Datenschutzbedenken + + **Bumble Dating App (2019)** + • IDOR ermöglichte Zugriff auf jedes Benutzerprofil + • Angreifer konnten private Fotos ansehen + • Konnte auf als "versteckt" markierte Benutzer zugreifen + • Echtzeit-Standortdaten offengelegt + • Profile von 95 Millionen Benutzern erfasst + + **Parler Social Network (2021)** + • IDOR in Post- und Benutzer-APIs + • Alle Beiträge waren sequentiell nummeriert + • Angreifer erfassten 70TB Daten + • Enthielt gelöschte Beiträge und Metadaten + • Enthielt GPS-Koordinaten aus Videos + + **Verizon (2017)** + • IDOR legte 14 Millionen Kundendatensätze offen + • Kontodetails, Telefonnummern und PINs + • Einfache Parametermanipulation + • Ohne Authentifizierung zugänglich + • Benötigte 6 Monate zur Entdeckung + + **USPS Informed Visibility (2018)** + • IDOR legte 60 Millionen Benutzer offen + • E-Mail-Adressen, Telefonnummern und Adressen + • Mailingkampagnendaten + • Kontodetails und Präferenzen + • Wildcard-Suchsicherheitslücke + + **PizzaHut Australia (2020)** + • IDOR in Bestell-API + • Kundennamen, Adressen und Bestellhistorie + • Kreditkartendetails (teilweise) + • Lieferanweisungen + • Telefonnummern + + **Auswirkungsstatistiken:** + • IDOR erscheint in ~15% aller Webanwendungen + • Durchschnittliche Kosten eines IDOR-Lecks: 3,86 Millionen Dollar + • Durchschnittliche Zeit zur Entdeckung: 197 Tage + • Durchschnittliche Zeit zur Eindämmung: 69 Tage + • 60% der Organisationen erlebten IDOR in den letzten 2 Jahren + + **Rechtliche Konsequenzen:** + • DSGVO-Strafen bis zu 20 Millionen Euro oder 4% des Umsatzes + • CCPA-Strafen bis zu 7.500 Dollar pro Verstoß + • Sammelklagen von betroffenen Benutzern + • Verlust von Kundenvertrauen und Reputation + • Behördliche Untersuchungen + • Verpflichtende Benachrichtigungen über Datenlecks + + - id: "question-2" + type: "question" + questionType: "single_choice" + question: "Was ist der BESTE Weg, um IDOR-Sicherheitslücken zu verhindern?" + options: + - id: "hide-ids" + text: "Alle Objekt-IDs in URLs verstecken oder verschlüsseln" + isCorrect: false + points: 0 + - id: "session-check" + text: "Überprüfen, dass der authentifizierte Benutzer die Berechtigung hat, auf die angeforderte Ressource zuzugreifen" + isCorrect: true + points: 30 + - id: "rate-limiting" + text: "Rate-Limiting implementieren, um ID-Aufzählung zu verhindern" + isCorrect: false + points: 0 + - id: "complex-ids" + text: "Komplexe, zufällige IDs anstelle von sequentiellen Nummern verwenden" + isCorrect: false + points: 0 + maxPoints: 30 + feedback: + correct: "Perfekt! Ordnungsgemäße Autorisierungsprüfungen sind unerlässlich. Jede Anfrage muss überprüfen, ob der Benutzer die Berechtigung hat, auf die spezifische Ressource zuzugreifen, unabhängig davon, wie die ID formatiert ist." + incorrect: "Obwohl Verschleierung und Rate-Limiting helfen können, lösen sie nicht das Grundproblem. Die Anwendung MUSS überprüfen, dass der authentifizierte Benutzer die Autorisierung hat, auf jede spezifische Ressource zuzugreifen, bevor sie zurückgegeben wird." + + - id: "secure-design" + type: "content" + title: "Sichere Designmuster" + content: | + **IDOR verhindern: Best Practices** + + **1. Zugriffskontrollprüfungen implementieren** + + Jeder Ressourcenzugriff muss die Autorisierung überprüfen: + + // ❌ ANFÄLLIG - Keine Autorisierungsprüfung + app.get('/api/profile/:userId', authenticate, (req, res) => { + const user = db.getUserById(req.params.userId); + res.json(user); // Gibt die Daten eines beliebigen Benutzers zurück! + }); + + // ✅ SICHER - Ordnungsgemäße Autorisierung + app.get('/api/profile/:userId', authenticate, (req, res) => { + const requestedUserId = req.params.userId; + const currentUserId = req.session.userId; + + // Prüfen, ob Benutzer Berechtigung hat + if (requestedUserId !== currentUserId && !req.session.isAdmin) { + return res.status(403).json({ error: 'Forbidden' }); + } + + const user = db.getUserById(requestedUserId); + res.json(user); + }); + + **2. Indirekte Referenzen verwenden** + + Datenbank-IDs nicht direkt offenlegen: + + // ❌ Direkte Referenz auf Datenbank-ID + GET /api/messages/12345 + + // ✅ Indirekte Referenz durch Benutzerkontext + GET /api/messages/inbox (gibt nur Nachrichten des Benutzers zurück) + GET /api/messages/sent (gibt nur gesendete Nachrichten des Benutzers zurück) + + // Wenn du IDs verwenden musst, überprüfe den Besitz: + GET /api/messages/msg_abc123 + // Dann prüfen: db.isMessageOwnedBy(msg_abc123, currentUserId) + + **3. Rollenbasierte Zugriffskontrolle (RBAC) implementieren** + + Klare Berechtigungsmodelle definieren: + + const permissions = { + user: { + canViewOwnProfile: true, + canViewOtherProfiles: false, + canEditOwnProfile: true, + canEditOtherProfiles: false + }, + admin: { + canViewOwnProfile: true, + canViewOtherProfiles: true, + canEditOwnProfile: true, + canEditOtherProfiles: true + } + }; + + function checkPermission(user, action, resource) { + if (action === 'view' && resource.ownerId !== user.id) { + return permissions[user.role].canViewOtherProfiles; + } + return permissions[user.role][`can${action}`]; + } + + **4. Sitzungsbasierten Ressourcenzugriff verwenden** + + Lass die Sitzung bestimmen, auf welche Ressourcen zugegriffen werden kann: + + // ✅ Aktuelle Benutzerdaten aus Sitzung abrufen + app.get('/api/profile', authenticate, (req, res) => { + const userId = req.session.userId; // Aus verifizierter Sitzung + const user = db.getUserById(userId); + res.json(user); + }); + + // ✅ Bestellungen des aktuellen Benutzers aus Sitzung abrufen + app.get('/api/orders', authenticate, (req, res) => { + const userId = req.session.userId; + const orders = db.getOrdersByUserId(userId); + res.json(orders); + }); + + **5. Zugriffskontrolllisten (ACLs) implementieren** + + Für komplexe Berechtigungen: + + class AccessControl { + canAccess(userId, resourceType, resourceId) { + // Besitz prüfen + const resource = db.getResource(resourceType, resourceId); + if (resource.ownerId === userId) return true; + + // Freigabeberechtigungen prüfen + const acl = db.getACL(resourceType, resourceId); + if (acl.sharedWith.includes(userId)) return true; + + // Gruppenberechtigungen prüfen + const user = db.getUser(userId); + if (acl.groupsWithAccess.some(g => user.groups.includes(g))) { + return true; + } + + return false; + } + } + + **6. Zugriffsversuche protokollieren und überwachen** + + app.get('/api/resource/:id', authenticate, (req, res) => { + const resourceId = req.params.id; + const userId = req.session.userId; + + // Zugriffsversuch protokollieren + logger.info('Ressourcenzugriffsversuch', { + userId, + resourceId, + timestamp: Date.now() + }); + + // Autorisierung prüfen + if (!canAccess(userId, 'resource', resourceId)) { + // Unbefugten Versuch protokollieren + logger.warn('Unbefugter Zugriffsversuch', { + userId, + resourceId, + ip: req.ip + }); + + // Sicherheitsteam bei mehreren Versuchen benachrichtigen + securityMonitor.recordUnauthorizedAccess(userId, resourceId); + + return res.status(403).json({ error: 'Forbidden' }); + } + + // Mit autorisiertem Zugriff fortfahren + const resource = db.getResource(resourceId); + res.json(resource); + }); + + **7. Auf IDOR testen** + + **Manuelles Testen:** + 1. Als Benutzer A anmelden + 2. Auf eine Ressource zugreifen: `/api/profile/123` + 3. Die ID in der URL/dem Parameter notieren + 4. Auf eine andere ID ändern: `/api/profile/124` + 5. Wenn du auf die Daten von Benutzer B zugreifen kannst → IDOR-Sicherheitslücke! + + **Automatisiertes Testen:** + • Tools wie Burp Suite, OWASP ZAP verwenden + • Alle Endpunkte mit verschiedenen Benutzerrollen testen + • IDs aufzählen, um zugängliche Ressourcen zu finden + • Auf horizontale Rechteausweitung prüfen (gleiche Rolle, anderer Benutzer) + • Auf vertikale Rechteausweitung prüfen (andere Rolle) + + **Sicherheits-Checkliste:** + ✅ Alle Ressourcenzugriffe haben Autorisierungsprüfungen + ✅ Datenbank-IDs werden wenn möglich nicht direkt offengelegt + ✅ Rollenbasierte Zugriffskontrolle ist implementiert + ✅ Zugriffsversuche werden protokolliert und überwacht + ✅ Sensible Operationen erfordern zusätzliche Verifizierung + ✅ Regelmäßige Sicherheitsaudits und Penetrationstests + ✅ Entwicklerschulung zur IDOR-Prävention + +scoring: + passingScore: 105 + maxTotalPoints: 210 # 70 from questions + up to 140 from interactive discoveries diff --git a/backend/lessons/configs/phishing-email-basics.yaml b/backend/lessons/configs/phishing-email-basics.yaml index a1181a4..d6d40af 100644 --- a/backend/lessons/configs/phishing-email-basics.yaml +++ b/backend/lessons/configs/phishing-email-basics.yaml @@ -1,6 +1,6 @@ lessonKey: "phishing-email-basics" -title: "Phishing Email Detection Basics" -description: "Learn to identify common phishing tactics in emails and protect yourself from email-based attacks" +title: "Grundlagen der Phishing-E-Mail-Erkennung" +description: "Lernen Sie, gängige Phishing-Taktiken in E-Mails zu erkennen und sich vor E-Mail-basierten Angriffen zu schützen" difficultyLevel: "beginner" estimatedDuration: 15 module: "phishing-email-basics" @@ -8,110 +8,95 @@ module: "phishing-email-basics" steps: - id: "intro" type: "content" - title: "What is Phishing?" + title: "Was ist Phishing?" content: | - Phishing is a type of cyber attack where attackers impersonate legitimate organizations - to steal sensitive information like passwords, credit card numbers, or personal data. + Phishing ist eine Art von Cyberangriff, bei dem Angreifer sich als legitime Organisationen ausgeben, + um sensible Informationen wie Passwörter, Kreditkartennummern oder persönliche Daten zu stehlen. - Phishing emails often: - - Create a sense of urgency - - Contain suspicious links or attachments - - Have spelling and grammar errors - - Use generic greetings like "Dear Customer" - - Request sensitive information + Phishing-E-Mails haben oft folgende Merkmale: + - Erzeugen ein Gefühl der Dringlichkeit + - Enthalten verdächtige Links oder Anhänge + - Weisen Rechtschreib- und Grammatikfehler auf + - Verwenden allgemeine Begrüßungen wie "Sehr geehrter Kunde" + - Fordern sensible Informationen an - id: "example-1" type: "content" - title: "Example Phishing Email" + title: "Beispiel einer Phishing-E-Mail" content: | - **From:** security@paypa1-verify.com - **Subject:** Urgent: Verify Your Account Now! + **Von:** security@paypa1-verify.com + **Betreff:** Dringend: Verifizieren Sie jetzt Ihr Konto! - Dear Valued Customer, + Sehr geehrter Kunde, - Your PayPal account has been temporarily suspended due to unusual activity. - To restore your account, please verify your information immediately by clicking - the link below: + Ihr PayPal-Konto wurde aufgrund ungewöhnlicher Aktivitäten vorübergehend gesperrt. + Um Ihr Konto wiederherzustellen, verifizieren Sie bitte sofort Ihre Informationen, + indem Sie auf den untenstehenden Link klicken: - [Verify Account Now] + [Konto jetzt verifizieren] - Failure to verify within 24 hours will result in permanent account suspension. + Wenn Sie nicht innerhalb von 24 Stunden verifizieren, wird Ihr Konto dauerhaft gesperrt. - Thank you, + Vielen Dank, PayPal Security Team - id: "question-1" type: "question" questionType: "multiple_choice" - question: "What are the suspicious elements in this email? (Select all that apply)" + question: "Was sind die verdächtigen Elemente in dieser E-Mail? (Wählen Sie alle zutreffenden)" options: - id: "misspelled-domain" - text: "The sender's domain is misspelled (paypa1 instead of paypal)" + text: "Die Domain des Absenders ist falsch geschrieben (paypa1 statt paypal)" isCorrect: true points: 15 - id: "urgent-language" - text: "Uses urgent/threatening language to create pressure" + text: "Verwendet dringende/drohende Sprache, um Druck zu erzeugen" isCorrect: true points: 15 - id: "generic-greeting" - text: "Uses generic greeting 'Dear Valued Customer'" + text: "Verwendet allgemeine Begrüßung 'Sehr geehrter Kunde'" isCorrect: true points: 10 - id: "requests-action" - text: "Requests immediate action via a link" + text: "Fordert sofortige Handlung über einen Link" isCorrect: true points: 10 - id: "legitimate" - text: "This appears to be a legitimate email" + text: "Dies scheint eine legitime E-Mail zu sein" isCorrect: false points: 0 maxPoints: 50 feedback: - correct: "Excellent! You identified all the key phishing indicators." - partial: "Good job! You spotted some red flags, but review the email again carefully." - incorrect: "Not quite. Let's review the common signs of phishing emails." + correct: "Ausgezeichnet! Sie haben alle wichtigen Phishing-Indikatoren erkannt." + partial: "Gut gemacht! Sie haben einige Warnsignale erkannt, aber überprüfen Sie die E-Mail noch einmal sorgfältig." + incorrect: "Nicht ganz. Lassen Sie uns die häufigen Anzeichen von Phishing-E-Mails noch einmal ansehen." - id: "question-2" type: "question" questionType: "single_choice" - question: "What should you do if you receive a suspicious email like this?" + question: "Was sollten Sie tun, wenn Sie eine verdächtige E-Mail wie diese erhalten?" options: - id: "click-link" - text: "Click the link to verify my account" + text: "Auf den Link klicken, um mein Konto zu verifizieren" isCorrect: false points: 0 - id: "reply-email" - text: "Reply to the email asking if it's legitimate" + text: "Auf die E-Mail antworten und fragen, ob sie legitim ist" isCorrect: false points: 0 - id: "delete-report" - text: "Delete the email and report it as phishing" + text: "Die E-Mail löschen und als Phishing melden" isCorrect: true points: 25 - id: "forward-friends" - text: "Forward it to friends to warn them" + text: "Sie an Freunde weiterleiten, um sie zu warnen" isCorrect: false points: 0 maxPoints: 25 feedback: - correct: "Perfect! Deleting and reporting phishing emails is the right approach." - incorrect: "That's not safe. Never click links or reply to suspicious emails. Delete and report them." - - - id: "question-3" - type: "question" - questionType: "free_text" - question: "Describe at least three things you should check before clicking a link in an email." - validationRules: - - type: "contains_keywords" - keywords: ["sender", "domain", "url", "link", "https", "hover", "address", "spelling", "grammar"] - minMatches: 3 - - type: "min_length" - value: 50 - maxPoints: 25 - feedback: - correct: "Great answer! You understand the importance of verifying emails before taking action." - incorrect: "Consider checking the sender's email address, hovering over links to see the real URL, and looking for HTTPS." + correct: "Perfekt! Das Löschen und Melden von Phishing-E-Mails ist der richtige Ansatz." + incorrect: "Das ist nicht sicher. Klicken Sie niemals auf Links oder antworten Sie auf verdächtige E-Mails. Löschen und melden Sie sie." scoring: - passingScore: 70 - maxTotalPoints: 100 + passingScore: 50 + maxTotalPoints: 75 diff --git a/backend/lessons/configs/script-injection-forum.yaml b/backend/lessons/configs/script-injection-forum.yaml new file mode 100644 index 0000000..bbcefc8 --- /dev/null +++ b/backend/lessons/configs/script-injection-forum.yaml @@ -0,0 +1,283 @@ +lessonKey: "script-injection-forum" +title: "Stored XSS - Forum Comment Injection" +description: "Lernen Sie, wie Script-Injection in benutzergenerierten Inhalten ganze Plattformen durch Stored-XSS-Angriffe kompromittieren kann" +difficultyLevel: "intermediate" +estimatedDuration: 25 +module: "script-injection-forum" + +steps: + - id: "intro" + type: "content" + title: "Was ist Stored XSS?" + content: | + Stored XSS (Cross-Site Scripting) ist eine Art von Injection-Angriff, bei dem bösartige Skripte dauerhaft auf einem Zielserver gespeichert werden. Im Gegensatz zu Reflected XSS, bei dem das Opfer auf einen bösartigen Link klicken muss, betrifft Stored XSS alle Benutzer, die den kompromittierten Inhalt ansehen. + + **Häufige Ziele:** + • Forum-Beiträge und Kommentare + • Benutzerprofile und Biografien + • Produktbewertungen + • Feedback-Formulare + • Social-Media-Beiträge + • Blog-Kommentare + • Wiki-Seiten + + **Auswirkungen:** + • Cookie-Diebstahl und Session-Hijacking + • Kontoübernahme + • Malware-Verteilung + • Website-Verunstaltung + • Phishing-Angriffe auf andere Benutzer + • Keylogging + • Datendiebstahl + + **Warum es gefährlich ist:** + Stored XSS ist besonders gefährlich, weil: + 1. Es bleibt in der Datenbank bestehen + 2. Es betrifft automatisch mehrere Benutzer + 3. Es erfordert kein Social Engineering zur Verbreitung + 4. Es kann über lange Zeiträume unentdeckt bleiben + + - id: "real-world" + type: "content" + title: "Reale Stored-XSS-Angriffe" + content: | + **Samy Worm (MySpace, 2005)** + Samy Kamkar erstellte einen sich selbst verbreitenden XSS-Wurm in seinem MySpace-Profil, der ihn automatisch als Freund zu jedem Profil hinzufügte, das ihn ansah. Der Wurm kopierte sich auch auf jedes infizierte Profil und verbreitete sich exponentiell. + + Innerhalb von 20 Stunden waren über 1 Million Benutzer betroffen, was Samy zur beliebtesten Person auf MySpace machte. Die Website musste offline genommen werden, um den Wurm zu entfernen. + + **TweetDeck XSS (Twitter, 2014)** + Eine Stored-XSS-Schwachstelle in TweetDeck ermöglichte es Angreifern, bösartigen Code über Tweets einzuschleusen. Als andere Benutzer diese Tweets in TweetDeck ansahen, wurde der Code automatisch ausgeführt und verursachte: + • Automatische Retweets der bösartigen Payload + • Pop-up-Benachrichtigungen für alle Betrachter + • Schnelle Verbreitung über die Plattform + + **eBay Stored XSS (2015-2016)** + Mehrere Stored-XSS-Schwachstellen wurden in den Artikelbeschreibungen von eBay entdeckt. Angreifer konnten: + • Code in Produktbeschreibungen einschleusen + • Benutzeranmeldeinformationen stehlen, wenn Käufer Angebote ansahen + • Benutzer auf Phishing-Seiten umleiten + • Konten von Käufern und Verkäufern kompromittieren + + **British Airways XSS (2018)** + Angreifer schleusten bösartiges JavaScript über eine Stored-XSS-Schwachstelle in die Zahlungsseite von British Airways ein. Das Skript: + • Erfasste Kreditkarteninformationen + • Sendete Daten an vom Angreifer kontrollierte Server + • Betraf über 380.000 Transaktionen + • Kostete British Airways über 20 Millionen Pfund an Strafen + + Diese Angriffe demonstrieren, warum Eingabevalidierung und Output-Encoding für jede Anwendung, die benutzergenerierte Inhalte akzeptiert, kritisch sind. + + - id: "forum-demo" + type: "interactive" + title: "Anfälliges Forum Demo" + interactiveComponent: "ForumScriptDemo" + content: | + Unten sehen Sie ein vereinfachtes Forum, das Benutzerkommentare OHNE ordnungsgemäße Eingabevalidierung oder Output-Encoding akzeptiert. Versuchen Sie zuerst, normale Kommentare zu posten, und experimentieren Sie dann mit Script-Injection-Payloads. + + Beachten Sie, wie die bösartigen Skripte gespeichert werden und alle Benutzer betreffen würden, die das Forum ansehen. In dieser Demo zeigen wir die Payloads sicher als Text an, anstatt sie auszuführen, mit klaren Warnungen, wenn eine Injection erkannt wird. + + **Probieren Sie diese Aktionen:** + 1. Posten Sie einen normalen Kommentar, um sicheres Verhalten zu sehen + 2. Versuchen Sie Beispiel-XSS-Payloads, um die Erkennung zu sehen + 3. Verwenden Sie die Reload-Schaltfläche, um das Forum zurückzusetzen + + - id: "question-1" + type: "question" + questionType: "multiple_choice" + question: "Welche der folgenden Payloads könnten für Stored-XSS-Angriffe in einem Forum verwendet werden?" + options: + - id: "script-cookie" + text: "" + isCorrect: true + points: 10 + - id: "img-steal" + text: "" + isCorrect: true + points: 10 + - id: "svg-payload" + text: "" + isCorrect: true + points: 10 + - id: "iframe-phishing" + text: "" + isCorrect: true + points: 10 + - id: "normal-comment" + text: "Dies ist ein normaler Kommentar ohne bösartigen Code" + isCorrect: false + points: 0 + maxPoints: 40 + feedback: + correct: "Ausgezeichnet! Sie haben alle gefährlichen Payloads identifiziert, die auf dem Server bestehen bleiben und mehrere Benutzer betreffen können." + partial: "Gut! Sie haben einige Bedrohungen erkannt, aber überprüfen Sie die Muster, die Code-Ausführung durch HTML-Tags und Event-Handler ermöglichen." + incorrect: "Überprüfen Sie die Demo. Suchen Sie nach Mustern, die Script-Tags, Event-Handler wie onerror oder onload oder eingebettete Inhalte wie iframes enthalten." + + - id: "attack-vectors" + type: "content" + title: "Stored-XSS-Angriffsvektoren" + content: | + Gängige Techniken, die Angreifer bei Stored XSS verwenden: + + **1. Cookie-Diebstahl** + + Stiehlt Authentifizierungs-Cookies und ermöglicht Kontoübernahme. Der Angreifer kann dann jeden Benutzer imitieren, der den Kommentar angesehen hat. + + **2. Session-Hijacking** + + Extrahiert Session-Token aus dem Browser-Speicher und kompromittiert Benutzersitzungen. + + **3. Keylogging** + + Zeichnet jeden Tastendruck auf der Seite auf und erfasst Passwörter und sensible Informationen. + + **4. Verunstaltung** + + Ändert den sichtbaren Inhalt für alle Benutzer und beschädigt Reputation und Vertrauen. + + **5. Phishing-Overlay** +
    +
    +

    Sitzung abgelaufen - Bitte erneut anmelden

    + Benutzername:
    + Passwort:
    + +
    +
    + Zeigt ein gefälschtes Login-Formular über der echten Seite an und erfasst Anmeldeinformationen. + + **6. Kryptowährungs-Mining** + + Mined heimlich Kryptowährung mit den CPU-Ressourcen der Besucher. + + **7. Malware-Verteilung** + + Leitet Benutzer zu Malware-Downloads oder Drive-by-Download-Angriffen um. + + - id: "question-2" + type: "question" + questionType: "single_choice" + question: "Warum gilt Stored XSS im Allgemeinen als GEFÄHRLICHER als Reflected XSS?" + options: + - id: "easier-exploit" + text: "Es ist einfacher auszunutzen, da es keine Sonderzeichen erfordert" + isCorrect: false + points: 0 + - id: "persistent-victims" + text: "Es bleibt auf dem Server bestehen und betrifft alle Benutzer, die den Inhalt ansehen, nicht nur diejenigen, die auf einen bösartigen Link klicken" + isCorrect: true + points: 30 + - id: "no-detection" + text: "Es kann nicht von Sicherheitstools oder Antiviren-Software erkannt werden" + isCorrect: false + points: 0 + - id: "admin-access" + text: "Es gewährt Angreifern automatisch Administratorzugriff auf den Server" + isCorrect: false + points: 0 + maxPoints: 30 + feedback: + correct: "Perfekt! Stored XSS ist eine persistente Bedrohung, die viele Benutzer über die Zeit betreffen kann, ohne dass eine individuelle Zielerfassung erforderlich ist. Es bleibt in der Datenbank und wird jedes Mal ausgeführt, wenn jemand es ansieht." + incorrect: "Denken Sie über den Unterschied zwischen einer Payload, die an jedes Opfer gesendet werden muss, und einer, die einmal gespeichert wird und jeden betrifft. Persistenz und automatische Verbreitung sind die Hauptgefahren." + + - id: "prevention" + type: "content" + title: "Stored XSS verhindern" + content: | + **Defense-in-Depth-Ansatz:** + + **1. Eingabevalidierung (Erste Linie)** + • Validieren Sie alle Benutzereingaben gegen das erwartete Format + • Verwenden Sie Allowlists für akzeptable Zeichen + • Lehnen Sie Eingaben ab, die verdächtige Muster enthalten + • Validieren Sie Datentyp, Länge und Format + • Vertrauen Sie niemals "bereinigten" Eingaben - validieren Sie immer + + **2. Output-Encoding (Kritisch)** + Kodieren Sie alle Ausgaben kontextabhängig: + + **HTML-Kontext:** + • < wird zu < + • > wird zu > + • & wird zu & + • " wird zu " + • ' wird zu ' + + **JavaScript-Kontext:** + • Verwenden Sie JSON.stringify() für Daten + • Escapieren Sie Backslashes und Anführungszeichen + + **URL-Kontext:** + • Verwenden Sie encodeURIComponent() + + **Vertrauen Sie niemals Inhalten aus der Datenbank** - selbst wenn sie bei der Eingabe validiert wurden, kodieren Sie immer bei der Ausgabe! + + **3. Content Security Policy (Verteidigungsebene)** + Content-Security-Policy: + default-src 'self'; + script-src 'self' 'nonce-{random}'; + style-src 'self' 'unsafe-inline'; + img-src 'self' https:; + object-src 'none'; + base-uri 'self'; + form-action 'self'; + + CSP-Vorteile: + • Verhindert Ausführung von Inline-Skripten + • Beschränkt Ressourcen-Laden auf vertrauenswürdige Quellen + • Mindert Auswirkungen, selbst wenn XSS durchkommt + • Bietet Verletzungsberichte zur Überwachung + + **4. HTTPOnly und Secure Cookies** + Set-Cookie: sessionId=abc123; + HttpOnly; + Secure; + SameSite=Strict + + • **HttpOnly** - Verhindert JavaScript-Zugriff auf Cookies + • **Secure** - Stellt HTTPS-only-Übertragung sicher + • **SameSite** - Verhindert CSRF-Angriffe + + **5. Framework-Sicherheitsfunktionen** + Moderne Frameworks bieten eingebauten XSS-Schutz: + + • **React:** Escapt JSX-Inhalte automatisch + • **Angular:** Eingebaute Bereinigung mit DomSanitizer + • **Vue:** Template-Escaping standardmäßig + + ⚠️ **Verwenden Sie NIEMALS gefährliche Funktionen:** + • React: `dangerouslySetInnerHTML` + • Angular: `bypassSecurityTrust...` Methoden + • Vue: `v-html` mit Benutzerinhalten + • JavaScript: `eval()`, `innerHTML` mit Benutzerdaten + + **6. Regelmäßige Sicherheitsaudits** + • Statische Code-Analyse (SAST-Tools) + • Dynamische Sicherheitstests (DAST-Tools) + • Penetrationstests + • Code-Reviews mit Fokus auf Benutzereingabe-Verarbeitung + • Sicherheitsbewusstseins-Schulungen für Entwickler + + **7. Web Application Firewall (WAF)** + • Kann XSS-Versuche erkennen und blockieren + • Sollte als zusätzliche Ebene verwendet werden, nicht als primäre Verteidigung + • Bietet Überwachung und Alarmierung + • Updates zum Blockieren neuer Angriffsmuster + +scoring: + passingScore: 58 + maxTotalPoints: 115 # 70 from questions + up to 45 from discovering XSS vectors diff --git a/backend/lessons/configs/social-engineering-password.yaml b/backend/lessons/configs/social-engineering-password.yaml new file mode 100644 index 0000000..9874033 --- /dev/null +++ b/backend/lessons/configs/social-engineering-password.yaml @@ -0,0 +1,290 @@ +lessonKey: "social-engineering-password" +title: "Social Engineering - Passwortsicherheit" +description: "Lernen Sie, wie persönliche Informationen aus sozialen Medien zu schwachen Passwörtern führen können" +difficultyLevel: "beginner" +estimatedDuration: 20 +module: "social-engineering-password" + +steps: + - id: "intro" + type: "content" + title: "Was ist Social Engineering?" + content: | + Social Engineering ist eine Manipulation von Menschen, um vertrauliche Informationen preiszugeben oder Sicherheitsmaßnahmen zu umgehen. Anders als technische Angriffe zielen Social-Engineering-Angriffe auf die menschliche Psychologie ab. + + **Häufige Social-Engineering-Taktiken:** + • Informationen aus sozialen Medien sammeln (OSINT) + • Persönliche Details für Passwörter nutzen + • Vertrauen ausnutzen + • Dringlichkeit vortäuschen + • Autorität vortäuschen + • Neugier ausnutzen + + **Warum ist das gefährlich?** + Menschen teilen freiwillig Informationen in sozialen Medien, die Angreifer nutzen können: + • Namen von Haustieren + • Geburtsdaten von Kindern + • Lieblingsorte oder -teams + • Geburtstage und Jubiläen + • Arbeitgeber und Positionen + • Hobbys und Interessen + + Diese Informationen können verwendet werden, um: + • Passwörter zu erraten + • Sicherheitsfragen zu beantworten + • Phishing-Angriffe zu personalisieren + • Vertrauen zu gewinnen + + - id: "osint" + type: "content" + title: "OSINT - Open Source Intelligence" + content: | + Open Source Intelligence (OSINT) bezeichnet das Sammeln von Informationen aus öffentlich zugänglichen Quellen. Soziale Medien sind eine Goldgrube für OSINT. + + **Was Angreifer aus Social Media lernen können:** + + **Facebook/Instagram:** + • Freunde und Familienmitglieder + • Wohnort und Arbeitgeber + • Reisen und Aufenthaltsorte + • Haustiere (oft mit Namen) + • Kinder (oft mit Alter/Geburtsjahr) + • Hobbys und Interessen + + **LinkedIn:** + • Vollständige Berufshistorie + • Bildungsweg + • Fähigkeiten und Zertifizierungen + • Geschäftskontakte + • Arbeitszeiten und Verantwortlichkeiten + + **Twitter/X:** + • Echtzeitaktivitäten + • Politische Ansichten + • Tägliche Routinen + • Technologie-Präferenzen + + **Wie wird das ausgenutzt?** + + 1. **Passwort-Erraten:** + • Haustiername + Geburtsjahr des Kindes + • Lieblingsverein + Hochzeitsjahr + • Spitzname + Hausnummer + + 2. **Sicherheitsfragen:** + • "Name Ihres ersten Haustieres?" → Auf Instagram gepostet + • "Geburtsort Ihrer Mutter?" → Im Profil erwähnt + • "Name Ihrer ersten Schule?" → LinkedIn Bildung + + 3. **Spear-Phishing:** + • Personalisierte E-Mails mit echten Details + • Vorwand, der auf Interessen basiert + • Zeitlich abgestimmte Angriffe (wenn Sie im Urlaub sind) + + **Beispiel:** + Ein Angreifer sieht auf Instagram: + • Post über Hund "Max" (2019) + • Post über Zwillinge "Emma & Liam" (geboren 2020) + • Lieblingsverein "FC Bayern" + + Mögliche Passwörter zum Testen: + • max2019 + • emma2020 + • bayern2020 + • maxbayern + • emmaliam + + - id: "social-media-demo" + type: "interactive" + title: "Social Media Profil & Passwort-Demo" + interactiveComponent: "SocialMediaPasswordDemo" + content: | + Unten sehen Sie ein simuliertes Social-Media-Profil einer fiktiven Person namens Sophia Müller. Ihre Aufgabe ist es, ihr Passwort zu erraten, indem Sie Informationen aus ihren Posts verwenden. + + **Anleitung:** + 1. Lesen Sie die Posts im Social-Media-Profil sorgfältig + 2. Achten Sie auf persönliche Details (Namen, Jahreszahlen, etc.) + 3. Versuchen Sie, das Passwort im Login-Formular zu erraten + 4. Nutzen Sie die Hinweise, wenn Sie feststecken + + Dies demonstriert, wie leicht Passwörter erraten werden können, wenn sie auf öffentlich verfügbaren Informationen basieren. + + - id: "question-1" + type: "question" + questionType: "multiple_choice" + question: "Welche Informationen aus Social-Media-Profilen können für Passwörter missbraucht werden?" + options: + - id: "pet-names" + text: "Namen von Haustieren" + isCorrect: true + points: 10 + - id: "birth-years" + text: "Geburtsjahre von Kindern" + isCorrect: true + points: 10 + - id: "favorite-teams" + text: "Lieblingssportvereine oder -teams" + isCorrect: true + points: 10 + - id: "profile-picture" + text: "Das Profilbild selbst" + isCorrect: false + points: 0 + - id: "anniversaries" + text: "Hochzeitstage oder Jubiläen" + isCorrect: true + points: 10 + maxPoints: 40 + feedback: + correct: "Richtig! Alle diese persönlichen Informationen werden häufig in unsicheren Passwörtern verwendet und sind leicht aus Social-Media-Profilen zu extrahieren." + partial: "Gut! Sie haben einige der gefährlichen Informationen erkannt. Denken Sie daran, dass fast alle persönlichen Details missbraucht werden können." + incorrect: "Überprüfen Sie das Demo. Namen, Jahreszahlen und persönliche Vorlieben aus Social Media können alle für Passwörter verwendet werden." + + - id: "password-patterns" + type: "content" + title: "Häufige Passwort-Muster" + content: | + **Die häufigsten unsicheren Passwort-Muster:** + + **1. Name + Jahreszahl** + • bella2018 + • max2020 + • luna2019 + Warum unsicher: Beide Teile sind oft öffentlich bekannt + + **2. Wort + einfache Ziffernfolge** + • passwort123 + • sommer2024 + • welcome1 + Warum unsicher: Sehr vorhersagbar, oft in Wörterbüchern + + **3. Tastaturmuster** + • qwertz + • asdfgh + • 123456 + Warum unsicher: Erste Option bei Brute-Force-Angriffen + + **4. Persönliche Informationen** + • vorname.nachname + • geburtsdatum + • telefonnummer + Warum unsicher: Leicht zu recherchieren + + **5. Einfache Substitutionen** + • P@ssw0rt (Passwort) + • H3ll0 (Hello) + Warum unsicher: Angreifer kennen diese Tricks + + **Statistiken:** + • 73% der Menschen verwenden Passwörter, die persönliche Informationen enthalten + • 50% der Passwörter sind kürzer als 10 Zeichen + • 35% verwenden denselben Passwort-Typen überall + • Die häufigsten Passwort-Bestandteile: + 1. Namen (Personen, Haustiere) + 2. Geburtsjahre + 3. Einfache Wörter ("Passwort", "Admin") + 4. Zahlenfolgen (123456, 111111) + 5. Sportvereine oder Marken + + **Warum verwenden Menschen schwache Passwörter?** + • Leicht zu merken + • Bequemlichkeit + • Mangelndes Sicherheitsbewusstsein + • Zu viele Konten zum Verwalten + • Unterschätzung des Risikos + + - id: "question-2" + type: "question" + questionType: "single_choice" + question: "Was ist die BESTE Methode für sichere Passwörter?" + options: + - id: "same-password" + text: "Ein sehr langes Passwort für alle Konten verwenden" + isCorrect: false + points: 0 + - id: "password-manager" + text: "Einen Passwort-Manager mit zufällig generierten Passwörtern verwenden" + isCorrect: true + points: 30 + - id: "write-down" + text: "Komplexe Passwörter aufschreiben und sicher aufbewahren" + isCorrect: false + points: 0 + - id: "substitution" + text: "Wörter mit Zahlen und Sonderzeichen ersetzen (z.B. P@ssw0rt)" + isCorrect: false + points: 0 + maxPoints: 30 + feedback: + correct: "Ausgezeichnet! Passwort-Manager generieren einzigartige, zufällige Passwörter für jedes Konto und speichern sie verschlüsselt. Sie müssen sich nur ein Master-Passwort merken." + incorrect: "Passwort-Manager sind die beste Lösung. Sie generieren starke, zufällige Passwörter für jedes Konto, sodass Sie sich nur ein Master-Passwort merken müssen. Einfache Substitutionen oder wiederverwendete Passwörter sind nicht sicher." + + - id: "digital-footprint" + type: "content" + title: "Digitaler Fußabdruck und Privatsphäre" + content: | + **Was Sie NICHT in Social Media teilen sollten:** + + **🚫 Vermeiden Sie diese Informationen:** + + **Passwort-relevante Details:** + • Namen von Haustieren (besonders mit Geburtsjahren) + • Geburtsdaten von Kindern + • Mädchenname der Mutter + • Erste Schule oder Wohnort + • Lieblingsteam oder -verein + • Hochzeitsdatum + • Wichtige Jubiläen + + **Sicherheitsrelevante Details:** + • Vollständige Adresse + • Reisepläne (vor der Reise) + • Arbeitspläne und Routinen + • Finanzdaten oder Erfolge + • Vollständiges Geburtsdatum + • Telefonnummer + • E-Mail-Adresse (öffentlich) + + **Kinder-bezogene Informationen:** + • Vollständige Namen und Alter + • Schule oder Kindergarten + • Routinen und Zeitpläne + • Genauer Wohnort + • Fotos mit Standort-Tags + + **Best Practices für Social Media:** + + **✅ Datenschutz-Einstellungen:** + • Profil auf "privat" stellen + • Freundesliste verbergen + • Standortdienste deaktivieren + • Gesichtserkennung deaktivieren + • Suchmaschinen-Indexierung verhindern + + **✅ Vorsichtiges Teilen:** + • Überlegen Sie, wer es sehen kann + • Posten Sie Urlaubsfotos NACH der Rückkehr + • Verwenden Sie Spitznamen statt echte Namen + • Vermeiden Sie detaillierte Standortangaben + • Keine Fotos von Haus/Auto mit erkennbaren Merkmalen + + **✅ Regelmäßige Überprüfung:** + • Alte Posts durchgehen und löschen + • Freundesliste aufräumen + • Datenschutz-Einstellungen aktualisieren + • Verknüpfte Apps überprüfen + • Suchmaschinen-Ergebnisse für Ihren Namen prüfen + + **Denken Sie daran:** + Alles, was Sie online posten, kann: + • Für immer gespeichert werden + • Screenshot und geteilt werden + • Von Arbeitgebern gefunden werden + • Gegen Sie verwendet werden + • Nicht vollständig gelöscht werden + + **"Wenn Sie es nicht jedem Fremden auf der Straße erzählen würden, posten Sie es nicht online!"** + +scoring: + passingScore: 65 + maxTotalPoints: 130 # 70 from questions + 30-60 from cracking password (based on attempts) diff --git a/backend/lessons/configs/sql-injection-shop.yaml b/backend/lessons/configs/sql-injection-shop.yaml index e9b4438..e1f9b30 100644 --- a/backend/lessons/configs/sql-injection-shop.yaml +++ b/backend/lessons/configs/sql-injection-shop.yaml @@ -1,6 +1,6 @@ lessonKey: "sql-injection-shop" -title: "SQL Injection Attack - Online Shop Demo" -description: "Learn how SQL injection vulnerabilities work through a realistic online shop scenario" +title: "SQL Injection Angriff - Online Shop Demo" +description: "Lernen Sie, wie SQL Injection-Schwachstellen funktionieren, anhand eines realistischen Online-Shop-Szenarios" difficultyLevel: "intermediate" estimatedDuration: 20 module: "sql-injection-shop" @@ -8,30 +8,30 @@ module: "sql-injection-shop" steps: - id: "intro" type: "content" - title: "What is SQL Injection?" + title: "Was ist SQL Injection?" content: | - SQL Injection is one of the most dangerous web application vulnerabilities. It occurs when an attacker can insert malicious SQL code into a query, allowing them to: + SQL Injection ist eine der gefährlichsten Schwachstellen in Webanwendungen. Sie tritt auf, wenn ein Angreifer bösartigen SQL-Code in eine Abfrage einfügen kann, wodurch er folgendes tun kann: - • Access unauthorized data - • Modify or delete database records - • Bypass authentication - • Execute administrative operations + • Auf nicht autorisierte Daten zugreifen + • Datenbankeinträge ändern oder löschen + • Authentifizierung umgehen + • Administrative Operationen ausführen - In this lesson, you'll explore a vulnerable online shop to understand how SQL injection works and why proper input validation is critical. + In dieser Lektion werden Sie einen verwundbaren Online-Shop erkunden, um zu verstehen, wie SQL Injection funktioniert und warum korrekte Eingabevalidierung entscheidend ist. - id: "shop-demo" type: "interactive" - title: "Vulnerable Online Shop" + title: "Verwundbarer Online-Shop" interactiveComponent: "SQLShopDemo" content: | - Below is a simplified online shop with a product search feature. The search functionality is vulnerable to SQL injection. + Unten sehen Sie einen vereinfachten Online-Shop mit einer Produktsuchfunktion. Die Suchfunktion ist anfällig für SQL Injection. - Try searching for normal products first, then experiment with SQL injection techniques. + Versuchen Sie zunächst, nach normalen Produkten zu suchen, und experimentieren Sie dann mit SQL Injection-Techniken. - id: "question-1" type: "question" questionType: "multiple_choice" - question: "Which of the following search inputs could be used to exploit SQL injection?" + question: "Welche der folgenden Sucheingaben könnten verwendet werden, um SQL Injection auszunutzen?" options: - id: "normal-search" text: "laptop" @@ -51,93 +51,79 @@ steps: points: 10 maxPoints: 40 feedback: - correct: "Correct! These inputs manipulate the SQL query structure." - incorrect: "Review the demo. SQL injection exploits use special characters like quotes and SQL keywords." + correct: "Richtig! Diese Eingaben manipulieren die SQL-Abfragestruktur." + incorrect: "Überprüfen Sie die Demo. SQL Injection-Exploits verwenden Sonderzeichen wie Anführungszeichen und SQL-Schlüsselwörter." - id: "detection" type: "content" - title: "How SQL Injection Works" + title: "Wie SQL Injection funktioniert" content: | - A vulnerable query might look like: + Eine verwundbare Abfrage könnte so aussehen: SELECT * FROM products WHERE name LIKE '%[USER_INPUT]%' - When a user searches for "laptop", the query becomes: + Wenn ein Benutzer nach "laptop" sucht, wird die Abfrage zu: SELECT * FROM products WHERE name LIKE '%laptop%' - But if they enter "' OR '1'='1", it becomes: + Wenn er aber "' OR '1'='1" eingibt, wird sie zu: SELECT * FROM products WHERE name LIKE '%' OR '1'='1%' - The OR '1'='1' condition is always true, so ALL products are returned! + Die Bedingung OR '1'='1' ist immer wahr, also werden ALLE Produkte zurückgegeben! - More dangerous attacks can extract data from other tables or even delete data. + Gefährlichere Angriffe können Daten aus anderen Tabellen extrahieren oder sogar Daten löschen. - id: "question-2" type: "question" questionType: "single_choice" - question: "What is the BEST way to prevent SQL injection vulnerabilities?" + question: "Was ist der BESTE Weg, um SQL Injection-Schwachstellen zu verhindern?" options: - id: "input-filtering" - text: "Filter out dangerous characters like quotes and semicolons" + text: "Gefährliche Zeichen wie Anführungszeichen und Semikolons herausfiltern" isCorrect: false points: 0 - id: "parameterized-queries" - text: "Use parameterized queries (prepared statements)" + text: "Parametrisierte Abfragen (Prepared Statements) verwenden" isCorrect: true points: 30 - id: "stored-procedures" - text: "Only use stored procedures for database access" + text: "Nur gespeicherte Prozeduren für den Datenbankzugriff verwenden" isCorrect: false points: 0 - id: "input-length" - text: "Limit the length of user inputs" + text: "Die Länge von Benutzereingaben begrenzen" isCorrect: false points: 0 maxPoints: 30 feedback: - correct: "Excellent! Parameterized queries separate SQL code from user data, making injection impossible." - incorrect: "While filtering helps, parameterized queries are the gold standard. They ensure user input is always treated as data, never as SQL code." + correct: "Ausgezeichnet! Parametrisierte Abfragen trennen SQL-Code von Benutzerdaten und machen Injection unmöglich." + incorrect: "Während Filterung hilft, sind parametrisierte Abfragen der Goldstandard. Sie stellen sicher, dass Benutzereingaben immer als Daten behandelt werden, niemals als SQL-Code." - id: "mitigation" type: "content" - title: "Preventing SQL Injection" + title: "SQL Injection verhindern" content: | - Best practices to prevent SQL injection: + Best Practices zur Verhinderung von SQL Injection: - 1. **Parameterized Queries** (Most Important) - • Use prepared statements with bound parameters - • Never concatenate user input into SQL strings + 1. **Parametrisierte Abfragen** (Am wichtigsten) + • Prepared Statements mit gebundenen Parametern verwenden + • Niemals Benutzereingaben in SQL-Strings konkatenieren - 2. **Input Validation** - • Validate data types (numbers, emails, etc.) - • Use allowlists for expected values + 2. **Eingabevalidierung** + • Datentypen validieren (Zahlen, E-Mails, etc.) + • Allowlists für erwartete Werte verwenden - 3. **Least Privilege** - • Database accounts should have minimal permissions - • Read-only accounts for read operations + 3. **Minimale Berechtigungen** + • Datenbankkonten sollten minimale Berechtigungen haben + • Nur-Lese-Konten für Leseoperationen 4. **Web Application Firewalls** - • Can detect and block SQL injection attempts - • Should be used as an additional layer, not primary defense + • Können SQL Injection-Versuche erkennen und blockieren + • Sollten als zusätzliche Ebene verwendet werden, nicht als primäre Verteidigung - 5. **Regular Security Audits** - • Code reviews and penetration testing - • Automated vulnerability scanning - - - id: "question-3" - type: "question" - questionType: "free_text" - question: "In your own words, explain why parameterized queries prevent SQL injection." - validationRules: - keywords: - required: ["parameter", "data", "separate"] - partialCredit: 10 - minLength: 50 - maxPoints: 30 - feedback: - correct: "Great explanation! You understand that parameterized queries keep SQL structure separate from user data." - incorrect: "Think about how parameterized queries treat user input differently than string concatenation. Key concepts: separation of code and data." + 5. **Regelmäßige Sicherheitsaudits** + • Code-Reviews und Penetrationstests + • Automatisiertes Schwachstellen-Scanning scoring: - passingScore: 70 - maxTotalPoints: 100 + passingScore: 90 + maxTotalPoints: 180 # 70 from questions + up to 110 from 3 simplified challenges (30+40+80) with time bonuses diff --git a/backend/lessons/configs/xss-comprehensive.yaml b/backend/lessons/configs/xss-comprehensive.yaml new file mode 100644 index 0000000..450d2f9 --- /dev/null +++ b/backend/lessons/configs/xss-comprehensive.yaml @@ -0,0 +1,387 @@ +lessonKey: "xss-comprehensive" +title: "Cross-Site Scripting (XSS) - Reflected & Stored Angriffe" +description: "Lernen Sie, wie XSS-Angriffe durch URL-Manipulation und benutzergenerierte Inhalte funktionieren und wie man sie erkennt" +difficultyLevel: "intermediate" +estimatedDuration: 35 +module: "xss-comprehensive" + +steps: + - id: "intro" + type: "content" + title: "Was ist Cross-Site Scripting (XSS)?" + content: | + Cross-Site Scripting (XSS) ist eine Sicherheitslücke, die es Angreifern ermöglicht, bösartigen JavaScript-Code in Webseiten einzuschleusen, die von anderen Benutzern angesehen werden. + + XSS kann auftreten, wenn: + • Benutzereingaben ohne ordnungsgemäße Bereinigung angezeigt werden + • URL-Parameter im Seiteninhalt wiedergegeben werden + • Benutzergenerierte Inhalte als HTML gerendert werden + + **Arten von XSS:** + • **Reflected XSS** - Payload ist Teil der Anfrage (z.B. URL-Parameter) + • **Stored XSS** - Payload wird in der Datenbank gespeichert und anderen Benutzern angezeigt + • **DOM-basiertes XSS** - Payload manipuliert direkt das Document Object Model + + **Was Angreifer mit XSS tun können:** + • Session-Cookies stehlen und Konten übernehmen + • Benutzer auf Phishing-Seiten umleiten + • Websites verunstalten + • Keylogger installieren + • Auf sensible Daten zugreifen + • Malware verteilen + + - id: "reflected-xss" + type: "content" + title: "Reflected XSS - URL-Parameter-Injection" + content: | + **Wie URL-Parameter funktionieren:** + + Viele Websites verwenden URL-Parameter (auch Query-Strings genannt), um Daten zu übergeben: + + https://beispiel-shop.com/produkt?name=Laptop&kategorie=Elektronik + + In dieser URL: + • name=Laptop ist ein Parameter + • kategorie=Elektronik ist ein weiterer Parameter + + **Deeplinks:** + Deeplinks sind URLs, die direkt auf bestimmte Inhalte innerhalb einer Website oder App verlinken. Sie enthalten oft Parameter, die den angezeigten Inhalt anpassen. + + **Die Sicherheitslücke:** + Wenn eine Website URL-Parameterwerte ohne Bereinigung anzeigt, kann ein Angreifer bösartigen Code einschleusen: + + https://beispiel-shop.com/produkt?name= + + Wenn die Seite den "name"-Parameter anzeigt, wird das Skript ausgeführt! + + **Wie Reflected XSS funktioniert:** + + Wenn eine anfällige Anwendung empfängt: + https://shop.com/suche?q= + + Und es so anzeigt: +
    Suchergebnisse fĂźr:
    + + Der Browser führt das Script-Tag aus und führt den Code des Angreifers aus! + + - id: "xss-demo" + type: "interactive" + title: "Reflected XSS Demo" + interactiveComponent: "XSSDeeplinkDemo" + content: | + Unten sehen Sie eine Demonstration, wie Reflected XSS durch URL-Parameter-Injection funktioniert. Die anfällige Version zeigt Benutzereingaben direkt an, während die sichere Version Sonderzeichen kodiert. + + Probieren Sie die Beispiel-Payloads aus, um zu sehen, wie verschiedene XSS-Techniken funktionieren. Beachten Sie, wie die Kodierung verhindert, dass der bösartige Code ausgeführt wird. + + - id: "question-1" + type: "question" + questionType: "multiple_choice" + question: "Welche der folgenden sind gültige XSS-Payloads, die über URL-Parameter eingeschleust werden können?" + options: + - id: "script-alert" + text: "" + isCorrect: true + points: 6 + - id: "img-onerror" + text: "" + isCorrect: true + points: 6 + - id: "svg-onload" + text: "" + isCorrect: true + points: 6 + - id: "iframe-src" + text: "" + isCorrect: true + points: 7 + - id: "normal-text" + text: "Nur ein normaler Produktname" + isCorrect: false + points: 0 + maxPoints: 25 + feedback: + correct: "Ausgezeichnet! Sie haben alle XSS-Payloads identifiziert. Diese Muster können JavaScript in anfälligen Anwendungen ausführen." + partial: "Gut! Sie haben einige XSS-Payloads erkannt. Überprüfen Sie die Muster: Script-Tags, Event-Handler und Protocol-Injections." + incorrect: "Schauen Sie sich die Demo an und suchen Sie nach Mustern, die HTML-Tags, Event-Handler oder JavaScript-Protokolle enthalten." + + - id: "stored-xss" + type: "content" + title: "Stored XSS - Persistente Angriffe" + content: | + Stored XSS (Cross-Site Scripting) ist eine Art von Injection-Angriff, bei dem bösartige Skripte dauerhaft auf einem Zielserver gespeichert werden. Im Gegensatz zu Reflected XSS, bei dem das Opfer auf einen bösartigen Link klicken muss, betrifft Stored XSS alle Benutzer, die den kompromittierten Inhalt ansehen. + + **Häufige Ziele:** + • Forum-Beiträge und Kommentare + • Benutzerprofile und Biografien + • Produktbewertungen + • Feedback-Formulare + • Social-Media-Beiträge + • Blog-Kommentare + • Wiki-Seiten + + **Auswirkungen:** + • Cookie-Diebstahl und Session-Hijacking + • Kontoübernahme + • Malware-Verteilung + • Website-Verunstaltung + • Phishing-Angriffe auf andere Benutzer + • Keylogging + • Datendiebstahl + + **Warum Stored XSS besonders gefährlich ist:** + 1. Es bleibt in der Datenbank bestehen + 2. Es betrifft automatisch mehrere Benutzer + 3. Es erfordert kein Social Engineering zur Verbreitung + 4. Es kann über lange Zeiträume unentdeckt bleiben + + - id: "real-world" + type: "content" + title: "Reale Stored-XSS-Angriffe" + content: | + **Samy Worm (MySpace, 2005)** + Samy Kamkar erstellte einen sich selbst verbreitenden XSS-Wurm in seinem MySpace-Profil, der ihn automatisch als Freund zu jedem Profil hinzufügte, das ihn ansah. Der Wurm kopierte sich auch auf jedes infizierte Profil und verbreitete sich exponentiell. + + Innerhalb von 20 Stunden waren über 1 Million Benutzer betroffen, was Samy zur beliebtesten Person auf MySpace machte. Die Website musste offline genommen werden, um den Wurm zu entfernen. + + **TweetDeck XSS (Twitter, 2014)** + Eine Stored-XSS-Schwachstelle in TweetDeck ermöglichte es Angreifern, bösartigen Code über Tweets einzuschleusen. Als andere Benutzer diese Tweets in TweetDeck ansahen, wurde der Code automatisch ausgeführt und verursachte: + • Automatische Retweets der bösartigen Payload + • Pop-up-Benachrichtigungen für alle Betrachter + • Schnelle Verbreitung über die Plattform + + **eBay Stored XSS (2015-2016)** + Mehrere Stored-XSS-Schwachstellen wurden in den Artikelbeschreibungen von eBay entdeckt. Angreifer konnten: + • Code in Produktbeschreibungen einschleusen + • Benutzeranmeldeinformationen stehlen, wenn Käufer Angebote ansahen + • Benutzer auf Phishing-Seiten umleiten + • Konten von Käufern und Verkäufern kompromittieren + + **British Airways XSS (2018)** + Angreifer schleusten bösartiges JavaScript über eine Stored-XSS-Schwachstelle in die Zahlungsseite von British Airways ein. Das Skript: + • Erfasste Kreditkarteninformationen + • Sendete Daten an vom Angreifer kontrollierte Server + • Betraf über 380.000 Transaktionen + • Kostete British Airways über 20 Millionen Pfund an Strafen + + Diese Angriffe demonstrieren, warum Eingabevalidierung und Output-Encoding für jede Anwendung, die benutzergenerierte Inhalte akzeptiert, kritisch sind. + + - id: "forum-demo" + type: "interactive" + title: "Stored XSS Forum Demo" + interactiveComponent: "ForumScriptDemo" + content: | + Unten sehen Sie ein vereinfachtes Forum, das Benutzerkommentare OHNE ordnungsgemäße Eingabevalidierung oder Output-Encoding akzeptiert. Versuchen Sie zuerst, normale Kommentare zu posten, und experimentieren Sie dann mit Script-Injection-Payloads. + + Beachten Sie, wie die bösartigen Skripte gespeichert werden und alle Benutzer betreffen würden, die das Forum ansehen. In dieser Demo zeigen wir die Payloads sicher als Text an, anstatt sie auszuführen, mit klaren Warnungen, wenn eine Injection erkannt wird. + + **Probieren Sie diese Aktionen:** + 1. Posten Sie einen normalen Kommentar, um sicheres Verhalten zu sehen + 2. Versuchen Sie Beispiel-XSS-Payloads, um die Erkennung zu sehen + 3. Verwenden Sie die Reload-Schaltfläche, um das Forum zurückzusetzen + + - id: "question-2" + type: "question" + questionType: "multiple_choice" + question: "Welche der folgenden Payloads könnten für Stored-XSS-Angriffe in einem Forum verwendet werden?" + options: + - id: "script-cookie" + text: "" + isCorrect: true + points: 6 + - id: "img-steal" + text: "" + isCorrect: true + points: 6 + - id: "svg-payload" + text: "" + isCorrect: true + points: 6 + - id: "iframe-phishing" + text: "" + isCorrect: true + points: 7 + - id: "normal-comment" + text: "Dies ist ein normaler Kommentar ohne bösartigen Code" + isCorrect: false + points: 0 + maxPoints: 25 + feedback: + correct: "Ausgezeichnet! Sie haben alle gefährlichen Payloads identifiziert, die auf dem Server bestehen bleiben und mehrere Benutzer betreffen können." + partial: "Gut! Sie haben einige Bedrohungen erkannt, aber überprüfen Sie die Muster, die Code-Ausführung durch HTML-Tags und Event-Handler ermöglichen." + incorrect: "Überprüfen Sie die Demo. Suchen Sie nach Mustern, die Script-Tags, Event-Handler wie onerror oder onload oder eingebettete Inhalte wie iframes enthalten." + + - id: "attack-vectors" + type: "content" + title: "XSS-Angriffsvektoren" + content: | + Gängige Techniken, die Angreifer bei XSS-Angriffen verwenden: + + **1. Cookie-Diebstahl** + + Stiehlt Authentifizierungs-Cookies und ermöglicht Kontoübernahme. Der Angreifer kann dann jeden Benutzer imitieren, der den Kommentar angesehen hat. + + **2. Session-Hijacking** + + Extrahiert Session-Token aus dem Browser-Speicher und kompromittiert Benutzersitzungen. + + **3. Keylogging** + + Zeichnet jeden Tastendruck auf der Seite auf und erfasst Passwörter und sensible Informationen. + + **4. Verunstaltung** + + Ändert den sichtbaren Inhalt für alle Benutzer und beschädigt Reputation und Vertrauen. + + **5. Phishing-Overlay** +
    +
    +

    Sitzung abgelaufen - Bitte erneut anmelden

    + Benutzername:
    + Passwort:
    + +
    +
    + Zeigt ein gefälschtes Login-Formular über der echten Seite an und erfasst Anmeldeinformationen. + + **6. Kryptowährungs-Mining** + + Mined heimlich Kryptowährung mit den CPU-Ressourcen der Besucher. + + **7. Malware-Verteilung** + + Leitet Benutzer zu Malware-Downloads oder Drive-by-Download-Angriffen um. + + - id: "question-3" + type: "question" + questionType: "single_choice" + question: "Warum gilt Stored XSS im Allgemeinen als GEFÄHRLICHER als Reflected XSS?" + options: + - id: "easier-exploit" + text: "Es ist einfacher auszunutzen, da es keine Sonderzeichen erfordert" + isCorrect: false + points: 0 + - id: "persistent-victims" + text: "Es bleibt auf dem Server bestehen und betrifft alle Benutzer, die den Inhalt ansehen, nicht nur diejenigen, die auf einen bösartigen Link klicken" + isCorrect: true + points: 30 + - id: "no-detection" + text: "Es kann nicht von Sicherheitstools oder Antiviren-Software erkannt werden" + isCorrect: false + points: 0 + - id: "admin-access" + text: "Es gewährt Angreifern automatisch Administratorzugriff auf den Server" + isCorrect: false + points: 0 + maxPoints: 30 + feedback: + correct: "Perfekt! Stored XSS ist eine persistente Bedrohung, die viele Benutzer über die Zeit betreffen kann, ohne dass eine individuelle Zielerfassung erforderlich ist. Es bleibt in der Datenbank und wird jedes Mal ausgeführt, wenn jemand es ansieht." + incorrect: "Denken Sie über den Unterschied zwischen einer Payload, die an jedes Opfer gesendet werden muss, und einer, die einmal gespeichert wird und jeden betrifft. Persistenz und automatische Verbreitung sind die Hauptgefahren." + + - id: "prevention" + type: "content" + title: "XSS-Angriffe verhindern" + content: | + **Defense-in-Depth-Ansatz:** + + **1. Output-Encoding (Am wichtigsten)** + Kodieren Sie Ausgaben immer kontextabhängig: + + • **HTML-Kontext:** < wird zu <, > wird zu > + • **JavaScript-Kontext:** Verwenden Sie JSON.stringify() für Daten + • **URL-Kontext:** Verwenden Sie encodeURIComponent() + • **CSS-Kontext:** Vermeiden Sie Benutzereingaben in CSS + + **Vertrauen Sie niemals Inhalten aus der Datenbank** - selbst wenn sie bei der Eingabe validiert wurden, kodieren Sie immer bei der Ausgabe! + + **2. Content Security Policy (CSP)** + Setzen Sie HTTP-Header, um Script-Quellen einzuschränken: + + Content-Security-Policy: + default-src 'self'; + script-src 'self' 'nonce-{random}'; + object-src 'none'; + base-uri 'self'; + form-action 'self'; + + CSP-Vorteile: + • Verhindert Ausführung von Inline-Skripten + • Beschränkt Ressourcen-Laden auf vertrauenswürdige Quellen + • Mindert Auswirkungen, selbst wenn XSS durchkommt + • Bietet Verletzungsberichte zur Überwachung + + **3. Eingabevalidierung** + • Validieren Sie alle Benutzereingaben gegen das erwartete Format + • Verwenden Sie Allowlists für akzeptable Zeichen + • Lehnen Sie Eingaben ab, die verdächtige Muster enthalten + • Validieren Sie Datentyp, Länge und Format + • Vertrauen Sie niemals allein auf clientseitige Validierung + + **4. HTTPOnly und Secure Cookies** + Setzen Sie das HTTPOnly-Flag auf Session-Cookies: + Set-Cookie: sessionId=abc123; + HttpOnly; + Secure; + SameSite=Strict + + • **HttpOnly** - Verhindert JavaScript-Zugriff auf Cookies + • **Secure** - Stellt HTTPS-only-Übertragung sicher + • **SameSite** - Verhindert CSRF-Angriffe + + Dies verhindert, dass JavaScript auf Cookies zugreift und begrenzt die Auswirkungen von XSS. + + **5. Web Application Firewall (WAF)** + • Kann XSS-Versuche erkennen und blockieren + • Sollte als zusätzliche Ebene verwendet werden, nicht als primäre Verteidigung + • Bietet Überwachung und Alarmierung + • Updates zum Blockieren neuer Angriffsmuster + + **6. Regelmäßige Sicherheitsaudits** + • Statische Code-Analyse (SAST-Tools) + • Dynamische Sicherheitstests (DAST-Tools) + • Penetrationstests + • Code-Reviews mit Fokus auf Benutzereingabe-Verarbeitung + • Sicherheitsbewusstseins-Schulungen + + - id: "question-4" + type: "question" + questionType: "single_choice" + question: "Was ist der EFFEKTIVSTE Weg, XSS-Angriffe zu verhindern?" + options: + - id: "input-length" + text: "Die Länge der Benutzereingabe begrenzen" + isCorrect: false + points: 0 + - id: "output-encoding" + text: "Alle Ausgaben kodieren und Content Security Policy (CSP) implementieren" + isCorrect: true + points: 20 + - id: "remove-tags" + text: "Alle HTML-Tags aus Benutzereingaben entfernen" + isCorrect: false + points: 0 + - id: "client-validation" + text: "Nur clientseitige JavaScript-Validierung verwenden" + isCorrect: false + points: 0 + maxPoints: 20 + feedback: + correct: "Perfekt! Output-Encoding wandelt Sonderzeichen um, sodass Browser sie als Text und nicht als Code behandeln. CSP bietet eine zusätzliche Sicherheitsebene." + incorrect: "Während Eingabefilterung helfen kann, ist Output-Encoding unerlässlich. Sonderzeichen wie < und > müssen in < und > umgewandelt werden, damit Browser sie als Text anzeigen, anstatt sie als HTML auszuführen." + +scoring: + passingScore: 70 + maxTotalPoints: 100 diff --git a/backend/lessons/configs/xss-deeplink-demo.yaml b/backend/lessons/configs/xss-deeplink-demo.yaml new file mode 100644 index 0000000..78209c8 --- /dev/null +++ b/backend/lessons/configs/xss-deeplink-demo.yaml @@ -0,0 +1,211 @@ +lessonKey: "xss-deeplink-demo" +title: "Cross-Site Scripting (XSS) - Deeplink Injection" +description: "Lernen Sie, wie XSS-Angriffe durch URL-Parameter-Manipulation und Deeplink-Injection funktionieren" +difficultyLevel: "intermediate" +estimatedDuration: 20 +module: "xss-deeplink-demo" + +steps: + - id: "intro" + type: "content" + title: "Was ist Cross-Site Scripting (XSS)?" + content: | + Cross-Site Scripting (XSS) ist eine Sicherheitslücke, die es Angreifern ermöglicht, bösartigen JavaScript-Code in Webseiten einzuschleusen, die von anderen Benutzern angesehen werden. + + XSS kann auftreten, wenn: + • Benutzereingaben ohne ordnungsgemäße Bereinigung angezeigt werden + • URL-Parameter im Seiteninhalt wiedergegeben werden + • Benutzergenerierte Inhalte als HTML gerendert werden + + **Arten von XSS:** + • **Reflected XSS** - Payload ist Teil der Anfrage (z.B. URL-Parameter) + • **Stored XSS** - Payload wird in der Datenbank gespeichert und anderen Benutzern angezeigt + • **DOM-basiertes XSS** - Payload manipuliert direkt das Document Object Model + + **Was Angreifer mit XSS tun können:** + • Session-Cookies stehlen und Konten übernehmen + • Benutzer auf Phishing-Seiten umleiten + • Websites verunstalten + • Keylogger installieren + • Auf sensible Daten zugreifen + + - id: "url-params" + type: "content" + title: "Wie URL-Parameter funktionieren" + content: | + Viele Websites verwenden URL-Parameter (auch Query-Strings genannt), um Daten zu übergeben: + + https://beispiel-shop.com/produkt?name=Laptop&kategorie=Elektronik + + In dieser URL: + • name=Laptop ist ein Parameter + • kategorie=Elektronik ist ein weiterer Parameter + + **Deeplinks:** + Deeplinks sind URLs, die direkt auf bestimmte Inhalte innerhalb einer Website oder App verlinken. Sie enthalten oft Parameter, die den angezeigten Inhalt anpassen. + + **Die Sicherheitslücke:** + Wenn eine Website URL-Parameterwerte ohne Bereinigung anzeigt, kann ein Angreifer bösartigen Code einschleusen: + + https://beispiel-shop.com/produkt?name= + + Wenn die Seite den "name"-Parameter anzeigt, wird das Skript ausgeführt! + + - id: "xss-demo" + type: "interactive" + title: "XSS Deeplink Demo" + interactiveComponent: "XSSDeeplinkDemo" + content: | + Unten sehen Sie eine Demonstration, wie XSS durch URL-Parameter-Injection funktioniert. Die anfällige Version zeigt Benutzereingaben direkt an, während die sichere Version Sonderzeichen kodiert. + + Probieren Sie die Beispiel-Payloads aus, um zu sehen, wie verschiedene XSS-Techniken funktionieren. Beachten Sie, wie die Kodierung verhindert, dass der bösartige Code ausgeführt wird. + + - id: "question-1" + type: "question" + questionType: "multiple_choice" + question: "Welche der folgenden sind gültige XSS-Payloads, die über URL-Parameter eingeschleust werden können?" + options: + - id: "script-alert" + text: "" + isCorrect: true + points: 10 + - id: "img-onerror" + text: "" + isCorrect: true + points: 10 + - id: "svg-onload" + text: "" + isCorrect: true + points: 10 + - id: "iframe-src" + text: "" + isCorrect: true + points: 10 + - id: "normal-text" + text: "Nur ein normaler Produktname" + isCorrect: false + points: 0 + maxPoints: 40 + feedback: + correct: "Ausgezeichnet! Sie haben alle XSS-Payloads identifiziert. Diese Muster können JavaScript in anfälligen Anwendungen ausführen." + partial: "Gut! Sie haben einige XSS-Payloads erkannt. Überprüfen Sie die Muster: Script-Tags, Event-Handler und Protocol-Injections." + incorrect: "Schauen Sie sich die Demo an und suchen Sie nach Mustern, die HTML-Tags, Event-Handler oder JavaScript-Protokolle enthalten." + + - id: "detection-impact" + type: "content" + title: "XSS-Erkennung und Auswirkungen" + content: | + **Wie XSS funktioniert:** + + Wenn eine anfällige Anwendung empfängt: + https://shop.com/suche?q= + + Und es so anzeigt: +
    Suchergebnisse fĂźr:
    + + Der Browser führt das Script-Tag aus und führt den Code des Angreifers aus! + + **Auswirkungen in der Praxis:** + + **Cookie-Diebstahl:** + + Sendet die Cookies des Opfers an den Server des Angreifers. + + **Session-Hijacking:** + Sobald der Angreifer den Session-Cookie hat, kann er sich als Benutzer ausgeben und auf dessen Konto zugreifen. + + **Phishing:** + + Ersetzt die Seite durch ein gefälschtes Login-Formular. + + **Keylogging:** + + Zeichnet jeden Tastendruck auf der Seite auf. + + - id: "question-2" + type: "question" + questionType: "single_choice" + question: "Was ist der EFFEKTIVSTE Weg, XSS-Angriffe zu verhindern?" + options: + - id: "input-length" + text: "Die Länge der Benutzereingabe begrenzen" + isCorrect: false + points: 0 + - id: "output-encoding" + text: "Alle Ausgaben kodieren und Content Security Policy (CSP) implementieren" + isCorrect: true + points: 30 + - id: "remove-tags" + text: "Alle HTML-Tags aus Benutzereingaben entfernen" + isCorrect: false + points: 0 + - id: "client-validation" + text: "Nur clientseitige JavaScript-Validierung verwenden" + isCorrect: false + points: 0 + maxPoints: 30 + feedback: + correct: "Perfekt! Output-Encoding wandelt Sonderzeichen um, sodass Browser sie als Text und nicht als Code behandeln. CSP bietet eine zusätzliche Sicherheitsebene." + incorrect: "Während Eingabefilterung helfen kann, ist Output-Encoding unerlässlich. Sonderzeichen wie < und > müssen in < und > umgewandelt werden, damit Browser sie als Text anzeigen, anstatt sie als HTML auszuführen." + + - id: "mitigation" + type: "content" + title: "XSS-Angriffe verhindern" + content: | + **Best Practices:** + + **1. Output-Encoding (Am wichtigsten)** + Kodieren Sie Ausgaben immer kontextabhängig: + + • **HTML-Kontext:** < wird zu <, > wird zu > + • **JavaScript-Kontext:** Verwenden Sie JSON.stringify() für Daten + • **URL-Kontext:** Verwenden Sie encodeURIComponent() + • **CSS-Kontext:** Vermeiden Sie Benutzereingaben in CSS + + **2. Content Security Policy (CSP)** + Setzen Sie HTTP-Header, um Script-Quellen einzuschränken: + + Content-Security-Policy: + default-src 'self'; + script-src 'self' 'nonce-{random}'; + object-src 'none'; + + Dies verhindert Inline-Skripte und schränkt ein, woher Skripte geladen werden können. + + **3. Eingabevalidierung** + • Validieren Sie Datentypen (Zahlen, E-Mails, etc.) + • Verwenden Sie Allowlists für erwartete Werte + • Lehnen Sie unerwartete Muster ab + • Vertrauen Sie niemals allein auf clientseitige Validierung + + **4. Framework-Sicherheitsfunktionen** + Moderne Frameworks helfen, XSS zu verhindern: + + • **React:** Escapt JSX-Inhalte automatisch + • **Angular:** Eingebaute Bereinigung + • **Vue:** Template-Escaping standardmäßig + + ⚠️ **Verwenden Sie NIEMALS gefährliche Funktionen:** + • React: `dangerouslySetInnerHTML` + • Angular: `bypassSecurityTrust...` + • Vue: `v-html` mit Benutzerinhalten + + **5. HTTPOnly Cookies** + Setzen Sie das HTTPOnly-Flag auf Session-Cookies: + Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict + + Dies verhindert, dass JavaScript auf Cookies zugreift und begrenzt die Auswirkungen von XSS. + +scoring: + passingScore: 55 + maxTotalPoints: 110 # 70 from questions + up to 40 from discovering XSS vectors diff --git a/backend/lessons/modules/base/LessonModule.js b/backend/lessons/modules/base/LessonModule.js index a7c7a6b..0b785af 100644 --- a/backend/lessons/modules/base/LessonModule.js +++ b/backend/lessons/modules/base/LessonModule.js @@ -183,20 +183,20 @@ class LessonModule { /** * Get lesson content for rendering (without answers) */ - getContent() { - return { - lessonKey: this.lessonKey, - title: this.config.title, - description: this.config.description, - difficultyLevel: this.config.difficultyLevel, - estimatedDuration: this.config.estimatedDuration, - steps: this.config.steps.map(step => ({ + async getContent() { + // Map steps and fetch interactive data for interactive steps + const steps = await Promise.all(this.config.steps.map(async step => { + const baseStep = { id: step.id, type: step.type, title: step.title, - content: step.content, - // For question steps, don't send correct answers - ...(step.type === 'question' && { + content: step.content + }; + + // For question steps, don't send correct answers + if (step.type === 'question') { + return { + ...baseStep, questionType: step.questionType, question: step.question, maxPoints: step.maxPoints, @@ -205,13 +205,30 @@ class LessonModule { text: opt.text // isCorrect and points are intentionally omitted })) - }), - // For interactive steps, send component info - ...(step.type === 'interactive' && { + }; + } + + // For interactive steps, fetch and include interactive data + if (step.type === 'interactive') { + const interactiveData = await this.getInteractiveData(step.id); + return { + ...baseStep, interactiveComponent: step.interactiveComponent, - componentProps: step.componentProps - }) - })), + componentProps: step.componentProps, + interactiveData + }; + } + + return baseStep; + })); + + return { + lessonKey: this.lessonKey, + title: this.config.title, + description: this.config.description, + difficultyLevel: this.config.difficultyLevel, + estimatedDuration: this.config.estimatedDuration, + steps, scoring: { maxTotalPoints: this.config.scoring?.maxTotalPoints || 100, passingScore: this.config.scoring?.passingScore || 70 @@ -219,6 +236,44 @@ class LessonModule { }; } + /** + * Award points for interactive component discoveries + * This method can be called by lesson modules to award points dynamically + * @param {number} participantId - Participant ID + * @param {number} eventLessonId - Event lesson ID + * @param {number} points - Points to award + * @param {string} reason - Reason for points (for tracking) + * @returns {Promise} New total score + */ + async awardPoints(participantId, eventLessonId, points, reason) { + const progressQueries = require('../../src/models/queries/progress.queries'); + + // Get or create progress + let progress = await progressQueries.getLessonProgress(participantId, eventLessonId); + + if (!progress) { + // Auto-start lesson if not started + progress = await progressQueries.startLesson(participantId, eventLessonId); + } + + // Award points + const newScore = await progressQueries.updateScore(progress.id, points); + + // Optionally save the discovery reason for tracking + if (reason) { + await progressQueries.saveAnswer( + progress.id, + `interactive-${Date.now()}`, + { type: 'interactive', reason }, + true, + points, + reason + ); + } + + return newScore; + } + /** * Get full configuration (for debugging/admin) */ diff --git a/backend/lessons/modules/idor-demo/index.js b/backend/lessons/modules/idor-demo/index.js new file mode 100644 index 0000000..196968a --- /dev/null +++ b/backend/lessons/modules/idor-demo/index.js @@ -0,0 +1,259 @@ +const LessonModule = require('../base/LessonModule'); + +/** + * IDOR (Insecure Direct Object Reference) Demo Lesson + * Demonstrates how URL parameter manipulation can expose other users' data + */ +class IDORDemoLesson extends LessonModule { + constructor(config) { + super(config); + } + + /** + * Get mock user database + * @returns {Array} Mock user data + */ + getMockUsers() { + return [ + { + id: 1, + name: 'System Administrator', + email: 'admin@securebank.example', + accountBalance: '$999,999.99', + accountNumber: '****0001', + lastLogin: '2026-02-08 10:00', + address: '1 Admin Tower, Capital City, USA', + phone: '(555) 000-0001', + isCurrentUser: false, + accountType: 'Administrative Account', + isHighValue: true, + adminAccess: true, + isEasterEgg: true, + easterEggType: 'admin', + bonusPoints: 25, + easterEggMessage: '🎯 Admin Account Found! You discovered the system administrator account.' + }, + { + id: 42, + name: 'Douglas Adams', + email: 'dont.panic@example.com', + accountBalance: '$42,000,000.00', + accountNumber: '****4242', + lastLogin: '2026-02-07 16:45', + address: '42 Galaxy Street, Universe, Space', + phone: '(555) 424-2424', + isCurrentUser: false, + accountType: 'Millionaire Account', + isHighValue: true, + isEasterEgg: true, + easterEggType: 'millionaire', + bonusPoints: 20, + easterEggMessage: '💰 Millionaire Discovered! The answer to life, universe, and everything.' + }, + { + id: 54, + name: 'Jane Smith', + email: 'jane.smith@example.com', + accountBalance: '$45,890.50', + accountNumber: '****5454', + lastLogin: '2026-02-08 08:30', + address: '456 Oak Avenue, Springfield, USA', + phone: '(555) 234-5678', + isCurrentUser: false, + accountType: 'Premium Savings', + securityLevel: 'high', + isNeighbor: true, + bonusPoints: 10 + }, + { + id: 55, + name: 'Max Mustermann', + email: 'max.mustermann@example.com', + accountBalance: '$2,340.75', + accountNumber: '****5555', + lastLogin: '2026-02-08 09:15', + address: '123 Main Street, Anytown, USA', + phone: '(555) 123-4567', + isCurrentUser: true, + accountType: 'Standard Checking' + }, + { + id: 56, + name: 'Lisa Wagner', + email: 'lisa.w@example.com', + accountBalance: '$18,250.00', + accountNumber: '****5656', + lastLogin: '2026-02-08 07:45', + address: '789 Pine Road, Neighborhood, USA', + phone: '(555) 567-8901', + isCurrentUser: false, + accountType: 'Business Checking', + isNeighbor: true, + bonusPoints: 10 + }, + { + id: 67, + name: '¯\\_(ツ)_/¯', + email: 'mystery@example.com', + accountBalance: '$6,700.00', + accountNumber: '****6767', + lastLogin: '2026-01-01 00:00', + address: '¯\\_(ツ)_/¯', + phone: '¯\\_(ツ)_/¯', + isCurrentUser: false, + accountType: 'Mystery Account', + isEasterEgg: true, + easterEggType: 'shrug', + bonusPoints: 15, + easterEggMessage: '¯\\_(ツ)_/¯' + }, + { + id: 100, + name: 'Diana Prince', + email: 'diana.p@example.com', + accountBalance: '$125,000.00', + accountNumber: '****1000', + lastLogin: '2026-02-08 07:00', + address: '100 Hero Boulevard, Metro City, USA', + phone: '(555) 100-0001', + isCurrentUser: false, + accountType: 'Premium Investment', + securityLevel: 'maximum' + } + ]; + } + + /** + * Fetch user profile by ID (vulnerable simulation) + * Called via executeLessonAction endpoint + * @param {number} userId - User ID to fetch + * @returns {Object} User profile data or error + */ + async fetchUserProfile(userId, participantId, eventLessonId) { + const users = this.getMockUsers(); + const requestedId = parseInt(userId); + + // Find user + const user = users.find(u => u.id === requestedId); + + if (!user) { + return { + success: false, + error: 'USER_NOT_FOUND', + message: 'Benutzer nicht gefunden', + statusCode: 404 + }; + } + + // Detect unauthorized access + const isUnauthorized = !user.isCurrentUser; + + // Award points for discoveries + let pointsAwarded = 0; + let discoveryMessage = null; + + if (isUnauthorized && participantId && eventLessonId) { + // Award points for any IDOR discovery + pointsAwarded = 10; + + // Check for easter eggs and award bonus points + if (user.isEasterEgg) { + pointsAwarded += user.bonusPoints; + discoveryMessage = user.easterEggMessage; + } else if (user.isNeighbor) { + pointsAwarded += user.bonusPoints; + } + + // Award points (don't duplicate if same user accessed multiple times) + try { + await this.awardPoints(participantId, eventLessonId, pointsAwarded, + `IDOR discovered: User ${requestedId}`); + } catch (error) { + console.error('Failed to award IDOR points:', error); + } + } + + return { + success: true, + user: { + id: user.id, + name: user.name, + email: user.email, + accountBalance: user.accountBalance, + accountNumber: user.accountNumber, + lastLogin: user.lastLogin, + address: user.address, + phone: user.phone, + accountType: user.accountType, + ...(user.isHighValue && { isHighValue: true }), + ...(user.adminAccess && { adminAccess: true }), + ...(user.securityLevel && { securityLevel: user.securityLevel }) + }, + isCurrentUser: user.isCurrentUser, + isUnauthorized, + pointsAwarded: pointsAwarded > 0 ? pointsAwarded : undefined, + easterEgg: user.isEasterEgg ? { + type: user.easterEggType, + message: discoveryMessage + } : undefined, + vulnerability: isUnauthorized ? { + type: 'IDOR', + severity: user.isHighValue || user.adminAccess ? 'CRITICAL' : 'HIGH', + description: '⚠️ IDOR-Schwachstelle entdeckt!', + message: `Sie sehen ${user.name}s private Daten ohne Berechtigung!`, + impact: 'Ein Angreifer kann auf sensible Informationen eines beliebigen Benutzers zugreifen, indem er einfach den userId-Parameter in der URL ändert.', + recommendation: 'Implementieren Sie ordnungsgemäße Autorisierungsprüfungen. Überprüfen Sie, ob der authentifizierte Benutzer die Berechtigung hat, auf die angeforderte Ressource zuzugreifen.', + cve: user.isHighValue ? 'Dies ist eine kritische Schwachstelle - Admin-/Hochwertkonto aufgerufen!' : null + } : null + }; + } + + /** + * Get interactive data for IDOR demo step + * @param {string} stepId - Step identifier + * @returns {Object} Interactive component data + */ + async getInteractiveData(stepId) { + if (stepId === 'idor-demo') { + return { + baseUrl: 'https://securebank.example/profile', + currentUserId: 55, + vulnerableParameter: 'userId', + easterEggs: [ + { id: 1, type: 'admin', found: false }, + { id: 42, type: 'millionaire', found: false }, + { id: 67, type: 'shrug', found: false }, + { id: 54, type: 'neighbor', found: false }, + { id: 56, type: 'neighbor', found: false } + ], + secureApproach: { + title: 'Sichere Implementierung', + description: 'Anstelle von URL-Parametern, verwenden Sie sitzungsbasierte Authentifizierung', + example: 'GET /profile (gibt nur die Daten des authentifizierten Benutzers zurück)', + code: ` +// Anfällig (IDOR): +app.get('/profile', (req, res) => { + const userId = req.query.userId; // ❌ Jeder kann dies ändern! + const user = db.getUserById(userId); + res.json(user); +}); + +// Sicher (Sitzungsbasiert): +app.get('/profile', authenticate, (req, res) => { + const userId = req.session.userId; // ✅ Aus verifizierter Sitzung + if (req.params.userId && req.params.userId !== userId) { + return res.status(403).json({ error: 'Forbidden' }); + } + const user = db.getUserById(userId); + res.json(user); +}); + `.trim() + } + }; + } + + return await super.getInteractiveData(stepId); + } +} + +module.exports = IDORDemoLesson; diff --git a/backend/lessons/modules/script-injection-forum/index.js b/backend/lessons/modules/script-injection-forum/index.js new file mode 100644 index 0000000..dd3ea1c --- /dev/null +++ b/backend/lessons/modules/script-injection-forum/index.js @@ -0,0 +1,236 @@ +const LessonModule = require('../base/LessonModule'); + +/** + * Forum Script Injection Lesson + * Demonstrates stored XSS vulnerabilities in comment systems + */ +class ForumScriptInjectionLesson extends LessonModule { + constructor(config) { + super(config); + } + + /** + * Detect script injection in comment content + * @param {string} content - Comment content + * @returns {boolean} True if script detected + */ + detectScriptInjection(content) { + const patterns = [ + //gi, + /on\w+\s*=/gi, + /javascript:/gi, + /