From cf51670727a509e9a016d94f8d844a70a55f49c0 Mon Sep 17 00:00:00 2001 From: "Christopher C. Wells" Date: Mon, 27 Sep 2021 09:02:44 -0700 Subject: [PATCH] Add CSP policy to all responses --- .phpstorm.meta.php | 11 +++ app/Http/Kernel.php | 1 + app/Services/Csp/Policies/DefaultPolicy.php | 31 ++++++++ composer.json | 1 + composer.lock | 86 ++++++++++++++++++++- config/csp.php | 34 ++++++++ 6 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 app/Services/Csp/Policies/DefaultPolicy.php create mode 100644 config/csp.php diff --git a/.phpstorm.meta.php b/.phpstorm.meta.php index f4a7888..3699592 100644 --- a/.phpstorm.meta.php +++ b/.phpstorm.meta.php @@ -80,6 +80,7 @@ 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, 'Psr\Http\Message\ResponseInterface' => \Nyholm\Psr7\Response::class, 'Psr\Http\Message\ServerRequestInterface' => \Nyholm\Psr7\ServerRequest::class, + 'Spatie\Csp\Nonce\NonceGenerator' => \Spatie\Csp\Nonce\RandomString::class, 'Spatie\MediaLibrary\MediaCollections\Filesystem' => \Spatie\MediaLibrary\MediaCollections\Filesystem::class, 'Spatie\MediaLibrary\MediaCollections\MediaRepository' => \Spatie\MediaLibrary\MediaCollections\MediaRepository::class, 'Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\TinyPlaceholderGenerator' => \Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class, @@ -294,6 +295,7 @@ 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, 'Psr\Http\Message\ResponseInterface' => \Nyholm\Psr7\Response::class, 'Psr\Http\Message\ServerRequestInterface' => \Nyholm\Psr7\ServerRequest::class, + 'Spatie\Csp\Nonce\NonceGenerator' => \Spatie\Csp\Nonce\RandomString::class, 'Spatie\MediaLibrary\MediaCollections\Filesystem' => \Spatie\MediaLibrary\MediaCollections\Filesystem::class, 'Spatie\MediaLibrary\MediaCollections\MediaRepository' => \Spatie\MediaLibrary\MediaCollections\MediaRepository::class, 'Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\TinyPlaceholderGenerator' => \Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class, @@ -508,6 +510,7 @@ 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, 'Psr\Http\Message\ResponseInterface' => \Nyholm\Psr7\Response::class, 'Psr\Http\Message\ServerRequestInterface' => \Nyholm\Psr7\ServerRequest::class, + 'Spatie\Csp\Nonce\NonceGenerator' => \Spatie\Csp\Nonce\RandomString::class, 'Spatie\MediaLibrary\MediaCollections\Filesystem' => \Spatie\MediaLibrary\MediaCollections\Filesystem::class, 'Spatie\MediaLibrary\MediaCollections\MediaRepository' => \Spatie\MediaLibrary\MediaCollections\MediaRepository::class, 'Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\TinyPlaceholderGenerator' => \Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class, @@ -722,6 +725,7 @@ 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, 'Psr\Http\Message\ResponseInterface' => \Nyholm\Psr7\Response::class, 'Psr\Http\Message\ServerRequestInterface' => \Nyholm\Psr7\ServerRequest::class, + 'Spatie\Csp\Nonce\NonceGenerator' => \Spatie\Csp\Nonce\RandomString::class, 'Spatie\MediaLibrary\MediaCollections\Filesystem' => \Spatie\MediaLibrary\MediaCollections\Filesystem::class, 'Spatie\MediaLibrary\MediaCollections\MediaRepository' => \Spatie\MediaLibrary\MediaCollections\MediaRepository::class, 'Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\TinyPlaceholderGenerator' => \Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class, @@ -936,6 +940,7 @@ 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, 'Psr\Http\Message\ResponseInterface' => \Nyholm\Psr7\Response::class, 'Psr\Http\Message\ServerRequestInterface' => \Nyholm\Psr7\ServerRequest::class, + 'Spatie\Csp\Nonce\NonceGenerator' => \Spatie\Csp\Nonce\RandomString::class, 'Spatie\MediaLibrary\MediaCollections\Filesystem' => \Spatie\MediaLibrary\MediaCollections\Filesystem::class, 'Spatie\MediaLibrary\MediaCollections\MediaRepository' => \Spatie\MediaLibrary\MediaCollections\MediaRepository::class, 'Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\TinyPlaceholderGenerator' => \Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class, @@ -1150,6 +1155,7 @@ 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, 'Psr\Http\Message\ResponseInterface' => \Nyholm\Psr7\Response::class, 'Psr\Http\Message\ServerRequestInterface' => \Nyholm\Psr7\ServerRequest::class, + 'Spatie\Csp\Nonce\NonceGenerator' => \Spatie\Csp\Nonce\RandomString::class, 'Spatie\MediaLibrary\MediaCollections\Filesystem' => \Spatie\MediaLibrary\MediaCollections\Filesystem::class, 'Spatie\MediaLibrary\MediaCollections\MediaRepository' => \Spatie\MediaLibrary\MediaCollections\MediaRepository::class, 'Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\TinyPlaceholderGenerator' => \Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class, @@ -1364,6 +1370,7 @@ 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, 'Psr\Http\Message\ResponseInterface' => \Nyholm\Psr7\Response::class, 'Psr\Http\Message\ServerRequestInterface' => \Nyholm\Psr7\ServerRequest::class, + 'Spatie\Csp\Nonce\NonceGenerator' => \Spatie\Csp\Nonce\RandomString::class, 'Spatie\MediaLibrary\MediaCollections\Filesystem' => \Spatie\MediaLibrary\MediaCollections\Filesystem::class, 'Spatie\MediaLibrary\MediaCollections\MediaRepository' => \Spatie\MediaLibrary\MediaCollections\MediaRepository::class, 'Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\TinyPlaceholderGenerator' => \Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class, @@ -1578,6 +1585,7 @@ 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, 'Psr\Http\Message\ResponseInterface' => \Nyholm\Psr7\Response::class, 'Psr\Http\Message\ServerRequestInterface' => \Nyholm\Psr7\ServerRequest::class, + 'Spatie\Csp\Nonce\NonceGenerator' => \Spatie\Csp\Nonce\RandomString::class, 'Spatie\MediaLibrary\MediaCollections\Filesystem' => \Spatie\MediaLibrary\MediaCollections\Filesystem::class, 'Spatie\MediaLibrary\MediaCollections\MediaRepository' => \Spatie\MediaLibrary\MediaCollections\MediaRepository::class, 'Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\TinyPlaceholderGenerator' => \Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class, @@ -1792,6 +1800,7 @@ 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, 'Psr\Http\Message\ResponseInterface' => \Nyholm\Psr7\Response::class, 'Psr\Http\Message\ServerRequestInterface' => \Nyholm\Psr7\ServerRequest::class, + 'Spatie\Csp\Nonce\NonceGenerator' => \Spatie\Csp\Nonce\RandomString::class, 'Spatie\MediaLibrary\MediaCollections\Filesystem' => \Spatie\MediaLibrary\MediaCollections\Filesystem::class, 'Spatie\MediaLibrary\MediaCollections\MediaRepository' => \Spatie\MediaLibrary\MediaCollections\MediaRepository::class, 'Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\TinyPlaceholderGenerator' => \Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class, @@ -2006,6 +2015,7 @@ 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, 'Psr\Http\Message\ResponseInterface' => \Nyholm\Psr7\Response::class, 'Psr\Http\Message\ServerRequestInterface' => \Nyholm\Psr7\ServerRequest::class, + 'Spatie\Csp\Nonce\NonceGenerator' => \Spatie\Csp\Nonce\RandomString::class, 'Spatie\MediaLibrary\MediaCollections\Filesystem' => \Spatie\MediaLibrary\MediaCollections\Filesystem::class, 'Spatie\MediaLibrary\MediaCollections\MediaRepository' => \Spatie\MediaLibrary\MediaCollections\MediaRepository::class, 'Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\TinyPlaceholderGenerator' => \Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class, @@ -2220,6 +2230,7 @@ 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, 'Psr\Http\Message\ResponseInterface' => \Nyholm\Psr7\Response::class, 'Psr\Http\Message\ServerRequestInterface' => \Nyholm\Psr7\ServerRequest::class, + 'Spatie\Csp\Nonce\NonceGenerator' => \Spatie\Csp\Nonce\RandomString::class, 'Spatie\MediaLibrary\MediaCollections\Filesystem' => \Spatie\MediaLibrary\MediaCollections\Filesystem::class, 'Spatie\MediaLibrary\MediaCollections\MediaRepository' => \Spatie\MediaLibrary\MediaCollections\MediaRepository::class, 'Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\TinyPlaceholderGenerator' => \Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class, diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 934700e..031b6f8 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -31,6 +31,7 @@ class Kernel extends HttpKernel \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, + \Spatie\Csp\AddCspHeaders::class, ], 'api' => [ diff --git a/app/Services/Csp/Policies/DefaultPolicy.php b/app/Services/Csp/Policies/DefaultPolicy.php new file mode 100644 index 0000000..ca23487 --- /dev/null +++ b/app/Services/Csp/Policies/DefaultPolicy.php @@ -0,0 +1,31 @@ +addDirective(Directive::BASE, Keyword::SELF) + ->addDirective(Directive::CONNECT, Keyword::SELF) + ->addDirective(Directive::DEFAULT, Keyword::SELF) + ->addDirective(Directive::FORM_ACTION, Keyword::SELF) + ->addDirective(Directive::IMG, [Keyword::SELF, Keyword::UNSAFE_INLINE, Scheme::DATA]) + ->addDirective(Directive::MEDIA, Keyword::SELF) + ->addDirective(Directive::OBJECT, Keyword::NONE) + ->addDirective(Directive::SCRIPT, [Keyword::SELF, Keyword::UNSAFE_EVAL, Keyword::UNSAFE_INLINE]) + ->addDirective(Directive::STYLE, [Keyword::SELF, Keyword::UNSAFE_INLINE]) + ->addDirective(Directive::FRAME, Keyword::NONE); + } +} diff --git a/composer.json b/composer.json index 937db41..f62b1b2 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "laravel/tinker": "^2.5", "league/flysystem-aws-s3-v3": "~1.0", "phospr/fraction": "^1.2", + "spatie/laravel-csp": "^2.6", "spatie/laravel-medialibrary": "^9.0.0", "spatie/laravel-tags": "^3.0" }, diff --git a/composer.lock b/composer.lock index 861b793..6930d10 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "d439d0b8ef963ec97130782e7092153d", + "content-hash": "2b01c1a7477b96fedb23ab644ec77fb4", "packages": [ { "name": "algolia/algoliasearch-client-php", @@ -5171,6 +5171,88 @@ }, "time": "2021-04-22T06:17:27+00:00" }, + { + "name": "spatie/laravel-csp", + "version": "2.6.4", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-csp.git", + "reference": "a9c15ea6dc5266083132999f104fa8a363ab07e3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-csp/zipball/a9c15ea6dc5266083132999f104fa8a363ab07e3", + "reference": "a9c15ea6dc5266083132999f104fa8a363ab07e3", + "shasum": "" + }, + "require": { + "illuminate/http": "~5.8.0|^6.0|^7.0|^8.0", + "illuminate/support": "~5.8.0|^6.0|^7.0|^8.0", + "php": "^7.2|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.0|^1.3.1", + "orchestra/testbench": "~3.8.0|^4.0|^5.0|^6.0", + "phpunit/phpunit": "^8.0|^9.3", + "roave/security-advisories": "dev-master" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Csp\\CspServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\Csp\\": "src" + }, + "files": [ + "src/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Thomas Verhelst", + "email": "tvke91@gmail.com", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Add CSP headers to the responses of a Laravel app", + "homepage": "https://github.com/spatie/laravel-csp", + "keywords": [ + "content-security-policy", + "csp", + "headers", + "laravel", + "laravel-csp", + "security", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-csp/issues", + "source": "https://github.com/spatie/laravel-csp/tree/2.6.4" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + } + ], + "time": "2020-12-01T20:35:30+00:00" + }, { "name": "spatie/laravel-medialibrary", "version": "9.7.4", @@ -12206,5 +12288,5 @@ "ext-mbstring": "*" }, "platform-dev": [], - "plugin-api-version": "2.0.0" + "plugin-api-version": "2.1.0" } diff --git a/config/csp.php b/config/csp.php new file mode 100644 index 0000000..61ed05a --- /dev/null +++ b/config/csp.php @@ -0,0 +1,34 @@ + App\Services\Csp\Policies\DefaultPolicy::class, + + /* + * This policy which will be put in report only mode. This is great for testing out + * a new policy or changes to existing csp policy without breaking anything. + */ + 'report_only_policy' => '', + + /* + * All violations against the policy will be reported to this url. + * A great service you could use for this is https://report-uri.com/ + * + * You can override this setting by calling `reportTo` on your policy. + */ + 'report_uri' => env('CSP_REPORT_URI', ''), + + /* + * Headers will only be added if this setting is set to true. + */ + 'enabled' => env('CSP_ENABLED', true), + + /* + * The class responsible for generating the nonces used in inline tags and headers. + */ + 'nonce_generator' => Spatie\Csp\Nonce\RandomString::class, +];