PluginProbe
HTTP Headers / 1.2.0
HTTP Headers v1.2.0
1.19.5 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.12.0 1.12.1 1.12.2 1.13.0 1.13.1 1.13.2 1.13.3 1.13.4 1.14.0 1.14.1 1.14.2 1.15.0 All 60 releases
← All changes | http-headers.php +74 -1200 1.13.31.2.0 View file →
@@ -1,10 +1,10 @@
1 1 <?php
2 2 /*
3 3 Plugin Name: HTTP Headers
4 4 Plugin URI: https://zinoui.com/blog/http-headers-for-wordpress
5 -Description: A plugin for HTTP headers management including security, access-control (CORS), caching, compression, and authentication.
6 -Version: 1.13.3
5 +Description: This plugin adds CORS & security HTTP headers to your website. Improves your website overall security.
6 +Version: 1.2.0
7 7 Author: Dimitar Ivanov
8 8 Author URI: https://zinoui.com
9 9 License: GPLv2 or later
10 10 Text Domain: http-headers
@@ -23,126 +23,40 @@
23 23
24 24 You should have received a copy of the GNU General Public License
25 25 along with this program. If not, see <http://www.gnu.org/copyleft/gpl.html>.
26 26
27 -Copyright (c) 2017-2019 Zino UI
27 +Copyright (c) 2017 Zino UI
28 28 */
29 29
30 -if (!defined('ABSPATH')) {
31 - exit;
30 +if (get_option('hh_strict_transport_security_max_age') === false) {
31 + $value = get_option('hh_strict_transport_security_value');
32 + $max_age = preg_match('/max-age=(\d+)/', $value, $match) ? $match[1] : 0;
33 + $sub_domains = strpos($value, 'includeSubDomains') !== false ? 1 : 0;
34 + add_option('hh_strict_transport_security_max_age', $max_age, null, 'yes');
35 + add_option('hh_strict_transport_security_sub_domains', $sub_domains, null, 'yes');
36 + add_option('hh_strict_transport_security_preload', 0, null, 'yes');
32 37 }
33 38
34 -$options = include dirname(__FILE__) . '/views/includes/options.inc.php';
35 -foreach ($options as $option) {
36 - if (get_option($option[0]) === false) {
37 - add_option($option[0], $option[1], null, 'yes');
38 - }
39 +if (get_option('hh_referrer_policy') === false) {
40 + add_option('hh_referrer_policy', 0, null, 'yes');
41 + add_option('hh_referrer_policy_value', null, null, 'yes');
39 42 }
40 43
41 -function build_csp_value($value) {
42 - $csp = array();
43 - foreach ($value as $key => $val)
44 - {
45 - if (is_array($val))
46 - {
47 - $source = NULL;
48 - if (isset($val['source']))
49 - {
50 - $source = $val['source'];
51 - unset($val['source']);
52 - }
53 - if (!empty($val))
54 - {
55 - $val = join(" ", array_keys($val));
56 - if ($source)
57 - {
58 - $val .= " " . $source;
59 - }
60 - $csp[] = sprintf("%s %s", $key, $val);
61 - } elseif ($source) {
62 - $csp[] = sprintf("%s %s", $key, $source);
63 - }
64 - } else {
65 - if (in_array($key, array('block-all-mixed-content', 'upgrade-insecure-requests')))
66 - {
67 - $csp[] = $key;
68 - }
69 - if (in_array($key, array('plugin-types', 'report-to')) && !empty($val))
70 - {
71 - $csp[] = sprintf("%s %s", $key, $val);
72 - }
73 - }
74 - }
75 -
76 - if (!$csp)
77 - {
78 - return NULL;
79 - }
80 -
81 - return join('; ', $csp);
82 -}
83 -
84 -function get_http_headers() {
85 - $statuses = array();
86 - $unset = array();
87 - $headers = array();
88 - $append = array();
44 +function http_headers() {
45 +
89 46 if (get_option('hh_x_frame_options') == 1) {
90 47 $x_frame_options_value = strtoupper(get_option('hh_x_frame_options_value'));
91 48 if ($x_frame_options_value == 'ALLOW-FROM') {
92 49 $x_frame_options_value .= ' ' . get_option('hh_x_frame_options_domain');
93 50 }
94 - $headers['X-Frame-Options'] = $x_frame_options_value;
51 + header("X-Frame-Options: " . $x_frame_options_value);
95 52 }
96 - if (get_option('hh_x_powered_by') == 1) {
97 - if (get_option('hh_x_powered_by_option') == 'set') {
98 - $headers['X-Powered-By'] = get_option('hh_x_powered_by_value');
99 - } else {
100 - $unset[] = 'X-Powered-By';
101 - }
102 - }
103 53 if (get_option('hh_x_xxs_protection') == 1) {
104 - $headers['X-XSS-Protection'] = get_option('hh_x_xxs_protection_value');
105 - if ($headers['X-XSS-Protection'] == '1; report=') {
106 - $headers['X-XSS-Protection'] .= get_option('hh_x_xxs_protection_uri');
107 - }
54 + header("X-XSS-Protection: " . get_option('hh_x_xxs_protection_value'));
108 55 }
109 56 if (get_option('hh_x_content_type_options') == 1) {
110 - $headers['X-Content-Type-Options'] = get_option('hh_x_content_type_options_value');
57 + header("X-Content-Type-Options: " . get_option('hh_x_content_type_options_value'));
111 58 }
112 - if (get_option('hh_x_download_options') == 1) {
113 - $headers['X-Download-Options'] = get_option('hh_x_download_options_value');
114 - }
115 - if (get_option('hh_x_permitted_cross_domain_policies') == 1) {
116 - $headers['X-Permitted-Cross-Domain-Policies'] = get_option('hh_x_permitted_cross_domain_policies_value');
117 - }
118 - if (get_option('hh_x_dns_prefetch_control') == 1) {
119 - $headers['X-DNS-Prefetch-Control'] = get_option('hh_x_dns_prefetch_control_value');
120 - }
121 - if (get_option('hh_connection') == 1) {
122 - $headers['Connection'] = get_option('hh_connection_value');
123 - }
124 - if (get_option('hh_pragma') == 1) {
125 - $headers['Pragma'] = get_option('hh_pragma_value');
126 - }
127 - if (get_option('hh_age') == 1) {
128 - $headers['Age'] = sprintf("%u", get_option('hh_age_value'));
129 - }
130 - if (get_option('hh_cache_control') == 1) {
131 - $hh_cache_control_value = get_option('hh_cache_control_value', array());
132 - $tmp = array();
133 - foreach ($hh_cache_control_value as $k => $v) {
134 - if (in_array($k, array('max-age', 's-maxage'))) {
135 - if (strlen($v) > 0) {
136 - $tmp[] = sprintf("%s=%u", $k, $v);
137 - }
138 - } else {
139 - $tmp[] = $k;
140 - }
141 - }
142 - $hh_cache_control_value = join(', ', $tmp);
143 - $headers['Cache-Control'] = $hh_cache_control_value;
144 - }
145 59 if (get_option('hh_strict_transport_security') == 1) {
146 60 $hh_strict_transport_security = array();
147 61
148 62 $hh_strict_transport_security_max_age = get_option('hh_strict_transport_security_max_age');
@@ -159,12 +73,12 @@
159 73 }
160 74 } else {
161 75 $hh_strict_transport_security = array(get_option('hh_strict_transport_security_value'));
162 76 }
163 - $headers['Strict-Transport-Security'] = join('; ', $hh_strict_transport_security);
77 + header("Strict-Transport-Security: " . join('; ', $hh_strict_transport_security));
164 78 }
165 79 if (get_option('hh_x_ua_compatible') == 1) {
166 - $headers['X-UA-Compatible'] = get_option('hh_x_ua_compatible_value');
80 + header("X-UA-Compatible: " . get_option('hh_x_ua_compatible_value'));
167 81 }
168 82 if (get_option('hh_public_key_pins') == 1) {
169 83 $public_key_pins_sha256_1 = get_option('hh_public_key_pins_sha256_1');
170 84 $public_key_pins_sha256_2 = get_option('hh_public_key_pins_sha256_2');
@@ -170,9 +84,8 @@
170 84 $public_key_pins_sha256_2 = get_option('hh_public_key_pins_sha256_2');
171 85 $public_key_pins_max_age = get_option('hh_public_key_pins_max_age');
172 86 $public_key_pins_sub_domains = get_option('hh_public_key_pins_sub_domains');
173 87 $public_key_pins_report_uri = get_option('hh_public_key_pins_report_uri');
174 - $public_key_pins_report_only = get_option('hh_public_key_pins_report_only');
175 88 if (!empty($public_key_pins_sha256_1) && !empty($public_key_pins_sha256_2) && !empty($public_key_pins_max_age)) {
176 89
177 90 $public_key_pins = array();
178 91 $public_key_pins[] = sprintf('pin-sha256="%s"', $public_key_pins_sha256_1);
@@ -183,22 +96,14 @@
183 96 }
184 97 if (!empty($public_key_pins_report_uri)) {
185 98 $public_key_pins[] = sprintf('report-uri="%s"', $public_key_pins_report_uri);
186 99 }
187 - $headers['Public-Key-Pins'.($public_key_pins_report_only ? '-Report-Only' : NULL)] = join('; ', $public_key_pins);
100 + header(sprintf("Public-Key-Pins: %s", join('; ', $public_key_pins)));
188 101 }
189 102 }
190 103
191 - if (get_option('hh_content_security_policy') == 1)
192 - {
193 - $value = get_option('hh_content_security_policy_value');
194 - $csp = build_csp_value($value);
195 - if ($csp)
196 - {
197 - $csp_report_only = get_option('hh_content_security_policy_report_only');
198 - $headers['Content-Security-Policy'.($csp_report_only ? '-Report-Only' : NULL)] = $csp;
199 - }
200 - }
104 + # TODO
105 + //header("Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';");
201 106
202 107 if (get_option('hh_access_control_allow_origin') == 1)
203 108 {
204 109 $value = get_option('hh_access_control_allow_origin_value');
@@ -203,24 +108,23 @@
203 108 {
204 109 $value = get_option('hh_access_control_allow_origin_value');
205 110 switch ($value)
206 111 {
112 + case 'HTTP_ORIGIN':
113 + $value = @$_SERVER['HTTP_ORIGIN'];
114 + break;
207 115 case 'origin':
208 - $value = get_option('hh_access_control_allow_origin_url', array());
209 - if (is_scalar($value))
210 - {
211 - $value = array($value);
212 - }
116 + $value = get_option('hh_access_control_allow_origin_url');
213 117 break;
214 118 }
215 119 if (!empty($value))
216 120 {
217 - $headers['Access-Control-Allow-Origin'] = $value;
121 + header("Access-Control-Allow-Origin: " . $value);
218 122 }
219 123 }
220 124 if (get_option('hh_access_control_allow_credentials') == 1)
221 125 {
222 - $headers['Access-Control-Allow-Credentials'] = get_option('hh_access_control_allow_credentials_value');
126 + header("Access-Control-Allow-Credentials: " . get_option('hh_access_control_allow_credentials_value'));
223 127 }
224 128 if (get_option('hh_access_control_max_age') == 1)
225 129 {
226 130 $value = get_option('hh_access_control_max_age_value');
@@ -225,9 +129,9 @@
225 129 {
226 130 $value = get_option('hh_access_control_max_age_value');
227 131 if (!empty($value))
228 132 {
229 - $headers['Access-Control-Max-Age'] = intval($value);
133 + header("Access-Control-Max-Age: " . intval($value));
230 134 }
231 135 }
232 136 if (get_option('hh_access_control_allow_methods') == 1)
233 137 {
@@ -233,9 +137,9 @@
233 137 {
234 138 $value = get_option('hh_access_control_allow_methods_value');
235 139 if (!empty($value))
236 140 {
237 - $headers['Access-Control-Allow-Methods'] = join(', ', array_keys($value));
141 + header("Access-Control-Allow-Methods: " . join(', ', array_keys($value)));
238 142 }
239 143 }
240 144 if (get_option('hh_access_control_allow_headers') == 1)
241 145 {
@@ -241,9 +145,9 @@
241 145 {
242 146 $value = get_option('hh_access_control_allow_headers_value');
243 147 if (!empty($value))
244 148 {
245 - $headers['Access-Control-Allow-Headers'] = join(', ', array_keys($value));
149 + header("Access-Control-Allow-Headers: " . join(', ', array_keys($value)));
246 150 }
247 151 }
248 152 if (get_option('hh_access_control_expose_headers') == 1)
249 153 {
@@ -249,9 +153,9 @@
249 153 {
250 154 $value = get_option('hh_access_control_expose_headers_value');
251 155 if (!empty($value))
252 156 {
253 - $headers['Access-Control-Expose-Headers'] = join(', ', array_keys($value));
157 + header("Access-Control-Expose-Headers: " . join(', ', array_keys($value)));
254 158 }
255 159 }
256 160 if (get_option('hh_p3p') == 1)
257 161 {
@@ -257,920 +161,60 @@
257 161 {
258 162 $value = get_option('hh_p3p_value');
259 163 if (!empty($value))
260 164 {
261 - $headers['P3P'] = 'CP="' . join(' ', array_keys($value)) . '"';
165 + header('P3P: CP="' . join(' ', array_keys($value)) . '"');
262 166 }
263 167 }
264 168 if (get_option('hh_referrer_policy') == 1) {
265 - $headers['Referrer-Policy'] = get_option('hh_referrer_policy_value');
169 + header("Referrer-Policy: " . get_option('hh_referrer_policy_value'));
266 170 }
267 - if (get_option('hh_www_authenticate') == 1) {
268 -
269 - switch (get_option('hh_www_authenticate_type')) {
270 - case 'Basic':
271 - if (!(isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])
272 - && $_SERVER['PHP_AUTH_USER'] == get_option('hh_www_authenticate_user')
273 - && $_SERVER['PHP_AUTH_PW'] == get_option('hh_www_authenticate_pswd'))) {
274 - $headers['WWW-Authenticate'] = sprintf("Basic realm='%s'", get_option('hh_www_authenticate_realm'));
275 - $statuses['HTTP/1.1'] = '401 Unauthorized';
276 - }
277 - break;
278 - case 'Digest':
279 - if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
280 - $realm = get_option('hh_www_authenticate_realm');
281 - $headers['WWW-Authenticate'] = sprintf("Digest realm='%s',qop='auth',nonce='%s',opaque='%s'",
282 - $realm, uniqid(), md5($realm));
283 - $statuses['HTTP/1.1'] = '401 Unauthorized';
284 - }
285 - break;
286 - }
287 - }
288 - if (get_option('hh_vary') == 1)
289 - {
290 - $value = get_option('hh_vary_value');
291 - if (!empty($value))
292 - {
293 - $append['Vary'] = join(', ', array_keys($value));
294 - }
295 - }
296 -
297 - if (get_option('hh_expect_ct') == 1) {
298 - $expect_ct_max_age = get_option('hh_expect_ct_max_age');
299 - $expect_ct_report_uri = get_option('hh_expect_ct_report_uri');
300 - if (!empty($expect_ct_report_uri) && !empty($expect_ct_max_age)) {
301 -
302 - $expect_ct = array();
303 - $expect_ct[] = sprintf("max-age=%u", $expect_ct_max_age);
304 - if (get_option('hh_expect_ct_enforce') == 1) {
305 - $expect_ct[] = "enforce";
306 - }
307 - $expect_ct[] = sprintf('report-uri="%s"', $expect_ct_report_uri);
308 - $headers['Expect-CT'] = join(', ', $expect_ct);
309 - }
310 - }
311 - if (get_option('hh_custom_headers') == 1) {
312 - $custom_headers = get_option('hh_custom_headers_value');
313 - if (isset($custom_headers['name'], $custom_headers['value']) && !empty($custom_headers['name'])) {
314 - foreach ($custom_headers['name'] as $key => $name) {
315 - $name = trim($name);
316 - $value = trim($custom_headers['value'][$key]);
317 - if (empty($name) || empty($value)) {
318 - continue;
319 - }
320 - $headers[$name] = $value;
321 - }
322 - }
323 - }
324 - if (get_option('hh_report_to') == 1) {
325 - $report_to = get_option('hh_report_to_value');
326 - $tmp = array();
327 - foreach ($report_to as $item)
328 - {
329 - $tmp[] = sprintf('{"url": "%s", "group": "%s", "max-age": %u%s}',
330 - $item['url'], $item['group'], $item['max-age'], isset($item['includeSubDomains']) ? ', includeSubDomains' : NULL);
331 - }
332 - if ($tmp)
333 - {
334 - $headers['Report-To'] = join(', ', $tmp);
335 - }
336 - }
337 - if (get_option('hh_feature_policy') == 1) {
338 - $feature_policy_feature = get_option('hh_feature_policy_feature');
339 - $feature_policy_value = get_option('hh_feature_policy_value');
340 - $feature_policy_origin = get_option('hh_feature_policy_origin');
341 - $tmp = array();
342 - $feature_policy_feature = is_array($feature_policy_feature) ? $feature_policy_feature : array();
343 - foreach (array_keys($feature_policy_feature) as $feature)
344 - {
345 - $value = NULL;
346 - switch ($feature_policy_value[$feature])
347 - {
348 - case '*':
349 - case "'none'":
350 - $value = $feature_policy_value[$feature];
351 - break;
352 - case "'self'":
353 - $value = $feature_policy_value[$feature];
354 - if (!empty($feature_policy_origin[$feature]))
355 - {
356 - $value .= " " . $feature_policy_origin[$feature];
357 - }
358 - break;
359 - case 'origin(s)':
360 - $value = $feature_policy_origin[$feature];
361 - break;
362 - }
363 -
364 - $tmp[] = sprintf("%s %s", $feature, $value);
365 - }
366 - if ($tmp)
367 - {
368 - $headers['Feature-Policy'] = join('; ', $tmp);
369 - }
370 - }
371 -
372 - return array($headers, $statuses, $unset, $append);
373 171 }
374 172
375 -function http_digest_parse($txt) {
376 - $txt = stripslashes($txt);
377 -
378 - $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
379 - $data = array();
380 - $keys = implode('|', array_keys($needed_parts));
381 -
382 - preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);
383 -
384 - foreach ($matches as $m) {
385 - $data[$m[1]] = $m[3] ? $m[3] : $m[4];
386 - unset($needed_parts[$m[1]]);
387 - }
388 -
389 - return $needed_parts ? false : $data;
390 -}
391 -
392 -function php_auth_digest() {
393 - if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || get_option('hh_www_authenticate_user') != $data['username']) {
394 - die('Wrong Credentials!');
395 - }
396 -
397 - $A1 = md5($data['username'] . ':' . get_option('hh_www_authenticate_realm') . ':' . get_option('hh_www_authenticate_pswd'));
398 - $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
399 - $valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
400 - if ($data['response'] != $valid_response) {
401 - die('Wrong Credentials!');
402 - }
403 -}
404 -
405 -function php_content_encoding() {
406 - if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) {
407 - ob_start('ob_gzhandler');
408 - } else {
409 - ob_start();
410 - }
411 -}
412 -
413 -function php_cookie_security_directives() {
414 - $lines = array();
415 - if (get_option('hh_cookie_security') == 1) {
416 - $value = get_option('hh_cookie_security_value', array());
417 - if (isset($value['HttpOnly'])) {
418 - $lines[] = 'session.cookie_httponly = on';
419 - }
420 - if (isset($value['Secure'])) {
421 - $lines[] = 'session.cookie_secure = on';
422 - }
423 - if (isset($value['SameSite']) && in_array($value['SameSite'], array('None', 'Lax', 'Strict'))) {
424 - $lines[] = sprintf('session.cookie_samesite = "%s"', $value['SameSite']);
425 - }
426 - }
427 -
428 - return $lines;
429 -}
430 -
431 -function http_headers() {
432 - if (get_option('hh_method') !== 'php') {
433 - return;
434 - }
435 - // PHP method below
436 - list($headers, $statuses, $unset, $append) = get_http_headers();
437 - $isCors = false;
438 - foreach ($headers as $key => $value) {
439 - if ($key == 'Access-Control-Allow-Origin') {
440 - if (isset($_SERVER['HTTP_ORIGIN'])) {
441 - if ($value == '*') {
442 - $isCors = true;
443 - header(sprintf("%s: *", $key));
444 - }
445 -
446 - if (is_array($value) && in_array($_SERVER['HTTP_ORIGIN'], $value)) {
447 - $isCors = true;
448 - header(sprintf("%s: %s", $key, $_SERVER['HTTP_ORIGIN']));
449 - }
450 - }
451 - continue;
452 - }
453 - if (in_array($key, array('Access-Control-Allow-Headers', 'Access-Control-Allow-Methods', 'Access-Control-Allow-Credentials', 'Access-Control-Max-Age', 'Access-Control-Expose-Headers'))) {
454 - if ($isCors) {
455 - header(sprintf("%s: %s", $key, $value));
456 - }
457 - continue;
458 - }
459 - header(sprintf("%s: %s", $key, $value));
460 - }
461 - foreach ($append as $key => $value) {
462 - header(sprintf("%s: %s", $key, $value), false);
463 - }
464 - foreach ($unset as $header) {
465 - if (function_exists('header_remove')) {
466 - header_remove($header);
467 - } else {
468 - header("$header:");
469 - }
470 - }
471 - foreach ($statuses as $key => $value) {
472 - header(sprintf("%s %s", $key, $value));
473 - exit;
474 - }
475 -
476 - if (get_option('hh_www_authenticate') == 1) {
477 - php_auth_digest();
478 - }
479 -
480 - if (get_option('hh_content_encoding') == 1) {
481 - php_content_encoding();
482 - }
483 -}
484 -
485 173 function http_headers_admin_add_page() {
486 174 add_options_page('HTTP Headers', 'HTTP Headers', 'manage_options', 'http-headers', 'http_headers_admin_page');
487 175 }
488 176
489 177 function http_headers_admin() {
490 - register_setting('http-headers-mtd', 'hh_method');
491 - register_setting('http-headers-xfo', 'hh_x_frame_options');
492 - register_setting('http-headers-xfo', 'hh_x_frame_options_value');
493 - register_setting('http-headers-xfo', 'hh_x_frame_options_domain');
494 - register_setting('http-headers-xss', 'hh_x_xxs_protection');
495 - register_setting('http-headers-xss', 'hh_x_xxs_protection_value');
496 - register_setting('http-headers-xss', 'hh_x_xxs_protection_uri');
497 - register_setting('http-headers-cto', 'hh_x_content_type_options');
498 - register_setting('http-headers-cto', 'hh_x_content_type_options_value');
499 - register_setting('http-headers-sts', 'hh_strict_transport_security');
500 - register_setting('http-headers-sts', 'hh_strict_transport_security_value'); //obsolete
501 - register_setting('http-headers-sts', 'hh_strict_transport_security_max_age');
502 - register_setting('http-headers-sts', 'hh_strict_transport_security_sub_domains');
503 - register_setting('http-headers-sts', 'hh_strict_transport_security_preload');
504 - register_setting('http-headers-pkp', 'hh_public_key_pins');
505 - register_setting('http-headers-pkp', 'hh_public_key_pins_sha256_1');
506 - register_setting('http-headers-pkp', 'hh_public_key_pins_sha256_2');
507 - register_setting('http-headers-pkp', 'hh_public_key_pins_max_age');
508 - register_setting('http-headers-pkp', 'hh_public_key_pins_sub_domains');
509 - register_setting('http-headers-pkp', 'hh_public_key_pins_report_uri');
510 - register_setting('http-headers-pkp', 'hh_public_key_pins_report_only');
511 - register_setting('http-headers-uac', 'hh_x_ua_compatible');
512 - register_setting('http-headers-uac', 'hh_x_ua_compatible_value');
513 - register_setting('http-headers-p3p', 'hh_p3p');
514 - register_setting('http-headers-p3p', 'hh_p3p_value');
515 - register_setting('http-headers-rp', 'hh_referrer_policy');
516 - register_setting('http-headers-rp', 'hh_referrer_policy_value');
517 - register_setting('http-headers-csp', 'hh_content_security_policy');
518 - register_setting('http-headers-csp', 'hh_content_security_policy_value');
519 - register_setting('http-headers-csp', 'hh_content_security_policy_report_only');
520 - register_setting('http-headers-acao', 'hh_access_control_allow_origin');
521 - register_setting('http-headers-acao', 'hh_access_control_allow_origin_value');
522 - register_setting('http-headers-acao', 'hh_access_control_allow_origin_url');
523 - register_setting('http-headers-acac', 'hh_access_control_allow_credentials');
524 - register_setting('http-headers-acac', 'hh_access_control_allow_credentials_value');
525 - register_setting('http-headers-acam', 'hh_access_control_allow_methods');
526 - register_setting('http-headers-acam', 'hh_access_control_allow_methods_value');
527 - register_setting('http-headers-acah', 'hh_access_control_allow_headers');
528 - register_setting('http-headers-acah', 'hh_access_control_allow_headers_value');
529 - register_setting('http-headers-aceh', 'hh_access_control_expose_headers');
530 - register_setting('http-headers-aceh', 'hh_access_control_expose_headers_value');
531 - register_setting('http-headers-acma', 'hh_access_control_max_age');
532 - register_setting('http-headers-acma', 'hh_access_control_max_age_value');
533 - register_setting('http-headers-ce', 'hh_content_encoding');
534 - register_setting('http-headers-ce', 'hh_content_encoding_module');
535 - register_setting('http-headers-ce', 'hh_content_encoding_value');
536 - register_setting('http-headers-ce', 'hh_content_encoding_ext');
537 - register_setting('http-headers-vary', 'hh_vary');
538 - register_setting('http-headers-vary', 'hh_vary_value');
539 - register_setting('http-headers-xpb', 'hh_x_powered_by');
540 - register_setting('http-headers-xpb', 'hh_x_powered_by_option');
541 - register_setting('http-headers-xpb', 'hh_x_powered_by_value');
542 - register_setting('http-headers-wwa', 'hh_www_authenticate');
543 - register_setting('http-headers-wwa', 'hh_www_authenticate_type');
544 - register_setting('http-headers-wwa', 'hh_www_authenticate_realm');
545 - register_setting('http-headers-wwa', 'hh_www_authenticate_user');
546 - register_setting('http-headers-wwa', 'hh_www_authenticate_pswd');
547 - register_setting('http-headers-cc', 'hh_cache_control');
548 - register_setting('http-headers-cc', 'hh_cache_control_value');
549 - register_setting('http-headers-age', 'hh_age');
550 - register_setting('http-headers-age', 'hh_age_value');
551 - register_setting('http-headers-pra', 'hh_pragma');
552 - register_setting('http-headers-pra', 'hh_pragma_value');
553 - register_setting('http-headers-exp', 'hh_expires');
554 - register_setting('http-headers-exp', 'hh_expires_value');
555 - register_setting('http-headers-exp', 'hh_expires_type');
556 - register_setting('http-headers-con', 'hh_connection');
557 - register_setting('http-headers-con', 'hh_connection_value');
558 - register_setting('http-headers-cose', 'hh_cookie_security');
559 - register_setting('http-headers-cose', 'hh_cookie_security_value');
560 - register_setting('http-headers-ect', 'hh_expect_ct');
561 - register_setting('http-headers-ect', 'hh_expect_ct_max_age');
562 - register_setting('http-headers-ect', 'hh_expect_ct_report_uri');
563 - register_setting('http-headers-ect', 'hh_expect_ct_enforce');
564 - register_setting('http-headers-tao', 'hh_timing_allow_origin');
565 - register_setting('http-headers-tao', 'hh_timing_allow_origin_value');
566 - register_setting('http-headers-tao', 'hh_timing_allow_origin_url');
567 - register_setting('http-headers-che', 'hh_custom_headers');
568 - register_setting('http-headers-che', 'hh_custom_headers_value');
569 - register_setting('http-headers-xdo', 'hh_x_download_options');
570 - register_setting('http-headers-xdo', 'hh_x_download_options_value');
571 - register_setting('http-headers-xpcd', 'hh_x_permitted_cross_domain_policies');
572 - register_setting('http-headers-xpcd', 'hh_x_permitted_cross_domain_policies_value');
573 - register_setting('http-headers-xdpc', 'hh_x_dns_prefetch_control');
574 - register_setting('http-headers-xdpc', 'hh_x_dns_prefetch_control_value');
575 - register_setting('http-headers-rt', 'hh_report_to');
576 - register_setting('http-headers-rt', 'hh_report_to_value');
577 - register_setting('http-headers-fp', 'hh_feature_policy');
578 - register_setting('http-headers-fp', 'hh_feature_policy_value');
579 - register_setting('http-headers-fp', 'hh_feature_policy_feature');
580 - register_setting('http-headers-fp', 'hh_feature_policy_origin');
581 - register_setting('http-headers-csd', 'hh_clear_site_data');
582 - register_setting('http-headers-csd', 'hh_clear_site_data_value');
178 + register_setting('http-headers-group', 'hh_x_frame_options');
179 + register_setting('http-headers-group', 'hh_x_frame_options_value');
180 + register_setting('http-headers-group', 'hh_x_frame_options_domain');
181 + register_setting('http-headers-group', 'hh_x_xxs_protection');
182 + register_setting('http-headers-group', 'hh_x_xxs_protection_value');
183 + register_setting('http-headers-group', 'hh_x_content_type_options');
184 + register_setting('http-headers-group', 'hh_x_content_type_options_value');
185 + register_setting('http-headers-group', 'hh_strict_transport_security');
186 + register_setting('http-headers-group', 'hh_strict_transport_security_value'); //obsolete
187 + register_setting('http-headers-group', 'hh_strict_transport_security_max_age');
188 + register_setting('http-headers-group', 'hh_strict_transport_security_sub_domains');
189 + register_setting('http-headers-group', 'hh_strict_transport_security_preload');
190 + register_setting('http-headers-group', 'hh_public_key_pins');
191 + register_setting('http-headers-group', 'hh_public_key_pins_sha256_1');
192 + register_setting('http-headers-group', 'hh_public_key_pins_sha256_2');
193 + register_setting('http-headers-group', 'hh_public_key_pins_max_age');
194 + register_setting('http-headers-group', 'hh_public_key_pins_sub_domains');
195 + register_setting('http-headers-group', 'hh_public_key_pins_report_uri');
196 + register_setting('http-headers-group', 'hh_x_ua_compatible');
197 + register_setting('http-headers-group', 'hh_x_ua_compatible_value');
198 + register_setting('http-headers-group', 'hh_p3p');
199 + register_setting('http-headers-group', 'hh_p3p_value');
200 + register_setting('http-headers-group', 'hh_referrer_policy');
201 + register_setting('http-headers-group', 'hh_referrer_policy_value');
202 + register_setting('http-headers-cors', 'hh_access_control_allow_origin');
203 + register_setting('http-headers-cors', 'hh_access_control_allow_origin_value');
204 + register_setting('http-headers-cors', 'hh_access_control_allow_origin_url');
205 + register_setting('http-headers-cors', 'hh_access_control_allow_credentials');
206 + register_setting('http-headers-cors', 'hh_access_control_allow_credentials_value');
207 + register_setting('http-headers-cors', 'hh_access_control_allow_methods');
208 + register_setting('http-headers-cors', 'hh_access_control_allow_methods_value');
209 + register_setting('http-headers-cors', 'hh_access_control_allow_headers');
210 + register_setting('http-headers-cors', 'hh_access_control_allow_headers_value');
211 + register_setting('http-headers-cors', 'hh_access_control_expose_headers');
212 + register_setting('http-headers-cors', 'hh_access_control_expose_headers_value');
213 + register_setting('http-headers-cors', 'hh_access_control_max_age');
214 + register_setting('http-headers-cors', 'hh_access_control_max_age_value');
583 215 }
584 -
585 -function http_headers_option($option) {
586 -
587 - include_once ABSPATH . 'wp-admin/includes/admin.php';
588 -
589 - if (isset($_POST['hh_method']))
590 - {
591 - check_admin_referer('http-headers-mtd-options');
592 - # When method is changed
593 - http_headers_activate();
594 -
595 - } elseif (get_option('hh_method') == 'htaccess') {
596 - # When particular header is changed
597 - switch (true) {
598 - case array_key_exists('hh_www_authenticate', $_POST):
599 - check_admin_referer('http-headers-wwa-options');
600 - update_auth_credentials();
601 - update_auth_directives();
602 - break;
603 - case array_key_exists('hh_content_encoding', $_POST):
604 - check_admin_referer('http-headers-ce-options');
605 - update_content_encoding_directives();
606 - break;
607 - case array_key_exists('hh_expires', $_POST):
608 - check_admin_referer('http-headers-exp-options');
609 - update_expires_directives();
610 - break;
611 - case array_key_exists('hh_cookie_security', $_POST):
612 - check_admin_referer('http-headers-cose-options');
613 - update_cookie_security_directives();
614 - break;
615 - case array_key_exists('hh_timing_allow_origin', $_POST):
616 - check_admin_referer('http-headers-tao-options');
617 - update_timing_directives();
618 - break;
619 - case array_key_exists('option_page', $_POST) && strpos($_POST['option_page'], 'http-headers-') === 0:
620 - check_admin_referer($_POST['option_page'].'-options');
621 - update_headers_directives();
622 - break;
623 - }
624 - }
625 -}
626 -
627 -function nginx_headers_directives() {
628 - $lines = array();
629 - list($headers, $statuses, $unset, $append) = get_http_headers();
630 -
631 - foreach ($unset as $header) {
632 - $lines[] = sprintf(' more_clear_headers "%s";', $header);
633 - }
634 - $cors = $cors_header = $cors_inner = $cors_footer = array();
635 - $all = array();
636 - foreach ($headers as $key => $value) {
637 - if (in_array($key, array('WWW-Authenticate'))) {
638 - continue;
639 - }
640 - if (in_array($key, array('X-Content-Type-Options'))) {
641 - $all[] = sprintf('add_header %s %s always;', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
642 - continue;
643 - }
644 - if ($key == 'Access-Control-Allow-Origin' && is_array($value)) {
645 - $cors_header[] = sprintf('if ($http_origin ~* ^(%s)$) {', str_replace('.', '\.', join('|', $value)));
646 - $cors_footer[] = '}';
647 - $cors_inner[] = ' add_header Access-Control-Allow-Origin "$http_origin";';
648 - continue;
649 - }
650 - if (in_array($key, array('Access-Control-Allow-Headers', 'Access-Control-Allow-Methods', 'Access-Control-Allow-Credentials', 'Access-Control-Max-Age', 'Access-Control-Expose-Headers'))) {
651 - $cors_inner[] = sprintf(' add_header %s %s;', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
652 - continue;
653 - }
654 - $lines[] = sprintf(' add_header %s %s;', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
655 - }
656 - foreach ($append as $key => $value) {
657 - $lines[] = sprintf(' add_header %s %s;', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
658 - }
659 - if (!empty($cors_inner))
660 - {
661 - $cors = array_merge(
662 - $cors_header,
663 - $cors_inner,
664 - $cors_footer
665 - );
666 - }
667 - if (!empty($lines)) {
668 - $lines = array_merge(
669 - $all,
670 - $cors,
671 - array('location ~* \.(php|html)$ {'),
672 - $lines,
673 - array('}')
674 - );
675 - }
676 - return $lines;
677 -}
678 216
679 -function nginx_content_encoding_directives() {
680 - $lines = array();
681 - if (get_option('hh_content_encoding') == 1) {
682 -
683 - $lines[] = 'gzip on;';
684 -
685 - $content_encoding_value = get_option('hh_content_encoding_value');
686 - if (!$content_encoding_value) {
687 - $content_encoding_value = array();
688 - }
689 -
690 - $content_encoding_ext = get_option('hh_content_encoding_ext');
691 - if (!$content_encoding_ext) {
692 - $content_encoding_ext = array();
693 - }
694 - if (!empty($content_encoding_ext)) {
695 - //$lines[] = sprintf('<FilesMatch "\.(%s)$">', join('|', array_keys($content_encoding_ext)));
696 - }
697 - if (!empty($content_encoding_value)) {
698 - $lines[] = sprintf('gzip_types %s;', join(' ', array_keys($content_encoding_value)));
699 - }
700 - }
701 - return $lines;
702 -}
703 -
704 -function nginx_expires_directives() {
705 - $lines = array();
706 - if (get_option('hh_expires') == 1) {
707 -
708 - $types = get_option('hh_expires_type', array());
709 - $values = get_option('hh_expires_value', array());
710 -
711 - $lines[] = 'map $sent_http_content_type $expires {';
712 - foreach ($types as $type => $whatever) {
713 - list($base, $period, $suffix) = explode('_', $values[$type]);
714 - if (in_array($base, array('access', 'modification'))) {
715 - $lines[] = $type != 'default'
716 - ? sprintf(' %s %u%s;', $type, $period, $suffix[0])
717 - : sprintf(' default %u%s;', $period, $suffix[0]);
718 - } elseif ($base == 'invalid') {
719 - $lines[] = $type != 'default'
720 - ? sprintf(' %s 0;', $type)
721 - : sprintf(' default 0;');
722 - }
723 - }
724 - $lines[] = '}';
725 -
726 - $lines[] = 'expires $expires;';
727 - }
728 - return $lines;
729 -}
730 -
731 -function nginx_timing_directives() {
732 - $lines = array();
733 - if (get_option('hh_timing_allow_origin') == 1) {
734 - $value = get_option('hh_timing_allow_origin_value');
735 - switch ($value)
736 - {
737 - case 'origin':
738 - $value = get_option('hh_timing_allow_origin_url');
739 - break;
740 - }
741 - if (!empty($value))
742 - {
743 - $lines[] = 'location ~* \.(js|css|jpe?g|png|gif|eot|otf|svg|ttf|woff2?)$ {';
744 - $lines[] = sprintf(' add_header Timing-Allow-Origin "%s";', $value);
745 - $lines[] = '}';
746 - }
747 - }
748 - return $lines;
749 -}
750 -
751 -function nginx_auth_directives() {
752 - $lines = array();
753 - if (get_option('hh_www_authenticate') == 1) {
754 -
755 - $type = get_option('hh_www_authenticate_type');
756 -
757 - $file = $type == 'Basic' ? '.hh-htpasswd' : '.hh-htdigest';
758 -
759 - $lines[] = 'location ~ ^\.hh-ht(digest|passwd)$ {';
760 - $lines[] = ' deny all;';
761 - $lines[] = '}';
762 -
763 - $lines[] = sprintf('location %s {', get_home_path());
764 - if ($type == 'Basic') {
765 - $lines[] = sprintf(' auth_basic "%s";', get_option('hh_www_authenticate_realm'));
766 - $lines[] = sprintf(' auth_basic_user_file %s%s;', get_home_path(), $file);
767 - } else {
768 - $lines[] = sprintf(' auth_digest "%s";', get_option('hh_www_authenticate_realm'));
769 - $lines[] = sprintf(' auth_digest_user_file %s%s;', get_home_path(), $file);
770 - }
771 - $lines[] = '}';
772 - }
773 - return $lines;
774 -}
775 -
776 -function nginx_auth_credentials() {
777 - return apache_auth_credentials();
778 -}
779 -
780 -function nginx_cookie_security_directives() {
781 - $lines = array();
782 -
783 - //TODO
784 -
785 - return $lines;
786 -}
787 -
788 -function nginx_check_requirements() {
789 - //TODO scheduled for v2.0.0
790 - return true;
791 -}
792 -
793 -function iis_headers_directives() {
794 - //TODO scheduled for v2.0.0
795 -}
796 -
797 -function iis_content_encoding_directives() {
798 - //TODO scheduled for v2.0.0
799 -}
800 -
801 -function iis_expires_directives() {
802 - //TODO scheduled for v2.0.0
803 -}
804 -
805 -function iis_timing_directives() {
806 - //TODO scheduled for v2.0.0
807 -}
808 -
809 -function iis_auth_directives() {
810 - //TODO scheduled for v2.0.0
811 -}
812 -
813 -function iis_auth_credentials() {
814 - //TODO scheduled for v2.0.0
815 -}
816 -
817 -function iis_cookie_security_directives() {
818 - //TODO scheduled for v2.0.0
819 -}
820 -
821 -function iis_check_requirements() {
822 - //TODO scheduled for v2.0.0
823 - return true;
824 -}
825 -
826 -function apache_headers_directives() {
827 - $lines = array();
828 - list($headers, $statuses, $unset, $append) = get_http_headers();
829 -
830 - foreach ($unset as $header) {
831 - $lines[] = sprintf(' Header unset %s', $header);
832 - }
833 - $all = array();
834 - foreach ($headers as $key => $value) {
835 - if (in_array($key, array('WWW-Authenticate'))) {
836 - continue;
837 - }
838 - if (in_array($key, array('X-Content-Type-Options'))) {
839 - $all[] = sprintf(' Header always set %s %s', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
840 - continue;
841 - }
842 - if ($key == 'Strict-Transport-Security') {
843 - $lines[] = sprintf(' Header set %s %s env=HTTPS', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
844 - continue;
845 - }
846 - if ($key == 'Access-Control-Allow-Origin') {
847 - $all[] = ' <IfModule mod_setenvif.c>';
848 - if (!is_array($value)) {
849 - if ($value) {
850 - $value = array($value);
851 - } else {
852 - $value = array();
853 - }
854 - }
855 - $value[] = 'null';
856 - if (is_array($value))
857 - {
858 - $all[] = sprintf(' SetEnvIf Origin "^(%s)$" CORS=$0', str_replace('.', '\.', join('|', $value)));
859 - } else {
860 - $all[] = ' SetEnvIf Origin "^(.+)$" CORS=$0';
861 - }
862 - $all[] = ' </IfModule>';
863 - $all[] = ' Header set Access-Control-Allow-Origin %{CORS}e env=CORS';
864 - continue;
865 - }
866 - if (in_array($key, array('Access-Control-Allow-Headers', 'Access-Control-Allow-Methods', 'Access-Control-Allow-Credentials', 'Access-Control-Max-Age', 'Access-Control-Expose-Headers'))) {
867 - $all[] = sprintf(' Header set %s %s env=CORS', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
868 - continue;
869 - }
870 - $lines[] = sprintf(' Header set %s %s', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
871 - }
872 - foreach ($append as $key => $value) {
873 - $lines[] = sprintf(' Header append %s %s', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
874 - }
875 - if (!empty($lines)) {
876 - $lines = array_merge(
877 - array('<IfModule mod_headers.c>'),
878 - $all,
879 - array(' <FilesMatch "\.(php|html)$">'),
880 - $lines,
881 - array(' </FilesMatch>', '</IfModule>')
882 - );
883 - }
884 - return $lines;
885 -}
886 -
887 -function apache_content_encoding_directives() {
888 - $lines = array();
889 - if (get_option('hh_content_encoding') == 1) {
890 -
891 - $content_encoding_module = get_option('hh_content_encoding_module');
892 - switch ($content_encoding_module) {
893 - case 'brotli':
894 - $module = 'mod_brotli.c';
895 - $module_end = '';
896 - $filter = 'BROTLI_COMPRESS';
897 - break;
898 - case 'brotli_deflate':
899 - $module = "mod_brotli.c>\n<IfModule mod_deflate.c";
900 - $module_end = "\n</IfModule>";
901 - $filter = 'BROTLI_COMPRESS;DEFLATE';
902 - break;
903 - case 'deflate':
904 - default:
905 - $module = 'mod_deflate.c';
906 - $module_end = '';
907 - $filter = 'DEFLATE';
908 - break;
909 - }
910 -
911 - $content_encoding_value = get_option('hh_content_encoding_value');
912 - if (!$content_encoding_value) {
913 - $content_encoding_value = array();
914 - }
915 -
916 - $content_encoding_ext = get_option('hh_content_encoding_ext');
917 - if (!$content_encoding_ext) {
918 - $content_encoding_ext = array();
919 - }
920 - if (!empty($content_encoding_ext)) {
921 - $lines[] = sprintf('<FilesMatch "\.(%s)$">', join('|', array_keys($content_encoding_ext)));
922 - $lines[] = sprintf(' <IfModule %s>', $module);
923 - $lines[] = sprintf(' SetOutputFilter %s', $filter);
924 - $lines[] = sprintf(' </IfModule>%s', $module_end);
925 - $lines[] = '</FilesMatch>';
926 - }
927 - if (!empty($content_encoding_value)) {
928 - if (!empty($lines)) {
929 - $lines[] = '';
930 - }
931 - $lines[] = sprintf('<IfModule %s>', $module);
932 - foreach (array_keys($content_encoding_value) as $item) {
933 - $lines[] = sprintf(' AddOutputFilterByType %s %s', $filter, $item);
934 - }
935 - $lines[] = sprintf('</IfModule>%s', $module_end);
936 - }
937 - }
938 -
939 - return $lines;
940 -}
941 -
942 -function apache_expires_directives() {
943 - $lines = array();
944 - if (get_option('hh_expires') == 1) {
945 -
946 - $types = get_option('hh_expires_type', array());
947 - $values = get_option('hh_expires_value', array());
948 -
949 - $lines[] = '<IfModule mod_expires.c>';
950 - $lines[] = ' ExpiresActive On';
951 - foreach ($types as $type => $whatever) {
952 - list($base, $period, $suffix) = explode('_', $values[$type]);
953 - if (in_array($base, array('access', 'modification'))) {
954 - $lines[] = $type != 'default'
955 - ? sprintf(' ExpiresByType %s "%s plus %u %s"', $type, $base, $period, $suffix)
956 - : sprintf(' ExpiresDefault "%s plus %u %s"', $base, $period, $suffix);
957 - } elseif ($base == 'invalid') {
958 - $lines[] = $type != 'default'
959 - ? sprintf(' ExpiresByType %s A0', $type)
960 - : sprintf(' ExpiresDefault A0');
961 - }
962 - }
963 - $lines[] = '</IfModule>';
964 - }
965 -
966 - return $lines;
967 -}
968 -
969 -function apache_timing_directives() {
970 - $lines = array();
971 - if (get_option('hh_timing_allow_origin') == 1) {
972 - $value = get_option('hh_timing_allow_origin_value');
973 - switch ($value)
974 - {
975 - case 'origin':
976 - $value = get_option('hh_timing_allow_origin_url');
977 - break;
978 - }
979 - if (!empty($value))
980 - {
981 - $lines[] = '<IfModule mod_headers.c>';
982 - $lines[] = ' <FilesMatch "\\.(js|css|jpe?g|png|gif|eot|otf|svg|ttf|woff2?)$">';
983 - $lines[] = sprintf(' Header set Timing-Allow-Origin "%s"', $value);
984 - $lines[] = ' </FilesMatch>';
985 - $lines[] = '</IfModule>';
986 - }
987 - }
988 -
989 - return $lines;
990 -}
991 -
992 -function apache_auth_directives() {
993 - $lines = array();
994 - if (get_option('hh_www_authenticate') == 1) {
995 -
996 - $type = get_option('hh_www_authenticate_type');
997 -
998 - $file = $type == 'Basic' ? '.hh-htpasswd' : '.hh-htdigest';
999 -
1000 - $lines[] = '<FilesMatch "^\.hh-ht(digest|passwd)$">';
1001 - $lines[] = ' <IfModule mod_authz_core.c>';
1002 - $lines[] = ' Require all denied';
1003 - $lines[] = ' </IfModule>';
1004 - $lines[] = ' <IfModule !mod_authz_core.c>';
1005 - $lines[] = ' Order deny,allow';
1006 - $lines[] = ' Deny from all';
1007 - $lines[] = ' </IfModule>';
1008 - $lines[] = '</FilesMatch>';
1009 - // no empty AuthName
1010 - $realm = get_option('hh_www_authenticate_realm'); // AuthName
1011 - $realm = ($realm == '') ? 'restricted area':$realm; // Empty => give fixed value
1012 -
1013 - $lines[] = sprintf('<IfModule mod_auth_%s.c>', strtolower($type));
1014 - $lines[] = sprintf(' AuthType %s', get_option('hh_www_authenticate_type'));
1015 - $lines[] = sprintf(' AuthName "%s"', $realm);
1016 - $lines[] = sprintf(' AuthUserFile "%s%s"', get_home_path(), $file);
1017 - $lines[] = ' Require valid-user';
1018 - $lines[] = '</IfModule>';
1019 - }
1020 -
1021 - return $lines;
1022 -}
1023 -
1024 -function apache_auth_credentials() {
1025 - if (get_option('hh_www_authenticate') == 1) {
1026 - $type = get_option('hh_www_authenticate_type');
1027 - $usernames = get_option('hh_www_authenticate_user', array());
1028 - $passwords = get_option('hh_www_authenticate_pswd', array());
1029 - if (!is_array($usernames)) {
1030 - $usernames = array($usernames);
1031 - }
1032 - if (!is_array($passwords)) {
1033 - $passwords = array($passwords);
1034 - }
1035 - $realm = get_option('hh_www_authenticate_realm');
1036 - $auth = array();
1037 - switch ($type) {
1038 - case 'Basic':
1039 - $ht_file = get_home_path().'.hh-htpasswd';
1040 - foreach ($usernames as $k => $user) {
1041 - $auth[] = sprintf('%s:{SHA}%s', $user, base64_encode(sha1($passwords[$k], true)));
1042 - }
1043 - break;
1044 - case 'Digest':
1045 - $ht_file = get_home_path().'.hh-htdigest';
1046 - foreach ($usernames as $k => $user) {
1047 - $auth[] = sprintf('%s:%s:%s', $user, $realm, md5($user.':'.$realm.':'.$passwords[$k]));
1048 - }
1049 - break;
1050 - }
1051 - $auth = join("\n", $auth);
1052 -
1053 - return compact('ht_file', 'auth');
1054 - }
1055 - return false;
1056 -}
1057 -
1058 -function apache_cookie_security_directives() {
1059 - $lines = array();
1060 - if (get_option('hh_cookie_security') == 1) {
1061 - $value = get_option('hh_cookie_security_value', array());
1062 - if (isset($value['HttpOnly'])) {
1063 - $lines[] = 'php_flag session.cookie_httponly on';
1064 - }
1065 - if (isset($value['Secure'])) {
1066 - $lines[] = 'php_flag session.cookie_secure on';
1067 - }
1068 - if (isset($value['SameSite']) && in_array($value['SameSite'], array('None', 'Lax', 'Strict'))) {
1069 - $lines[] = sprintf('php_value session.cookie_samesite "%s"', $value['SameSite']);
1070 - }
1071 - }
1072 -
1073 - return $lines;
1074 -}
1075 -
1076 -function apache_check_requirements() {
1077 - return check_filename(get_home_path().'.htaccess');
1078 -}
1079 -
1080 -function update_headers_directives() {
1081 - $lines = array();
1082 - if (get_option('hh_method') == 'htaccess') {
1083 - $lines = apache_headers_directives();
1084 - }
1085 -
1086 - return insert_with_markers(get_home_path().'.htaccess', "HttpHeaders", $lines);
1087 -}
1088 -
1089 -function update_content_encoding_directives() {
1090 - $lines = array();
1091 - if (get_option('hh_method') == 'htaccess') {
1092 - $lines = apache_content_encoding_directives();
1093 - }
1094 -
1095 - return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersCompression", $lines);
1096 -}
1097 -
1098 -function update_expires_directives() {
1099 - $lines = array();
1100 - if (get_option('hh_method') == 'htaccess') {
1101 - $lines = apache_expires_directives();
1102 - }
1103 -
1104 - return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersExpires", $lines);
1105 -}
1106 -
1107 -function update_timing_directives() {
1108 - $lines = array();
1109 - if (get_option('hh_method') == 'htaccess') {
1110 - $lines = apache_timing_directives();
1111 - }
1112 -
1113 - return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersTiming", $lines);
1114 -}
1115 -
1116 -function update_auth_directives() {
1117 - $lines = array();
1118 - if (get_option('hh_method') == 'htaccess') {
1119 - $lines = apache_auth_directives();
1120 - }
1121 -
1122 - return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersAuth", $lines);
1123 - }
1124 -
1125 -function update_auth_credentials() {
1126 - if (get_option('hh_method') == 'htaccess') {
1127 - $credentials = apache_auth_credentials();
1128 -
1129 - return @file_put_contents($credentials['ht_file'], $credentials['auth']);
1130 - }
1131 -
1132 - return false;
1133 -}
1134 -
1135 -function update_cookie_security_directives() {
1136 - $lines = array();
1137 - $is_apache = get_option('hh_method') == 'htaccess';
1138 - $htaccess = get_home_path().'.htaccess';
1139 - if (strpos(PHP_SAPI, 'cgi') !== false) {
1140 - $filename = get_home_path().ini_get('user_ini.filename');
1141 - $lines = php_cookie_security_directives();
1142 - } elseif ($is_apache) {
1143 - $filename = $htaccess;
1144 - $lines = apache_cookie_security_directives();
1145 - }
1146 -
1147 - if (!$is_apache) {
1148 - insert_with_markers($htaccess, "HttpHeadersCookieSecurity", array());
1149 - }
1150 -
1151 - return insert_with_markers($filename, "HttpHeadersCookieSecurity", $lines);
1152 -}
1153 -
1154 -function is_samesite_supported() {
1155 - return version_compare(PHP_VERSION, '7.3.0', '>=');
1156 -}
1157 -
1158 -function http_headers_text_domain() {
1159 - load_plugin_textdomain('http-headers', false, basename( dirname( __FILE__ ) ) . '/languages/');
1160 -}
1161 -
1162 -function http_headers_settings_link( $links ) {
1163 - $url = get_admin_url() . 'options-general.php?page=http-headers';
1164 - $settings_link = '<a href="' . $url . '">' . __('Settings', 'http-headers') . '</a>';
1165 - array_unshift( $links, $settings_link );
1166 - return $links;
1167 -}
1168 -
1169 -function http_headers_after_setup_theme() {
1170 - add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'http_headers_settings_link');
1171 -}
1172 -
1173 217 function http_headers_enqueue($hook) {
1174 218 if ( 'http-headers.php' != $hook ) {
1175 219 # FIXME
1176 220 //return;
@@ -1175,187 +219,17 @@
1175 219 # FIXME
1176 220 //return;
1177 221 }
1178 222
1179 - wp_enqueue_script('http_headers_admin_scripts', plugin_dir_url( __FILE__ ) . 'assets/scripts.js', array(), '1.13.0', true);
1180 - wp_localize_script('http_headers_admin_scripts', 'hh', array(
1181 - 'lbl_delete' => __('Delete', 'http-headers'),
1182 - 'lbl_value' => __('Value', 'http-headers'),
1183 - ));
223 + wp_enqueue_script('http_headers_admin_scripts', plugin_dir_url( __FILE__ ) . 'assets/scripts.js');
1184 224 wp_enqueue_style('http_headers_admin_styles', plugin_dir_url( __FILE__ ) . 'assets/styles.css');
1185 225 }
1186 226
1187 -function http_headers_ajax_inspect() {
1188 - check_ajax_referer('inspect');
1189 - if (current_user_can('manage_options')) {
1190 - include 'views/ajax-inspect.php';
1191 - }
1192 - wp_die();
1193 -}
1194 227
1195 -function http_headers_post_import() {
1196 - check_admin_referer('import');
1197 - global $wpdb;
1198 - if (!(isset($_FILES['file']['tmp_name'])
1199 - && is_uploaded_file($_FILES['file']['tmp_name'])
1200 - && $_FILES['file']['error'] == UPLOAD_ERR_OK
1201 - )) {
1202 - wp_redirect(sprintf("%soptions-general.php?page=http-headers&tab=advanced&status=ERR&code=100", get_admin_url()));
1203 - exit;
1204 - }
1205 -
1206 - $string = @file_get_contents($_FILES['file']['tmp_name']);
1207 - if ($string === false) {
1208 - wp_redirect(sprintf("%soptions-general.php?page=http-headers&tab=advanced&status=ERR&code=101", get_admin_url()));
1209 - exit;
1210 - }
1211 -
1212 - $arr = preg_split('/;(\s+)?\n/', $string);
1213 - foreach ($arr as $statement) {
1214 - $wpdb->query($statement);
1215 - }
1216 -
1217 - wp_redirect(sprintf("%soptions-general.php?page=http-headers&tab=advanced&status=OK", get_admin_url()));
1218 - exit;
1219 -}
1220 -
1221 -function http_headers_post_export() {
1222 - check_admin_referer('export');
1223 - global $wpdb;
1224 - $options = include dirname(__FILE__) . '/views/includes/options.inc.php';
1225 - $opts = array();
1226 - foreach ($options as $option)
1227 - {
1228 - $opts[] = $option[0];
1229 - }
1230 - $statement = sprintf("SELECT * FROM %s WHERE option_name IN ('%s');", $wpdb->options, join("','", $opts));
1231 - $results = $wpdb->get_results($statement, ARRAY_A);
1232 - $sql = array();
1233 -
1234 - $indexes = array();
1235 - foreach ($options as $option)
1236 - {
1237 - foreach ($results as $item)
1238 - {
1239 - if ($item['option_name'] == $option[0])
1240 - {
1241 - $indexes[$option[0]] = 1;
1242 -
1243 - $value = str_replace("'", "''", $item['option_value']);
1244 - $query = array();
1245 - $query[] = sprintf("INSERT INTO %s (option_id, option_name, option_value, autoload)", $wpdb->options);
1246 - $query[] = sprintf("VALUES (NULL, '%s', '%s', '%s')", $item['option_name'], $value, $item['autoload']);
1247 - $query[] = sprintf("ON DUPLICATE KEY UPDATE option_value = '%s', autoload = '%s';", $value, $item['autoload']);
1248 - $sql[] = join("\n", $query);
1249 - break;
1250 - }
1251 - }
1252 -
1253 - if (!isset($indexes[$option[0]]))
1254 - {
1255 - $query = array();
1256 - $query[] = sprintf("INSERT INTO %s (option_id, option_name, option_value, autoload)", $wpdb->options);
1257 - $query[] = sprintf("VALUES (NULL, '%s', '%s', 'yes')", $option[0], $option[1]);
1258 - $query[] = sprintf("ON DUPLICATE KEY UPDATE option_value = '%s', autoload = 'yes';", $option[1]);
1259 - $sql[] = join("\n", $query);
1260 - }
1261 - }
1262 -
1263 - $sql = join("\n\n", $sql);
1264 - $length = function_exists('mb_strlen') ? mb_strlen($sql) : strlen($sql);
1265 - $name = sprintf('WP-HTTP-Headers-%u.sql', time());
1266 -
1267 - # Send headers
1268 - header('Pragma: public');
1269 - header('Expires: 0');
1270 - header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
1271 - header('Cache-Control: private', false);
1272 - header('Content-Transfer-Encoding: binary');
1273 - header('Content-Disposition: attachment; filename="'.$name.'";');
1274 - header('Content-Type: application/sql');
1275 - header('Content-Length: ' . $length);
1276 -
1277 - echo $sql;
1278 - exit;
1279 -}
1280 -
1281 -function check_filename($filename) {
1282 - if (!is_file($filename)) {
1283 - return -1;
1284 - }
1285 -
1286 - clearstatcache();
1287 - if (!is_writable($filename)) {
1288 - return -2;
1289 - }
1290 -
1291 - return true;
1292 -}
1293 -
1294 -function check_webserver_requirements() {
1295 - $method = get_option('hh_method');
1296 - if ($method == 'htaccess') {
1297 - return apache_check_requirements();
1298 - }
1299 -
1300 - return true;
1301 -}
1302 -
1303 -function check_php_requirements() {
1304 - if (strpos(PHP_SAPI, 'cgi') !== false) {
1305 - // cgi, cgi-fcgi, fpm-fcgi
1306 - return check_filename(get_home_path().ini_get('user_ini.filename'));
1307 - }
1308 -
1309 - return true;
1310 -}
1311 -
1312 -function http_headers_logout() {
1313 - if (get_option('hh_clear_site_data') == 1) {
1314 - $values = get_option('hh_clear_site_data_value', array());
1315 - $tmp = array_keys($values);
1316 - if ($tmp) {
1317 - header(sprintf('Clear-Site-Data: "%s"', join('", "', $tmp)));
1318 - }
1319 - }
1320 -}
1321 -
1322 -function http_headers_activate() {
1323 - update_headers_directives();
1324 - update_auth_credentials();
1325 - update_auth_directives();
1326 - update_content_encoding_directives();
1327 - update_expires_directives();
1328 - update_cookie_security_directives();
1329 - update_timing_directives();
1330 -}
1331 -
1332 -function http_headers_deactivate() {
1333 - $filename = get_home_path().'.htaccess';
1334 -
1335 - insert_with_markers($filename, "HttpHeaders", array());
1336 - insert_with_markers($filename, "HttpHeadersCompression", array());
1337 - insert_with_markers($filename, "HttpHeadersExpires", array());
1338 - insert_with_markers($filename, "HttpHeadersTiming", array());
1339 - insert_with_markers($filename, "HttpHeadersAuth", array());
1340 - insert_with_markers($filename, "HttpHeadersCookieSecurity", array());
1341 -}
1342 -
1343 -register_activation_hook(__FILE__, 'http_headers_activate');
1344 -register_deactivation_hook(__FILE__, 'http_headers_deactivate');
1345 -add_action('wp_logout', 'http_headers_logout');
1346 -
1347 228 if ( is_admin() ){ // admin actions
1348 229 add_action('admin_menu', 'http_headers_admin_add_page');
1349 230 add_action('admin_init', 'http_headers_admin');
1350 - add_action("added_option", 'http_headers_option');
1351 - add_action("updated_option", 'http_headers_option');
1352 231 add_action('admin_enqueue_scripts', 'http_headers_enqueue');
1353 - add_action('after_setup_theme', 'http_headers_after_setup_theme');
1354 - add_action('plugins_loaded', 'http_headers_text_domain');
1355 - add_action('wp_ajax_inspect', 'http_headers_ajax_inspect');
1356 - add_action('admin_post_import', 'http_headers_post_import');
1357 - add_action('admin_post_export', 'http_headers_post_export');
1358 232 } else {
1359 233 // non-admin enqueues, actions, and filters
1360 234 add_action('send_headers', 'http_headers');
1361 235 }
@@ -1360,6 +234,6 @@
1360 234 add_action('send_headers', 'http_headers');
1361 235 }
1362 236
1363 237 function http_headers_admin_page() {
1364 - include 'views/index.php';
238 + include 'views/admin.php';
1365 239 }