Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
CSP Header for PHP or Apache or .htaccess - Content Security Protocol
<?
//CSP only works in modern browsers Chrome 25+, Firefox 23+, Safari 7+
$headerCSP = "Content-Security-Policy:".
"connect-src 'self' ;". // XMLHttpRequest (AJAX request), WebSocket or EventSource.
"default-src 'self';". // Default policy for loading html elements
"frame-ancestors 'self' ;". //allow parent framing - this one blocks click jacking and ui redress
"frame-src 'none';". // vaid sources for frames
"media-src 'self' *.example.com;". // vaid sources for media (audio and video html tags src)
"object-src 'none'; ". // valid object embed and applet tags src
"report-uri https://example.com/violationReportForCSP.php;". //A URL that will get raw json data in post that lets you know what was violated and blocked
"script-src 'self' 'unsafe-inline' example.com code.jquery.com https://ssl.google-analytics.com ;". // allows js from self, jquery and google analytics. Inline allows inline js
"style-src 'self' 'unsafe-inline';";// allows css from self and inline allows inline css
//Sends the Header in the HTTP response to instruct the Browser how it should handle content and what is whitelisted
//Its up to the browser to follow the policy which each browser has varying support
header($contentSecurityPolicy);
//X-Frame-Options is not a standard (note the X- which stands for extension not a standard)
//This was never officially created but is supported by a lot of the current browsers in use in 2015 and will block iframing of your website
header('X-Frame-Options: SAMEORIGIN');
#this can also be done in a .htaccess file depending on your server set determines where you decide to set it
Header unset Content-Security-Policy
#Add the entire CSP key value pairs that you want below is just default-src
Header add Content-Security-Policy "default-src 'self'"
#This opens support to older browsers that support X-Content-Security-Policy but not Content-Security-Policy
Header unset X-Content-Security-Policy
Header add X-Content-Security-Policy "default-src 'self'"
#This opens support to older browsers that support X-WebKit-CSP but not Content-Security-Policy
Header unset X-WebKit-CSP
Header add X-WebKit-CSP "default-src 'self'"
#These headers are also helpful in increasing security
Header set X-Content-Type-Options "nosniff"
Header set X-XSS-Protection "1; mode=block"
Header set X-Frame-Options "DENY"
Header set Strict-Transport-Security "max-age=631138519; includeSubDomains"
<?php
$data = json_decode($HTTP_RAW_POST_DATA,true);
$to = 'myemail@example.com';
$subject = 'CSP Violations';
$message="Following violations occured:<br/><br/>";
if($document_uri!="")
$message.="<b>Document URI:</b> ".$data['csp-report']['document-uri']."<br/><br/>";
if($referrer!="")
$message.="<b>Referrer:</b> ".$data['csp-report']['referrer']."<br/><br/>";
if($blocked_uri!="")
$message.="<b>Blocked URI:</b> ".$data['csp-report']['blocked_uri']."<br/><br/>";
if($violated_directive!="")
$message.="<b>Violated Directive:</b> ".$data['csp-report']['violated_directive']."<br/><br/>";
if($original_policy!="")
$message.="<b>Original Policy:</b> ".$data['csp-report']['original_policy']."<br/><br/>";
// To send HTML mail, the Content-type header must be set
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= 'From: Example Website <noreply@example.com>' . "\r\n";
// Mail it
mail($to, $subject, $message, $headers);
@hobbyman

This comment has been minimized.

Copy link

@hobbyman hobbyman commented Nov 28, 2017

cspheader.php has a typo

header($contentSecurityPolicy);

should be

header($headerCSP);

or rename $headerCSP to $contentSecurityPolicy

@AkinOlawale

This comment has been minimized.

Copy link

@AkinOlawale AkinOlawale commented Feb 10, 2019

This "code" does not work. $HTTP_RAW_POST_DATA is undefined

@naitsirch

This comment has been minimized.

Copy link

@naitsirch naitsirch commented Feb 15, 2019

@AkinOlawale Look at http://php.net/manual/en/reserved.variables.httprawpostdata.php

Warning: This feature was DEPRECATED in PHP 5.6.0, and REMOVED as of PHP 7.0.0.
...
In general, php://input should be used instead of $HTTP_RAW_POST_DATA.

Try this instead

$requestContent = file_get_contents("php://input");
$data = json_decode($requestContent, true);

And please avoid PHP' shorttags <? .... They are official discouraged see here.

@cmar0ck

This comment has been minimized.

Copy link

@cmar0ck cmar0ck commented Feb 25, 2019

There are several issues with this code...
As mentioned in other comments already variable $headerCSP is named incorrectly, as header() expects variable $contentSecurityPolicy, then $HTTP_RAW_POST_DATA is deprecated and needs to be replaced with file_get_contents("php://input"); in php > 7, apart from that

$message.="<b>Blocked URI:</b> ".$data['csp-report']['blocked_uri']."<br/><br/>";
$message.="<b>Violated Directive:</b> ".$data['csp-report']['violated_directive']."<br/><br/>";
$message.="<b>Original Policy:</b> ".$data['csp-report']['original_policy']."<br/><br/>";

needs to be replaced with

$message.="<b>Blocked URI:</b> ".$data['csp-report']['blocked-uri']."<br/><br/>";	    
$message.="<b>Violated Directive:</b> ".$data['csp-report']['violated-directive']."<br/><br/>";
$message.="<b>Original Policy:</b> ".$data['csp-report']['original-policy']."<br/><br/>";

(note the '_' are turned into '-')

otherwise these fields will be empty in the generated email.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment