Skip to content

Instantly share code, notes, and snippets.

@LucasLarson
Forked from rattfieldnz/cspheader.php
Last active April 9, 2019 20:22
Show Gist options
  • Save LucasLarson/cfa77f9d9228f8369f9b9c13de026ad8 to your computer and use it in GitHub Desktop.
Save LucasLarson/cfa77f9d9228f8369f9b9c13de026ad8 to your computer and use it in GitHub Desktop.
Content Security Protocol: LAMP-flavored CSP header for Content-Security-Policy
<?php
/**
* @author Dave LaRonde
* @author Lucas Larson
* @link https://gist.github.com/phpdave/24d879514e7411047267
*/
// Content Security Protocol (CSP) works only in modern browsers Chrome ≥25,
// Firefox ≥23, Safari ≥7
$headerCSP = "Content-Security-Policy: "
. // XMLHttpRequest (AJAX request), WebSocket, or EventSource
"connect-src 'self' *.google-analytics.com *.doubleclick.net;"
. // default policy for loading HTML elements
"default-src 'self' *.example.com *.google-analytics.com *.googletagmanager.com googletagmanager.com *.google.com;"
. // allow parent framing – this one blocks clickjacking and
// UI redress
"frame-ancestors 'self';"
. // valid sources for frames
"frame-src 'self'"
. // valid src domains for media via HTML audio and
// video elements
"media-src 'self' *.example.com;"
. // valid src domains for object, embed, and applet elements
"object-src 'none';"
. // a URL that will get raw JSON data in post that lets you
// know what was violated and blocked
// sign up for your own at report-uri.com
// hat tip Matt Ferderer https://dev.to/mattferderer/what-is-csp-why--how-to-add-it-to-your-website-28df
"report-uri https://example.report-uri.com/r/d/csp/reportOnly;"
. // report-to, which is deprecating report-uri
"Report-To: {'group':'default','max_age':31536000,'endpoints':[{'url':'https://example.report-uri.com/a/d/g'}],'include_subdomains':true};"
. // The Network Error Logging (NEL) spec defines a mechanism for collecting client-side network errors from an origin
"NEL: {'report_to':'default','max_age':31536000,'include_subdomains':true};"
. // allows JavaScript from self, jQuery and Google Analytics;
// inline allows inline JavaScript
"script-src 'self' 'unsafe-inline' 'unsafe-eval' *.example.com *.jquery.com *.google-analytics.com *.googletagmanager.com;"
. // allows CSS from self and inline allows inline CSS
"style-src 'self' 'unsafe-inline' *.example.com *.cloudflare.com *.jsdelivr.net *.googleapis.com;"
. // allows fonts from self and jsdelivr.net for Computer Modern!
"font-src 'self' 'unsafe-inline' *.example.com *.jsdelivr.net;";
// Sends the header in the HTTP response to instruct the browser how it
// should handle content and what is whitelisted. It’s up to the browser to
// follow the policy which each browser has varying support
// $contentSecurityPolicy → $headerCSP via @hobbyman https://git.io/fjtmU
header($headerCSP);
// X-Frame-Options was never officially created – its X- prefix indicates
// it’s non-standard – but most browsers support it to block iframing
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=31557600; includeSubDomains"
<?php
/**
* This isn’t working and neither was the original: https://git.io/fjtZ9
* Matt Ferderer referred me to an excellent replacement: https://report-uri.com
*/
// $requestContent and $data replace $HTTP_RAW_POST_DATA via @naitsirch git.io/fjtqx
/*
$requestContent = file_get_contents("php://input");
$data = json_decode($requestContent, TRUE);
$to = 'myemail@example.com';
$subject = 'CSP Violations';
$message = "Following violations occurred:<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);
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment