Dotclear

source: admin/csp_report.php @ 3874:ab8368569446

Revision 3874:ab8368569446, 4.2 KB checked in by franck <carnet.franck.paul@…>, 7 years ago (diff)

short notation for array (array() → [])

Line 
1<?php
2/**
3 * @package Dotclear
4 * @subpackage Backend
5 *
6 * @copyright Olivier Meunier & Association Dotclear
7 * @copyright GPL-2.0-only
8 */
9
10// From: https://github.com/nico3333fr/CSP-useful
11//
12// Note: this script requires PHP ≥ 5.4.
13// Inspired from https://mathiasbynens.be/notes/csp-reports
14
15// Dareboost wants it? Not a problem.
16header('X-Content-Type-Options: "nosniff"');
17
18require dirname(__FILE__) . '/../inc/admin/prepend.php';
19
20// Specify admin CSP log file if necessary
21if (!defined('LOGFILE')) {
22    define('LOGFILE', path::real(DC_VAR) . '/csp/csp_report.json');
23}
24
25// Get the raw POST data
26$data = file_get_contents('php://input');
27
28// Only continue if it’s valid JSON that is not just `null`, `0`, `false` or an
29// empty string, i.e. if it could be a CSP violation report.
30if ($data = json_decode($data, true)) {
31
32    // get source-file and blocked-URI to perform some tests
33    $source_file        = isset($data['csp-report']['source-file']) ? $data['csp-report']['source-file'] : '';
34    $line_number        = isset($data['csp-report']['line-number']) ? $data['csp-report']['line-number'] : '';
35    $blocked_uri        = isset($data['csp-report']['blocked-uri']) ? $data['csp-report']['blocked-uri'] : '';
36    $document_uri       = isset($data['csp-report']['document-uri']) ? $data['csp-report']['document-uri'] : '';
37    $violated_directive = isset($data['csp-report']['violated-directive']) ? $data['csp-report']['violated-directive'] : '';
38
39    if (
40        // avoid false positives notifications coming from Chrome extensions (Wappalyzer, MuteTab, etc.)
41        // bug here https://code.google.com/p/chromium/issues/detail?id=524356
42        strpos($source_file, 'chrome-extension://') === false
43
44        // avoid false positives notifications coming from Safari extensions (diigo, evernote, etc.)
45         && strpos($source_file, 'safari-extension://') === false
46        && strpos($blocked_uri, 'safari-extension://') === false
47
48        // search engine extensions ?
49         && strpos($source_file, 'se-extension://') === false
50
51        // added by browsers in webviews
52         && strpos($blocked_uri, 'webviewprogressproxy://') === false
53
54        // Google Search App see for details https://github.com/nico3333fr/CSP-useful/commit/ecc8f9b0b379ae643bc754d2db33c8b47e185fd1
55         && strpos($blocked_uri, 'gsa://onpageload') === false
56
57    ) {
58        // Prepare report data (hash => info)
59        $hash = hash('md5', $blocked_uri . $document_uri . $source_file . $line_number . $violated_directive);
60
61        try {
62            // Check report dir (create it if necessary)
63            files::makeDir(dirname(LOGFILE), true);
64
65            // Check if report is not already stored in log file
66            $contents = '';
67            if (file_exists(LOGFILE)) {
68                $contents = file_get_contents(LOGFILE);
69                if ($contents && $contents != '') {
70                    if (substr($contents, -1) == ',') {
71                        // Remove final comma if present
72                        $contents = substr($contents, 0, -1);
73                    }
74                    if ($contents != '') {
75                        $list = json_decode('[' . $contents . ']', true);
76                        if (is_array($list)) {
77                            foreach ($list as $idx => $value) {
78                                if (isset($value['hash']) && $value['hash'] == $hash) {
79                                    // Already stored, ignore
80                                    return;
81                                }
82                            }
83                        }
84                    }
85                }
86            }
87
88            // Add report to the file
89            if (!($fp = @fopen(LOGFILE, 'a'))) {
90                // Unable to open file, ignore
91                return;
92            }
93
94            // Prettify the JSON-formatted data
95            $violation = array_merge(['hash' => $hash], $data['csp-report']);
96            $output    = json_encode($violation, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
97
98            // The file content will have to be enclosed in brackets [] before
99            // beeing decoded with json_decoded(<content>,true);
100            fprintf($fp, ($contents != '' ? ',' : '') . '%s', $output);
101
102        } catch (Exception $e) {
103            return;
104        }
105    }
106}
Note: See TracBrowser for help on using the repository browser.

Sites map