xref: /plugin/combo/action/metacsp.php (revision 85e82846b0a214bc35e62864fa49d9cad0723d0e)
1<?php
2
3use ComboStrap\Site;
4use ComboStrap\StringUtility;
5
6if (!defined('DOKU_INC')) die();
7
8/**
9 *
10 * Adding security directive
11 *
12 */
13class action_plugin_combo_metacsp extends DokuWiki_Action_Plugin
14{
15
16
17    function __construct()
18    {
19        // enable direct access to language strings
20        // ie $this->lang
21        $this->setupLocale();
22    }
23
24    public function register(Doku_Event_Handler $controller)
25    {
26        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'metaCsp', array());
27    }
28
29    /**
30     * Dokuwiki has already a canonical methodology
31     * https://www.dokuwiki.org/canonical
32     *
33     * @param $event
34     */
35    function metaCsp($event)
36    {
37
38
39        /**
40         * HTML meta directives
41         */
42        $directives = [
43            'block-all-mixed-content', // no http, https
44        ];
45
46        // Search if the CSP property is already present
47        $cspKey = null;
48        foreach ($event->data['meta'] as $key => $meta) {
49            if (isset($meta["http-equiv"])) {
50                if ($meta["http-equiv"] == "content-security-policy") {
51                    $cspKey = $key;
52                }
53            }
54        }
55        if ($cspKey != null) {
56            $actualDirectives = StringUtility::explodeAndTrim($event->data['meta'][$cspKey]["content"], ",");
57            $directives = array_merge($actualDirectives, $directives);
58            $event->data['meta'][$cspKey] = [
59                "http-equiv" => "content-security-policy",
60                "content" => join(", ", $directives)
61            ];
62        } else {
63            $event->data['meta'][] = [
64                "http-equiv" => "content-security-policy",
65                "content" => join(",", $directives)
66            ];
67        }
68
69        /**
70         * Http header CSP directives
71         */
72        $httpHeaderReferer = $_SERVER['HTTP_REFERER'];
73        $httpDirectives = [];
74        if (strpos($httpHeaderReferer, Site::getUrl()) === false) {
75            // not same origin
76            $httpDirectives = [
77                "content-security-policy: frame-ancestors 'none'", // the page cannot be used in a iframe (clickjacking),
78                "X-Frame-Options: deny" // the page cannot be used in a iframe (clickjacking) - deprecated for frame ancestores
79            ];
80        }
81        foreach ($httpDirectives as $httpDirective) {
82            header($httpDirective);
83        }
84
85    }
86
87}
88