From 4df40cb77264ac4f2d5dd99b4736b06728ea3daa Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 9 Sep 2026 20:23:26 +0930 Subject: [PATCH] Escape user-provided content in curated register admin emails --- .../curated-register/admin_notify.blade.php | 2 +- .../admin_notify_user_response.blade.php | 2 +- .../CuratedRegisterEmailEscapeTest.php | 45 +++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 tests/Feature/CuratedRegisterEmailEscapeTest.php diff --git a/resources/views/emails/curated-register/admin_notify.blade.php b/resources/views/emails/curated-register/admin_notify.blade.php index 15090cc43..5e85e6f91 100644 --- a/resources/views/emails/curated-register/admin_notify.blade.php +++ b/resources/views/emails/curated-register/admin_notify.blade.php @@ -19,7 +19,7 @@ Email: {{ $verify->email }}
*The user provided the following reason to join:* -

{!!Str::limit(nl2br($verify->reason_to_join), 300)!!}

+

{!! nl2br(e(Str::limit($verify->reason_to_join, 300))) !!}

diff --git a/resources/views/emails/curated-register/admin_notify_user_response.blade.php b/resources/views/emails/curated-register/admin_notify_user_response.blade.php index 504795f83..3fbad7668 100644 --- a/resources/views/emails/curated-register/admin_notify_user_response.blade.php +++ b/resources/views/emails/curated-register/admin_notify_user_response.blade.php @@ -6,7 +6,7 @@ Hello, You have a new response from a curated onboarding application from **{{$activity->application->email}}**. -

{!! $activity->message !!}

+

{!! nl2br(e($activity->message)) !!}

diff --git a/tests/Feature/CuratedRegisterEmailEscapeTest.php b/tests/Feature/CuratedRegisterEmailEscapeTest.php new file mode 100644 index 000000000..ad2f467f2 --- /dev/null +++ b/tests/Feature/CuratedRegisterEmailEscapeTest.php @@ -0,0 +1,45 @@ +username = 'attacker'; + $verify->email = 'attacker@example.com'; + $verify->reason_to_join = "\nsecond line"; + $verify->save(); + + $applicationHtml = (new CuratedRegisterNotifyAdmin($verify))->render(); + + expect($applicationHtml)->not->toContain(''); + expect($applicationHtml)->toContain('<script>'); + // Line breaks preserved via nl2br. + expect($applicationHtml)->toContain('register_id = $verify->id; + $activity->message = ''; + $activity->save(); + + $responseHtml = (new CuratedRegisterNotifyAdminUserResponse($activity))->render(); + + expect($responseHtml)->not->toContain(''); + expect($responseHtml)->toContain('<script>'); +});