Search code examples
phplaravel-11

How can i access custom $nonce for CSP in all view templates?


I am building a laravel 11 app and using custom CSP middleware for the project. I have create ContentSecurityPolicy.php in app/http/middleware folder and it contains this code: `

namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\View;

 class ContentSecurityPolicy
{
 public function handle(Request $request, Closure $next)
 {
    // Generate a secure nonce
    $nonce = base64_encode(random_bytes(16));
    $isLocal = $request->getHost() === '[::1]';
  
    $csp = "base-uri 'self'; "
        . "script-src 'self' 'nonce-{$nonce}'". ($isLocal ? "http://[::1]:5173/ " : "") ." https://fonts.bunny.net/ https://reetahoo.com/ https://pagead2.googlesyndication.com/ "
        . "https://goatauthut.xyz/ https://itweepinbelltor.com/ https://dicouksa.com/ https://goomaphy.com/ "
        . "https://veepteero.com/ https://pertawee.net/ https://shoordaird.com/ https://soathoth.com/ "
        . "https://thubanoa.com/ https://alwingulla.com/ https://tzegilo.com/ https://whaickossu.net/ "
        . "https://www.google.com/recaptcha/ https://widget.trustpilot.com/ https://cdn.datatables.net/ "
        . "https://coding-nonny.github.io/ https://api.countrystatecity.in/ https://ip-api.com/ "
        . "https://api.coinpaprika.com/ https://cdn.jsdelivr.net/ https://js.paystack.co/ "
        . "https://www.smartsuppchat.com/ https://widget-v3.smartsuppcdn.com/ http://translate.google.com/ "
        . "https://www.gstatic.com/ https://translate-pa.googleapis.com/ https://ipwhois.app/ "
        . "https://boupeeli.com/; "
        . "style-src 'self' 'unsafe-inline' ". ($isLocal ? "http://[::1]:5173/ " : "") ." https://fonts.bunny.net/ https://cdnjs.cloudflare.com/ https://boupeeli.com/ https://goatauthut.xyz/ "
        . "https://fonts.googleapis.com/ https://coding-nonny.github.io/ https://cdn.datatables.net/ "
        . "https://cdn.jsdelivr.net/ https://www.smartsuppchat.com/ https://widget-v3.smartsuppcdn.com/ "
        . "http://translate.google.com/ https://rertessesse.xyz/ https://www.gstatic.com/ "
        . "https://translate-pa.googleapis.com/; "
        . "object-src 'none'; frame-ancestors 'none';";

    // Process request
    $response = $next($request);

    // Set CSP header properly
    $response->headers->set('Content-Security-Policy', $csp);

    // Share nonce with views (for inline scripts)
    view()->share('nonce', $nonce);

    return $response;
}
}

`

And i registered the middleware in bootstrap/app.php (alternative for kernel.php in laravel 11) like this: `

 use Illuminate\Foundation\Application;
 use Illuminate\Foundation\Configuration\Exceptions;
 use Illuminate\Foundation\Configuration\Middleware;
 use App\Http\Middleware\ContentSecurityPolicy;

 return Application::configure(basePath: dirname(__DIR__))
->withRouting(
    web: __DIR__ . '/../routes/web.php',
    commands: __DIR__ . '/../routes/console.php',
    health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
    $middleware->prepend(ContentSecurityPolicy::class);
})
->withExceptions(function (Exceptions $exceptions) {
    //
})->create();

`

but if use $nonce in inline scripts:

<script nonce="{{$nonce}}"></script>

i get this error: "Undefined variable $nonce". How can i solve it?


Solution

  • Okay I have found the solution. All i needed to do is to move this line

    `

     view()->share("nonce",$nonce);
    

    `

    before

    `

    $response = $next($request);
    

    `

    Everything will stark working as expected.