8000 [HttpKernel] Disable CSP header on exception pages · symfony/symfony@f33a383 · GitHub
[go: up one dir, main page]

Skip to content

Commit f33a383

Browse files
committed
[HttpKernel] Disable CSP header on exception pages
1 parent 62c11e5 commit f33a383

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313

1414
use Psr\Log\LoggerInterface;
1515
use Symfony\Component\Debug\Exception\FlattenException;
16+
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
1617
use Symfony\Component\HttpFoundation\Request;
18+
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
1719
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
1820
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
1921
use Symfony\Component\HttpKernel\KernelEvents;
@@ -41,6 +43,7 @@ public function onKernelException(GetResponseForExceptionEvent $event)
4143
{
4244
$exception = $event->getException();
4345
$request = $event->getRequest();
46+
$eventDispatcher = func_num_args() > 2 ? func_get_arg(2) : null;
4447

4548
$this->logException($exception, sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine()));
4649

@@ -67,6 +70,14 @@ public function onKernelException(GetResponseForExceptionEvent $event)
6770
}
6871

6972
$event->setResponse($response);
73+
74+
if ($eventDispatcher instanceof EventDispatcherInterface) {
75+
$cspRemovalListener = function (FilterResponseEvent $event) use (&$cspRemovalListener, $eventDispatcher) {
76+
$event->getResponse()->headers->remove('Content-Security-Policy');
77+
$eventDispatcher->removeListener(KernelEvents::RESPONSE, $cspRemovalListener);
78+
};
79+
$eventDispatcher->addListener(KernelEvents::RESPONSE, $cspRemovalListener, -128);
80+
}
7081
}
7182

7283
public static function getSubscribedEvents()

src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
namespace Symfony\Component\HttpKernel\Tests\EventListener;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\EventDispatcher\EventDispatcher;
16+
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
1517
use Symfony\Component\HttpKernel\HttpKernelInterface;
1618
use Symfony\Component\HttpKernel\EventListener\ExceptionListener;
19+
use Symfony\Component\HttpKernel\KernelEvents;
1720
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
1821
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
1922
use Symfony\Component\HttpFoundation\Request;
@@ -122,6 +125,32 @@ public function testSubRequestFormat()
122125
$response = $event->getResponse();
123126
$this->assertEquals('xml', $response->getContent());
124127
}
128+
129+
public function testCSPHeaderIsRemoved()
130+
{
131+
$dispatcher = new EventDispatcher();
132+
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
133+
$kernel->expects($this->once())->method('handle')->will($this->returnCallback(function (Request $request) {
134+
return new Response($request->getRequestFormat());
135+
}));
136+
137+
$listener = new ExceptionListener('foo', $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock());
138+
139+
$dispatcher->addSubscriber($listener);
140+
141+
$request = Request::create('/');
142+
$event = new GetResponseForExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new \Exception('foo'));
143+
$dispatcher->dispatch(KernelEvents::EXCEPTION, $event);
144+
145+
$response = new Response('', 200, array('content-security-policy' => "style-src 'self'"));
146+
$this->assertTrue($response->headers->has('content-security-policy'));
147+
148+
$event = new FilterResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response);
149+
$dispatcher->dispatch(KernelEvents::RESPONSE, $event);
150+
151+
$this->assertFalse($response->headers->has('content-security-policy'), 'CSP header has been removed');
152+
$this->assertFalse($dispatcher->hasListeners(KernelEvents::RESPONSE), 'CSP removal listener has been removed');
153+
}
125154
}
126155

127156
class TestLogger extends Logger implements DebugLoggerInterface

0 commit comments

Comments
 (0)
0