Merge pull request #7144 from shleeable/fix/curated-register-email-escape

Escape user-provided content in curated register admin emails
pull/7146/head
Shlee 2 weeks ago committed by GitHub
commit c3e01f86cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -19,7 +19,7 @@ Email: <strong>{{ $verify->email }}</strong>
<hr>
<small><strong>*The user provided the following reason to join:*</strong></small>
<p style="font-size:9pt;">{!!Str::limit(nl2br($verify->reason_to_join), 300)!!}</p>
<p style="font-size:9pt;">{!! nl2br(e(Str::limit($verify->reason_to_join, 300))) !!}</p>
</x-mail::panel>
<x-mail::button :url="$verify->adminReviewUrl()" color="success">

@ -6,7 +6,7 @@ Hello,
You have a new response from a curated onboarding application from **{{$activity->application->email}}**.
<x-mail::panel>
<p style="white-space: pre-wrap;">{!! $activity->message !!}</p>
<p style="white-space: pre-wrap;">{!! nl2br(e($activity->message)) !!}</p>
</x-mail::panel>
<x-mail::button :url="$activity->adminReviewUrl()" color="success">

@ -0,0 +1,45 @@
<?php
use App\Mail\CuratedRegisterNotifyAdmin;
use App\Mail\CuratedRegisterNotifyAdminUserResponse;
use App\Models\CuratedRegister;
use App\Models\CuratedRegisterActivity;
use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
uses(LazilyRefreshDatabase::class);
/*
|--------------------------------------------------------------------------
| Curated register admin email escaping
|--------------------------------------------------------------------------
|
| User-provided reason_to_join / response message must be HTML-escaped in the
| admin notification emails (prevents injected phishing UI), while preserving
| line breaks.
|
*/
it('escapes user-provided content in the admin notification emails', function () {
$verify = new CuratedRegister;
$verify->username = 'attacker';
$verify->email = 'attacker@example.com';
$verify->reason_to_join = "<script>alert(1)</script>\nsecond line";
$verify->save();
$applicationHtml = (new CuratedRegisterNotifyAdmin($verify))->render();
expect($applicationHtml)->not->toContain('<script>alert(1)</script>');
expect($applicationHtml)->toContain('&lt;script&gt;');
// Line breaks preserved via nl2br.
expect($applicationHtml)->toContain('<br');
$activity = new CuratedRegisterActivity;
$activity->register_id = $verify->id;
$activity->message = '<script>alert(2)</script>';
$activity->save();
$responseHtml = (new CuratedRegisterNotifyAdminUserResponse($activity))->render();
expect($responseHtml)->not->toContain('<script>alert(2)</script>');
expect($responseHtml)->toContain('&lt;script&gt;');
});
Loading…
Cancel
Save