Skip to content

Commit e05dfec

Browse files
committed
Constrain classes further in MailPreview controller
This controller should not attempt to load classes with `\` in the name, nor should it attempt to load classes that do not extedn `MailPreview`. Thanks to Volker Dusch and the PHP Ecosystem security team for reporting this.
1 parent dc794a0 commit e05dfec

2 files changed

Lines changed: 21 additions & 3 deletions

File tree

src/Controller/MailPreviewController.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use Cake\Routing\Router;
2424
use Cake\Utility\Inflector;
2525
use DebugKit\Mailer\AbstractResult;
26+
use DebugKit\Mailer\MailPreview;
2627
use DebugKit\Mailer\PreviewResult;
2728
use DebugKit\Mailer\SentMailResult;
2829
use Psr\Http\Message\ResponseInterface;
@@ -261,18 +262,21 @@ protected function findPreferredPart(AbstractResult $email, ?string $partType):
261262
*
262263
* @param string $previewName The Mailer name
263264
* @param string $emailName The mailer preview method
264-
* @param string $plugin The plugin where the mailer preview should be found
265+
* @param ?string $plugin The plugin where the mailer preview should be found
265266
* @return \DebugKit\Mailer\PreviewResult The result of the email preview
266267
* @throws \Cake\Http\Exception\NotFoundException
267268
*/
268-
protected function findPreview(string $previewName, string $emailName, string $plugin = ''): PreviewResult
269+
protected function findPreview(string $previewName, string $emailName, ?string $plugin = ''): PreviewResult
269270
{
270271
if ($plugin) {
271272
$plugin = "$plugin.";
272273
}
274+
if (str_contains($previewName, '\\')) {
275+
throw new NotFoundException("Mailer preview $previewName not found");
276+
}
273277

274278
$realClass = App::className($plugin . $previewName, 'Mailer/Preview');
275-
if (!$realClass) {
279+
if (!$realClass || !is_subclass_of($realClass, MailPreview::class, true)) {
276280
throw new NotFoundException("Mailer preview $previewName not found");
277281
}
278282
/** @var \DebugKit\Mailer\MailPreview $mailPreview */

tests/TestCase/Controller/MailPreviewControllerTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ public function testEmailPluginPassedToView()
4040
$this->assertResponseContains('src="?part=html&plugin=DebugkitTestPlugin');
4141
}
4242

43+
/**
44+
* Test that invalid classnames are rejected
45+
*
46+
* @return void
47+
*/
48+
public function testEmailRejectInvalidClassName()
49+
{
50+
$this->get('/debug-kit/mail-preview/preview/Cake\Utility\Inflector/slug');
51+
$this->assertResponseCode(404);
52+
53+
$this->get('/debug-kit/mail-preview/preview/Invalid/hello');
54+
$this->assertResponseCode(404);
55+
}
56+
4357
/** Test email template content
4458
*
4559
* @return void

0 commit comments

Comments
 (0)