[HttpKernel] Disable CSP header on exception pages
This commit is contained in:
parent
62c11e5ea8
commit
f33a383a1a
@ -13,7 +13,9 @@ namespace Symfony\Component\HttpKernel\EventListener;
|
|||||||
|
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Component\Debug\Exception\FlattenException;
|
use Symfony\Component\Debug\Exception\FlattenException;
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||||
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
|
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
|
||||||
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
||||||
use Symfony\Component\HttpKernel\KernelEvents;
|
use Symfony\Component\HttpKernel\KernelEvents;
|
||||||
@ -41,6 +43,7 @@ class ExceptionListener implements EventSubscriberInterface
|
|||||||
{
|
{
|
||||||
$exception = $event->getException();
|
$exception = $event->getException();
|
||||||
$request = $event->getRequest();
|
$request = $event->getRequest();
|
||||||
|
$eventDispatcher = func_num_args() > 2 ? func_get_arg(2) : null;
|
||||||
|
|
||||||
$this->logException($exception, sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine()));
|
$this->logException($exception, sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine()));
|
||||||
|
|
||||||
@ -67,6 +70,14 @@ class ExceptionListener implements EventSubscriberInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$event->setResponse($response);
|
$event->setResponse($response);
|
||||||
|
|
||||||
|
if ($eventDispatcher instanceof EventDispatcherInterface) {
|
||||||
|
$cspRemovalListener = function (FilterResponseEvent $event) use (&$cspRemovalListener, $eventDispatcher) {
|
||||||
|
$event->getResponse()->headers->remove('Content-Security-Policy');
|
||||||
|
$eventDispatcher->removeListener(KernelEvents::RESPONSE, $cspRemovalListener);
|
||||||
|
};
|
||||||
|
$eventDispatcher->addListener(KernelEvents::RESPONSE, $cspRemovalListener, -128);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getSubscribedEvents()
|
public static function getSubscribedEvents()
|
||||||
|
@ -12,8 +12,11 @@
|
|||||||
namespace Symfony\Component\HttpKernel\Tests\EventListener;
|
namespace Symfony\Component\HttpKernel\Tests\EventListener;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||||
|
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||||
use Symfony\Component\HttpKernel\EventListener\ExceptionListener;
|
use Symfony\Component\HttpKernel\EventListener\ExceptionListener;
|
||||||
|
use Symfony\Component\HttpKernel\KernelEvents;
|
||||||
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
|
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
|
||||||
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
@ -122,6 +125,32 @@ class ExceptionListenerTest extends TestCase
|
|||||||
$response = $event->getResponse();
|
$response = $event->getResponse();
|
||||||
$this->assertEquals('xml', $response->getContent());
|
$this->assertEquals('xml', $response->getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCSPHeaderIsRemoved()
|
||||||
|
{
|
||||||
|
$dispatcher = new EventDispatcher();
|
||||||
|
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
|
||||||
|
$kernel->expects($this->once())->method('handle')->will($this->returnCallback(function (Request $request) {
|
||||||
|
return new Response($request->getRequestFormat());
|
||||||
|
}));
|
||||||
|
|
||||||
|
$listener = new ExceptionListener('foo', $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock());
|
||||||
|
|
||||||
|
$dispatcher->addSubscriber($listener);
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
$event = new GetResponseForExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new \Exception('foo'));
|
||||||
|
$dispatcher->dispatch(KernelEvents::EXCEPTION, $event);
|
||||||
|
|
||||||
|
$response = new Response('', 200, array('content-security-policy' => "style-src 'self'"));
|
||||||
|
$this->assertTrue($response->headers->has('content-security-policy'));
|
||||||
|
|
||||||
|
$event = new FilterResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response);
|
||||||
|
$dispatcher->dispatch(KernelEvents::RESPONSE, $event);
|
||||||
|
|
||||||
|
$this->assertFalse($response->headers->has('content-security-policy'), 'CSP header has been removed');
|
||||||
|
$this->assertFalse($dispatcher->hasListeners(KernelEvents::RESPONSE), 'CSP removal listener has been removed');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestLogger extends Logger implements DebugLoggerInterface
|
class TestLogger extends Logger implements DebugLoggerInterface
|
||||||
|
Reference in New Issue
Block a user