rhand's avatar
Level 6

Content Security Policy / Dealing with multiple sources

Content Security Policy and blocking unsafe inline scripts or unsafe eval is really neat. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src However, it seems really hard to apply as the Facebook SDK requires unsafe eval for example and we would need to add a lot of sources. If you do add this to your Nginx configuration:

Content-Security-Policy: script-src https://*.domain.com

this would allow main domain and subdomains to work as sources for scripts. But it would block added Google Maps, Instagram CDN loaded JavaScript and other social media.

Just to load Google Maps I read we need something like this:

Content-Security-Policy: script-src maps.googleapis.com;img-src data: maps.gstatic.com *.googleapis.com *.ggpht

just to deal with Google Maps. And then you have not covered other social media you may be loading.

Question is, how do most of you deal with blocking the loading of insecure scripts? Do you use Content Security Policies (CSP)? Or do you apply other solutions? One using meta tags perhaps?

0 likes
3 replies
bobbybouwmann's avatar

Yeah, this is a tough issue because you can't control what other parties include in their scripts. The only way to know for sure if everything is secure is to include only the full/partial URLs you actually need as you did in your example.

Another solution is finding a different solution that is a bit more straight forward, which doesn't require 4 domains to load a script.

I guess the only way is to type it out and check it once in a while if everything is still correct. The other option is disabling it, but that of course is less secure.

1 like
rhand's avatar
Level 6

Yeah @bobbybouwmann thanks for the feedback. I guess we could either use something like this to Nginx configuration:

add_header Content-Security-Policy: script-src https://*.domain.com platform.twitter.com/widgets.js https://platform.instagram.com/en_US/embeds.js https://assets.pinterest.com/js/pinit.js https://platform.linkedin.com/in.js https://apis.google.com/js/platform.js https://secure.skypeassets.com/i/scom/js/skype-uri.js connect.facebook.net/en_US/sdk.js maps.googleapis.com;img-src data: maps.gstatic.com *.googleapis.com *.ggpht 

Or see if we can add all these or almost all JavaScript files locally and just use

Content-Security-Policy: script-src https://*.domain.com

or that plus a minimum amount of additional script sources.

PHP

With PHP that could be done using

<?php
	header("Content-Security-Policy: default-src '.....'");
?>

CSP Policies PHP example

Laravel Code

Or perhaps a view composer in Laravel as suggested at SO

App::before(function($request)  
{
     $headers=array('Content-Security-Policy: default-src '.....');

     View::share('headers', $headers);
}); 

Either that or Middleware as mentioned in same thread:

<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Routing\Middleware;

// If Laravel >= 5.2 then delete 'use' and 'implements' of deprecated Middleware interface.
class AddHeaders implements Middleware
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        $response->header('header name', 'header value');
        $response->header('another header', 'another value');

        return $response;
    }
}

with in this case this App\Http\Middleware\AddHeaders', added to Kernel.php if your file is called AddHeaders.php

Laravel Packages

There is also a Laravel CSP Middleware Package I found out. But it is outdated. Guess what... Spatie has one CSP Middleware package too and it is up to date!

WIth Spatie's package it becomes easier and you could use something like:

You can allow fetching scripts from www.google.com by extending this class:

namespace App\Services\Csp\Policies;

use Spatie\Csp\Directive;
use Spatie\Csp\Policies\Basic;

class MyCustomPolicy extends Basic
{
    public function configure()
    {
        parent::configure();
        
        $this->addDirective(Directive::SCRIPT, 'www.google.com');
    }
}

It has a cool built in report action as well!

1 like

Please or to participate in this conversation.