Skip to content

Commit

Permalink
[FEATURE] Add security headers to the default response (#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
xh3n1 authored and oliverklee committed Sep 19, 2018
1 parent d768aa6 commit c8e3636
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 1 deletion.
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@
"messages": {
"Symfony\\Component\\HttpKernel\\Exception\\BadRequestHttpException": true
}

},
"service": {
"view_handler": "my.secure_view_handler"
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,11 @@ services:
public: true
autowire: true
tags: ['controller.service_arguments']

my.secure_handler:
class: \PhpList\RestBundle\ViewHandler\SecuredViewHandler

my.secure_view_handler:
parent: fos_rest.view_handler.default
calls:
- ['registerHandler', [ 'json', ['@my.secure_handler', 'createResponse'] ] ]
38 changes: 38 additions & 0 deletions src/ViewHandler/SecuredViewHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);

namespace PhpList\RestBundle\ViewHandler;

use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandler;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
* This class is used to add headers to the default response.
*
* @author Xheni Myrtaj <[email protected]>
*/
class SecuredViewHandler
{
/**
* @param ViewHandler $viewHandler
* @param View $view
* @param Request $request
* @param string $format
*
* @return Response
*/
public function createResponse(ViewHandler $handler, View $view, Request $request, string $format): Response
{
$view->setHeaders(
[
'X-Content-Type-Options' => 'nosniff',
'Content-Security-Policy' => "default-src 'none'",
'X-Frame-Options' => 'DENY',
]
);

return $handler->createResponse($view, $request, $format);
}
}
69 changes: 69 additions & 0 deletions tests/System/Controller/SecuredViewHandlerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php
declare(strict_types=1);

namespace PhpList\RestBundle\Tests\System\Controller;

use GuzzleHttp\Client;
use PhpList\Core\TestingSupport\Traits\SymfonyServerTrait;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Response;

/**
* Test for security headers
*
* @author Xheni Myrtaj <[email protected]>
*/
class SecuredViewHandlerTest extends TestCase
{
use SymfonyServerTrait;

/**
* @var Client
*/
private $httpClient = null;

protected function setUp()
{
$this->httpClient = new Client(['http_errors' => false]);
}

protected function tearDown()
{
$this->stopSymfonyServer();
}

/**
* @return string[][]
*/
public function environmentDataProvider(): array
{
return [
'test' => ['test'],
'dev' => ['dev'],
];
}

/**
* @test
* @param string $environment
* @dataProvider environmentDataProvider
*/
public function testSecurityHeaders(string $environment)
{
$this->startSymfonyServer($environment);

$response = $this->httpClient->get(
'/api/v2/sessions',
['base_uri' => $this->getBaseUrl()]
);
$expectedHeaders = [
'X-Content-Type-Options' => 'nosniff',
'Content-Security-Policy' => "default-src 'none'",
'X-Frame-Options' => 'DENY',
];

foreach ($expectedHeaders as $key => $value) {
static::assertSame([$value], $response->getHeader($key));
}
}
}

0 comments on commit c8e3636

Please sign in to comment.