Add Content Security Policy

This commit is contained in:
Bubka 2024-11-17 20:39:27 +01:00
parent 06ad8f5cd0
commit ce1692eaf4
6 changed files with 44 additions and 2 deletions

View File

@ -274,6 +274,14 @@ TRUSTED_PROXIES=null
PROXY_FOR_OUTGOING_REQUESTS=null
# Set this to true to enable Content-Security-Policy (CSP).
# CSP helps to prevent or minimize the risk of certain types of security threats.
# This is mainly used as a defense against cross-site scripting (XSS) attacks, in which
# an attacker is able to inject malicious code into the web app
CONTENT_SECURITY_POLICY=true
# Leave the following configuration vars as is.
# Unless you like to tinker and know what you're doing.

View File

@ -6,6 +6,7 @@
use App\Facades\Settings;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Vite;
class SinglePageController extends Controller
{
@ -32,6 +33,7 @@ public function index()
$installDocUrl = config('2fauth.installDocUrl');
$ssoDocUrl = config('2fauth.ssoDocUrl');
$exportSchemaUrl = config('2fauth.exportSchemaUrl');
$cspNonce = Vite::cspNonce();
// if (Auth::user()->preferences)
@ -57,6 +59,7 @@ public function index()
'isTestingApp' => $isTestingApp,
'lang' => $lang,
'locales' => $locales,
'cspNonce' => $cspNonce,
]);
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Vite;
use Symfony\Component\HttpFoundation\Response;
class AddContentSecurityPolicyHeaders
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next) : Response
{
if (config('2fauth.config.contentSecurityPolicy')) {
Vite::useCspNonce();
return $next($request)->withHeaders([
'Content-Security-Policy' => "script-src 'nonce-" . Vite::cspNonce() . "';style-src 'self' 'unsafe-inline';connect-src 'self';img-src 'self' data:;object-src 'none';base-uri 'none';",
]);
}
return $next($request);
}
}

View File

@ -31,6 +31,7 @@
'proxyLogoutUrl' => env('PROXY_LOGOUT_URL', null),
'appSubdirectory' => env('APP_SUBDIRECTORY', ''),
'authLogRetentionTime' => envUnlessEmpty('AUTHENTICATION_LOG_RETENTION', 365),
'contentSecurityPolicy' => envUnlessEmpty('CONTENT_SECURITY_POLICY', true),
],
/*

View File

@ -22,7 +22,7 @@
<div id="app">
<app></app>
</div>
<script type="text/javascript">
<script type="text/javascript" nonce="{{ $cspNonce }}">
var appSettings = {!! $appSettings !!};
var appConfig = {!! $appConfig !!};
var urls = {!! $urls !!};

View File

@ -14,6 +14,7 @@
use App\Http\Controllers\Auth\WebAuthnRegisterController;
use App\Http\Controllers\SinglePageController;
use App\Http\Controllers\SystemController;
use App\Http\Middleware\AddContentSecurityPolicyHeaders;
use App\Http\Middleware\CustomCreateFreshApiToken;
use App\Http\Middleware\SetLanguage;
use Illuminate\Routing\Middleware\SubstituteBindings;
@ -117,4 +118,4 @@
/**
* Route for the main landing view
*/
Route::get('/{any}', [SinglePageController::class, 'index'])->where('any', '.*')->name('landing');
Route::get('/{any}', [SinglePageController::class, 'index'])->where('any', '.*')->name('landing')->middleware(AddContentSecurityPolicyHeaders::class);