Seditio Source
Root |
./othercms/dotclear-2.22/admin/csp_report.php
<?php
/**
 * @package Dotclear
 * @subpackage Backend
 *
 * @copyright Olivier Meunier & Association Dotclear
 * @copyright GPL-2.0-only
 *
 * @var dcCore $core
 */

// From: https://github.com/nico3333fr/CSP-useful
//
// Note: this script requires PHP ≥ 5.4.
// Inspired from https://mathiasbynens.be/notes/csp-reports

// Dareboost wants it? Not a problem.
header('X-Content-Type-Options: "nosniff"');

require
__DIR__ . '/../inc/admin/prepend.php';

// Specify admin CSP log file if necessary
if (!defined('LOGFILE')) {
   
define('LOGFILE', path::real(DC_VAR) . '/csp/csp_report.json');
}

// Get the raw POST data
$data = file_get_contents('php://input');

// Only continue if it’s valid JSON that is not just `null`, `0`, `false` or an
// empty string, i.e. if it could be a CSP violation report.
if ($data = json_decode($data, true)) {

   
// get source-file and blocked-URI to perform some tests
   
$source_file        = $data['csp-report']['source-file']        ?? '';
   
$line_number        = $data['csp-report']['line-number']        ?? '';
   
$blocked_uri        = $data['csp-report']['blocked-uri']        ?? '';
   
$document_uri       = $data['csp-report']['document-uri']       ?? '';
   
$violated_directive = $data['csp-report']['violated-directive'] ?? '';

    if (
       
// avoid false positives notifications coming from Chrome extensions (Wappalyzer, MuteTab, etc.)
        // bug here https://code.google.com/p/chromium/issues/detail?id=524356
       
strpos($source_file, 'chrome-extension://') === false

       
// avoid false positives notifications coming from Safari extensions (diigo, evernote, etc.)
         
&& strpos($source_file, 'safari-extension://') === false
       
&& strpos($blocked_uri, 'safari-extension://') === false

       
// search engine extensions ?
         
&& strpos($source_file, 'se-extension://') === false

       
// added by browsers in webviews
         
&& strpos($blocked_uri, 'webviewprogressproxy://') === false

       
// Google Search App see for details https://github.com/nico3333fr/CSP-useful/commit/ecc8f9b0b379ae643bc754d2db33c8b47e185fd1
         
&& strpos($blocked_uri, 'gsa://onpageload') === false

   
) {
       
// Prepare report data (hash => info)
       
$hash = hash('md5', $blocked_uri . $document_uri . $source_file . $line_number . $violated_directive);

        try {
           
// Check report dir (create it if necessary)
           
files::makeDir(dirname(LOGFILE), true);

           
// Check if report is not already stored in log file
           
$contents = '';
            if (
file_exists(LOGFILE)) {
               
$contents = file_get_contents(LOGFILE);
                if (
$contents) {
                    if (
substr($contents, -1) == ',') {
                       
// Remove final comma if present
                       
$contents = substr($contents, 0, -1);
                    }
                    if (
$contents != '') {
                       
$list = json_decode('[' . $contents . ']', true);
                        if (
is_array($list)) {
                            foreach (
$list as $idx => $value) {
                                if (isset(
$value['hash']) && $value['hash'] == $hash) {
                                   
// Already stored, ignore
                                   
return;
                                }
                            }
                        }
                    }
                }
            }

           
// Add report to the file
           
if (!($fp = @fopen(LOGFILE, 'a'))) {
               
// Unable to open file, ignore
               
return;
            }

           
// Prettify the JSON-formatted data
           
$violation = array_merge(['hash' => $hash], $data['csp-report']);
           
$output    = json_encode($violation, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

           
// The file content will have to be enclosed in brackets [] before
            // beeing decoded with json_decoded(<content>,true);
           
fprintf($fp, ($contents != '' ? ',' : '') . '%s', $output);
        } catch (
Exception $e) {
            return;
        }
    }
}