Browse Source

Refactor and enforce Content-Security-Policy

Skylar Ittner 1 year ago
parent
commit
5dae7bc168
4 changed files with 70 additions and 3 deletions
  1. 2
    2
      app.php
  2. 1
    0
      mobile/index.php
  3. 45
    1
      required.php
  4. 22
    0
      static/css/app.css

+ 2
- 2
app.php View File

@@ -74,7 +74,7 @@ if (!is_empty($_GET['page'])) {
74 74
                                 }
75 75
                                 ?>
76 76
                                 <a class="navbar-brand" href="app.php">
77
-                                    <img style="height: 35px; padding-bottom: 12px; padding-left: 5px;" src="<?php echo $src; ?>" />
77
+                                    <img src="<?php echo $src; ?>" />
78 78
                                 </a>
79 79
                                 <?php
80 80
                             }
@@ -124,7 +124,7 @@ if (!is_empty($_GET['page'])) {
124 124
             <?php
125 125
             if (MENU_BAR_STYLE == "fixed") {
126 126
                 ?>
127
-                <div style="height: 75px;"></div>
127
+                <div class="pad-75px"></div>
128 128
                 <?php
129 129
             }
130 130
             ?>

+ 1
- 0
mobile/index.php View File

@@ -94,6 +94,7 @@ switch ($VARS['action']) {
94 94
                 if (authenticate_user($VARS['username'], $VARS['password'], $autherror)) {
95 95
                     if (is_null($access_permission) || account_has_permission($VARS['username'], $access_permission)) {
96 96
                         doLoginUser($VARS['username'], $VARS['password']);
97
+                        $_SESSION['mobile'] = true;
97 98
                         exit(json_encode(["status" => "OK"]));
98 99
                     } else {
99 100
                         exit(json_encode(["status" => "ERROR", "msg" => lang("no admin permission", false)]));

+ 45
- 1
required.php View File

@@ -10,12 +10,42 @@ header('Content-Type: text/html; charset=utf-8');
10 10
 // l33t $ecurity h4x
11 11
 header('X-Content-Type-Options: nosniff');
12 12
 header('X-XSS-Protection: 1; mode=block');
13
+header('X-Powered-By: PHP'); // no versions makes it harder to find vulns
14
+header('X-Frame-Options: "DENY"');
15
+header('Referrer-Policy: "no-referrer, strict-origin-when-cross-origin"');
16
+$SECURE_NONCE = base64_encode(random_bytes(8));
17
+
13 18
 $session_length = 60 * 60; // 1 hour
14 19
 session_set_cookie_params($session_length, "/", null, false, false);
15 20
 
16 21
 session_start(); // stick some cookies in it
17 22
 // renew session cookie
18 23
 setcookie(session_name(), session_id(), time() + $session_length);
24
+
25
+if ($_SESSION['mobile'] === TRUE) {
26
+    header("Content-Security-Policy: "
27
+            . "default-src 'self';"
28
+            . "object-src 'none'; "
29
+            . "img-src * data:; "
30
+            . "media-src 'self'; "
31
+            . "frame-src 'none'; "
32
+            . "font-src 'self'; "
33
+            . "connect-src *; "
34
+            . "style-src 'self' 'unsafe-inline'; "
35
+            . "script-src 'self' 'unsafe-inline'");
36
+} else {
37
+    header("Content-Security-Policy: "
38
+            . "default-src 'self';"
39
+            . "object-src 'none'; "
40
+            . "img-src * data:; "
41
+            . "media-src 'self'; "
42
+            . "frame-src 'none'; "
43
+            . "font-src 'self'; "
44
+            . "connect-src *; "
45
+            . "style-src 'self' 'nonce-$SECURE_NONCE'; "
46
+            . "script-src 'self' 'nonce-$SECURE_NONCE'");
47
+}
48
+
19 49
 //
20 50
 // Composer
21 51
 require __DIR__ . '/vendor/autoload.php';
@@ -32,7 +62,21 @@ require __DIR__ . '/lang/' . LANGUAGE . ".php";
32 62
  * @param string $error error message
33 63
  */
34 64
 function sendError($error) {
35
-    die("<!DOCTYPE html><html><head><title>Error</title></head><body><h1 style='color: red; font-family: sans-serif; font-size:100%;'>" . htmlspecialchars($error) . "</h1></body></html>");
65
+    global $SECURE_NONCE;
66
+    die("<!DOCTYPE html>"
67
+            . "<meta charset=\"UTF-8\">"
68
+            . "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
69
+            . "<title>Error</title>"
70
+            . "<style nonce=\"" . $SECURE_NONCE . "\">"
71
+            . "h1 {color: red; font-family: sans-serif; font-size: 20px; margin-bottom: 0px;} "
72
+            . "h2 {font-family: sans-serif; font-size: 16px;} "
73
+            . "p {font-family: monospace; font-size: 14px; width: 100%; wrap-style: break-word;} "
74
+            . "i {font-size: 12px;}"
75
+            . "</style>"
76
+            . "<h1>A fatal application error has occurred.</h1>"
77
+            . "<i>(This isn't your fault.)</i>"
78
+            . "<h2>Details:</h2>"
79
+            . "<p>" . htmlspecialchars($error) . "</p>");
36 80
 }
37 81
 
38 82
 date_default_timezone_set(TIMEZONE);

+ 22
- 0
static/css/app.css View File

@@ -9,6 +9,28 @@
9 9
     font-size: 110%;
10 10
 }
11 11
 
12
+.navbar-brand img {
13
+    height: 35px;
14
+    padding-bottom: 12px;
15
+    padding-left: 5px;
16
+}
17
+
18
+.pad-75px {
19
+    height: 75px;
20
+}
21
+
22
+.mgn-btm-10px {
23
+    margin-bottom: 10px;
24
+}
25
+
26
+.mgn-top-8px {
27
+    margin-top: 8px;
28
+}
29
+
30
+.black-text {
31
+    color: black;
32
+}
33
+
12 34
 .footer {
13 35
     margin-top: 10em;
14 36
     text-align: center;

Loading…
Cancel
Save