mikeg_de

Send Content Security Policy Report to Google Analytics

Jan 1st, 2016
1,756
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 4.39 KB | None | 0 0
  1. <?php
  2. // Caution: Work still in progress!
  3.  
  4. /* Thanks to
  5.     Stu Miller – Web Consultant, WordPress developer/specialist based in Leeds, UK
  6.     http://www.stumiller.me/implementing-google-analytics-measurement-protocol-in-php-and-wordpress/
  7.  
  8.     Amit Agarwal
  9.     http://ctrlq.org/code/19011-google-analytics-php
  10.  
  11.     Ani Lopez
  12.     http://dynamical.biz/blog/technical-analytics/tracking-ga-user-id-72.html
  13.  
  14.     Cardinal Path
  15.     http://www.cardinalpath.com/ga-basics-the-structure-of-cookie-values/
  16. */
  17.  
  18. /* Transmitted JSON on CSP validation
  19. {
  20.     "csp-report": {
  21.         "document-uri": "http://example.org/page.html",
  22.         "referrer": "http://evil.example.com/",
  23.         "blocked-uri": "http://evil.example.com/evil.js",
  24.         "violated-directive": "script-src "self" https://apis.google.com",
  25.         "original-policy": "script-src "self" https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"
  26.     }
  27. } */
  28.  
  29. // 1st Receive and store CSP message as string in temporary variable
  30. $c = file_get_contents("php://input");
  31.  
  32. if (!$c)
  33.     // Send GA-Event for empty JSON?
  34.     exit;
  35.  
  36. // 2nd convert string to array
  37. $c = json_decode($c, true);
  38.  
  39. /* 3rd get Google Analytics Client ID from "_ga" cookie
  40.     https://developers.google.com/analytics/devguides/collection/protocol/v1/reference
  41.     https://developers.google.com/analytics/devguides/collection/analyticsjs/cookie-usage#gajs
  42.     GA#.#.[User ID].[Time Stamp]
  43.     http://ctrlq.org/code/19011-google-analytics-php
  44. */
  45. function gaParseCookie() {
  46.     if (isset($_COOKIE["_ga"])) {
  47.         list($version, $domainDepth, $cid1, $cid2) = split("[\.]", $_COOKIE["_ga"],4);
  48.         $contents = array("version" => $version, "domainDepth" => $domainDepth, "cid" => $cid1.".".$cid2);
  49.         $cid = $contents["cid"];
  50.     } else $cid = gaGenUUID(); // Fallback
  51.     return $cid;
  52. }
  53.  
  54. // Generate UUID v4 function - needed to generate a CID when one isn"t available
  55. function gaGenUUID() {
  56.     return sprintf( "%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
  57.     // 32 bits for "time_low"
  58.     mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
  59.     // 16 bits for "time_mid"
  60.  
  61.     mt_rand( 0, 0xffff ),
  62.     // 16 bits for "time_hi_and_version",
  63.     // four most significant bits holds version number 4
  64.     mt_rand( 0, 0x0fff ) | 0x4000,
  65.  
  66.     // 16 bits, 8 bits for "clk_seq_hi_res",
  67.     // 8 bits for "clk_seq_low",
  68.     // two most significant bits holds zero and one for variant DCE1.1
  69.     mt_rand( 0, 0x3fff ) | 0x8000,
  70.  
  71.     // 48 bits for "node"
  72.     mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
  73.     );
  74. }
  75.  
  76. /* 4th match document URI with UA-String to send GA-Event to corresponding GA property */
  77. // If you are administering multiple customers. Else simply set $tid in function gaBuildHit and comment this section
  78. function uaString () {
  79.     $documentUri = $c(["csp-report"]["document-uri"]);
  80.     switch($documentUri) {
  81.         case (preg_match('/^(https?:\/\/)?.*mikeg.de', $documentUri) ? true : false) :
  82.             $analyticsUA = "YOUR ANALYTICS UA-PROPERTY ID";
  83.             break;
  84.         case (preg_match('/John.*/', $documentUri) ? true : false) :
  85.             $analyticsUA = "";
  86.             break;
  87.     }
  88.     return $analyticsUA;
  89. }
  90.  
  91. /* 5th Send GA Event via Measurement Protocol
  92.     Google Analytics Hit Builder: https://ga-dev-tools.appspot.com/hit-builder/
  93.     URL-Schemata: v=1&t=event&tid=UA-XXXXX-Y&cid=[Client ID form 1st party Cookie]&ec=[Event Category]&ea=[Event Action]&el=[Event Label]&ev=[Event label]
  94. */
  95. function gaBuildHit( $method = null, $info = null ) {
  96.     if ( $method && $info) {
  97.         $data = [
  98.             $v = 1,
  99.             $t=event,
  100.             $tid = $analyticsUA, // Put your own Analytics ID in here
  101.             $cid = gaParseCookie(),
  102.             $ec = "CSP-Error" + $c(["csp-report"]["effective-directive"]),
  103.             $ea = $c(["csp-report"]["violated-directive"]),
  104.             $el = $c(["csp-report"]["original-policy"]),
  105.             $dl = $c(["csp-report"]["document-uri"])
  106.         ];
  107.  
  108.         gaFireHit($data);
  109.     }
  110. }
  111.  
  112. // See https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide
  113. function gaFireHit( $data = null ) {
  114.     if ( $data ) {
  115.         $getString = 'https://ssl.google-analytics.com/collect';
  116.         $getString .= '?payload_data&';
  117.         $getString .= http_build_query($data);
  118.         $result = wp_remote_get( $getString );
  119.         // $sendlog = error_log($getString, 1, "YOUR_EMAIL@YOUR_DOMAIN.TLD"); // comment this in and change your email to get an log sent to your email
  120.         return $result;
  121.     }
  122.     return false;
  123. }
  124.  
  125. /* fallback: write CSP violation to server file
  126.     http://php.net/manual/en/function.syslog.php
  127. */
  128. //file_put_contents("csp.errors", $c, FILE_APPEND);
  129. ?>
Add Comment
Please, Sign In to add comment