Content Security Policy

Otherwise known as CSP, it allows your website to inform the browser which resources can be loaded.

It is currently 'enabled' by default, and 'enforced' in development mode.

Ideally a new website will start with:

$config['output.csp_enabled'] = true;
$config['output.csp_enforced'] = true;
$config['output.csp_report'] = false;

To customise the directives, start with something like:

$config['output.csp_directives'] = [
        'default-src'  => ["'none'"], // Ideal default
        // 'navigate-to'  => ["'self'"],
        'form-action'  => ["'self'"],
        'style-src'    => ["'self'"],
        'img-src'      => ["'self'"],
        'script-src'   => ["'self'"],

For additional resources (e.g. on a per-page basis) you can also call:

$response = response_get();
$response->csp_source_add('frame-src', '');
$response->csp_source_add('img-src', array('', ''));

So for example, Google Maps might require:

$response = response_get();
$response->csp_source_add('style-src',  array('"unsafe-inline"'));
$response->csp_source_add('script-src', array('"unsafe-inline"', '"unsafe-eval"', 'https://*', 'https://*'));
$response->csp_source_add('img-src',    array('https://*', 'https://*'));


By default you should have a system_report_csp table, which is populated when the browser posts data to /a/api/csp-report/

If you want to record additional information in this table, you can either set the config variable:



    config::set('output.csp_report_extra', array(
            'user_id'   => strval(USER_ID),
            'user_name' => strval(USER_NAME),


Or you can create a function which is called from the API:

$config['output.csp_report_handle'] = 'csp_report';

function csp_report($report, $data_raw) {
    // Your code

If this function returns an array, then it will work the same as output.csp_report_extra.