Skip to content

Commit

Permalink
Add API for Content-Security-Policy
Browse files Browse the repository at this point in the history
Add APIs to allow plugins to change the Content-Security-Policy header.

Fixes #21263
  • Loading branch information
vboctor authored and dregad committed Aug 27, 2016
1 parent 77db038 commit a905dd0
Showing 1 changed file with 52 additions and 14 deletions.
66 changes: 52 additions & 14 deletions core/http_api.php
Expand Up @@ -29,6 +29,12 @@

require_api( 'config_api.php' );

/**
* The Content-Security-Policy settings array. Use http_csp_add() to update it.
* @var array
*/
$g_csp = array();

/**
* Checks to see if script was queried through the HTTPS protocol
* @return boolean True if protocol is HTTPS
Expand Down Expand Up @@ -138,6 +144,43 @@ function http_content_headers() {
}
}

/**
* Add a Content-Security-Policy directive.
*
* @param string $p_type The directive type, e.g. style-src, script-src.
* @param string $p_value The directive value, e.g. 'self', https://ajax.googleapis.com
* @return void
*/
function http_csp_add( $p_type, $p_value ) {
global $g_csp;

if ( isset( $g_csp[$p_type] ) ) {
if ( !in_array( $p_value, $g_csp[$p_type] ) ) {
$g_csp[$p_type][] = $p_value;
}
} else {
$g_csp[$p_type] = array( $p_value );
}
}

/**
* Constructs the value of the CSP header.
* @return string CSP header value.
*/
function http_csp_value() {
global $g_csp;

$t_csp_value = '';

foreach ( $g_csp as $t_key => $t_values ) {
$t_csp_value .= $t_key . ' ' . implode( ' ', $t_values ) . '; ';
}

$t_csp_value = trim( $t_csp_value, '; ' );

return $t_csp_value;
}

/**
* Set security headers (frame busting, clickjacking/XSS/CSRF protection).
* @return void
Expand All @@ -147,32 +190,27 @@ function http_security_headers() {
header( 'X-Frame-Options: DENY' );

# Define Content Security Policy
$t_csp = array(
"default-src 'self'",
"frame-ancestors 'none'",
);

$t_style_src = "style-src 'self'";
$t_script_src = "script-src 'self'";
http_csp_add( 'default-src', "'self'" );
http_csp_add( 'frame-ancestors', "'none'" );
http_csp_add( 'style-src', "'self'" );
http_csp_add( 'script-src', "'self'" );
http_csp_add( 'img-src', "'self'" );

# White list the CDN urls (if enabled)
if ( config_get_global( 'cdn_enabled' ) == ON ) {
$t_cdn_url = 'https://ajax.googleapis.com';
$t_style_src .= " $t_cdn_url";
$t_script_src .= " $t_cdn_url";
http_csp_add( 'style-src', $t_cdn_url );
http_csp_add( 'script-src', $t_cdn_url );
}

# Relaxing policy for roadmap page to allow inline styles
# This is a workaround to fix the broken progress bars (see #19501)
if( 'roadmap_page.php' == basename( $_SERVER['SCRIPT_NAME'] ) ) {
$t_style_src .= " 'unsafe-inline'";
http_csp_add( 'style-src', "'unsafe-inline'" );
}

$t_csp[] = $t_style_src;
$t_csp[] = $t_script_src;

# Set CSP header
header( 'Content-Security-Policy: ' . implode('; ', $t_csp) );
header( 'Content-Security-Policy: ' . http_csp_value() );

if( http_is_protocol_https() ) {
header( 'Strict-Transport-Security: max-age=7776000' );
Expand Down

0 comments on commit a905dd0

Please sign in to comment.