Make the CSP compatible with debug tools

This commit is contained in:
Pierre Rudloff 2020-10-19 23:43:33 +02:00
parent e2560cd9cb
commit 561b6c8370
6 changed files with 194 additions and 2 deletions

View file

@ -36,6 +36,5 @@ FileETag None
Header set X-Content-Type-Options nosniff
Header set X-XSS-Protection "1; mode=block"
Header set Referrer-Policy no-referrer
Header set Content-Security-Policy "default-src 'self'; object-src 'none'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src http:"
Header add Link "</css/fonts.css>; rel=preload, </css/style.css>; rel=preload" "expr=%{CONTENT_TYPE} =~ m#text/html#"
</ifmodule>

View file

@ -6,6 +6,7 @@
namespace Alltube\Controller;
use Alltube\CspMiddleware;
use Alltube\Library\Exception\PasswordException;
use Alltube\Library\Exception\AlltubeLibraryException;
use Alltube\Library\Exception\WrongPasswordException;
@ -295,6 +296,12 @@ class FrontController extends BaseController
{
$this->logger->error($error);
// We apply the CSP manually because middlewares are not called on error pages.
$cspMiddleware = new CspMiddleware($this->container);
/** @var Response $response */
$response = $cspMiddleware->applyHeader($response);
if ($this->config->debug) {
$renderer = new HtmlErrorRenderer(true);
$exception = $renderer->render($error);

65
classes/CspMiddleware.php Normal file
View file

@ -0,0 +1,65 @@
<?php
namespace Alltube;
use ParagonIE\CSPBuilder\CSPBuilder;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\MessageInterface;
use Slim\Http\Request;
use Slim\Http\Response;
/**
* Class CspMiddleware
* @package Alltube
*/
class CspMiddleware
{
/**
* @var Config
*/
private $config;
/**
* CspMiddleware constructor.
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
$this->config = $container->get('config');
}
/**
* @param Response $response
* @return MessageInterface
*/
public function applyHeader(Response $response)
{
$csp = new CSPBuilder();
$csp->addDirective('default-src', [])
->addDirective('font-src', ['self' => true])
->addDirective('style-src', ['self' => true])
->addSource('img-src', '*');
if ($this->config->debug) {
// So symfony/debug and symfony/error-handler can work.
$csp->setDirective('script-src', ['unsafe-inline' => true])
->setDirective('style-src', ['self' => true, 'unsafe-inline' => true]);
}
return $csp->injectCSPHeader($response);
}
/**
* @param Request $request
* @param Response $response
* @param callable $next
* @return mixed
*/
public function __invoke(Request $request, Response $response, callable $next)
{
$response = $this->applyHeader($response);
return $next($request, $response);
}
}

View file

@ -27,6 +27,7 @@
"jawira/case-converter": "^3.4",
"jean85/pretty-package-versions": "^1.3",
"mathmarques/smarty-view": "^1.1",
"paragonie/csp-builder": "^2.5",
"rinvex/countries": "^6.1",
"rudloff/alltube-library": "dev-develop",
"symfony/finder": "^5.0",

120
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "7e756e8b0f372bd5a914c54310933ecb",
"content-hash": "c0d33bde893f1ac7cbfcd26d26a92c9f",
"packages": [
{
"name": "aura/session",
@ -618,6 +618,124 @@
],
"time": "2018-02-13T20:26:39+00:00"
},
{
"name": "paragonie/constant_time_encoding",
"version": "v2.3.0",
"source": {
"type": "git",
"url": "https://github.com/paragonie/constant_time_encoding.git",
"reference": "47a1cedd2e4d52688eb8c96469c05ebc8fd28fa2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/47a1cedd2e4d52688eb8c96469c05ebc8fd28fa2",
"reference": "47a1cedd2e4d52688eb8c96469c05ebc8fd28fa2",
"shasum": ""
},
"require": {
"php": "^7|^8"
},
"require-dev": {
"phpunit/phpunit": "^6|^7",
"vimeo/psalm": "^1|^2|^3"
},
"type": "library",
"autoload": {
"psr-4": {
"ParagonIE\\ConstantTime\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com",
"role": "Maintainer"
},
{
"name": "Steve 'Sc00bz' Thomas",
"email": "steve@tobtu.com",
"homepage": "https://www.tobtu.com",
"role": "Original Developer"
}
],
"description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
"keywords": [
"base16",
"base32",
"base32_decode",
"base32_encode",
"base64",
"base64_decode",
"base64_encode",
"bin2hex",
"encoding",
"hex",
"hex2bin",
"rfc4648"
],
"time": "2019-11-06T19:20:29+00:00"
},
{
"name": "paragonie/csp-builder",
"version": "v2.5.0",
"source": {
"type": "git",
"url": "https://github.com/paragonie/csp-builder.git",
"reference": "73ebd90199eb6f3be6549d5390a7698c6deffa30"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/csp-builder/zipball/73ebd90199eb6f3be6549d5390a7698c6deffa30",
"reference": "73ebd90199eb6f3be6549d5390a7698c6deffa30",
"shasum": ""
},
"require": {
"paragonie/constant_time_encoding": "^2",
"php": "^7.1|^8"
},
"require-dev": {
"phpunit/phpunit": "^7|^8|^9",
"psr/http-message": "^1",
"squizlabs/php_codesniffer": "^3",
"vimeo/psalm": "^3"
},
"suggest": {
"psr/http-message": "For CSPBuilder::injectCSPHeader()"
},
"type": "library",
"autoload": {
"psr-4": {
"ParagonIE\\CSPBuilder\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com",
"role": "Owner"
}
],
"description": "Easily add and update Content-Security-Policy headers for your project",
"keywords": [
"content-security-policy",
"csp",
"headers",
"http",
"security",
"xss"
],
"time": "2020-09-02T14:53:15+00:00"
},
{
"name": "pimple/pimple",
"version": "v3.3.0",

View file

@ -6,6 +6,7 @@ use Alltube\ConfigFactory;
use Alltube\Controller\DownloadController;
use Alltube\Controller\FrontController;
use Alltube\Controller\JsonController;
use Alltube\CspMiddleware;
use Alltube\ErrorHandler;
use Alltube\LocaleManagerFactory;
use Alltube\LocaleMiddleware;
@ -42,6 +43,7 @@ try {
// Middlewares.
$app->add(new LocaleMiddleware($container));
$app->add(new RouterPathMiddleware($container));
$app->add(new CspMiddleware($container));
// Controllers.
$frontController = new FrontController($container);