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 -1192 1.13.2 → 1.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.2
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,912 +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[] = ' Order deny,allow';
1002 - $lines[] = ' Deny from all';
1003 - $lines[] = '</FilesMatch>';
1004 -
1005 - $lines[] = sprintf('<IfModule mod_auth_%s.c>', strtolower($type));
1006 - $lines[] = sprintf(' AuthType %s', get_option('hh_www_authenticate_type'));
1007 - $lines[] = sprintf(' AuthName "%s"', get_option('hh_www_authenticate_realm'));
1008 - $lines[] = sprintf(' AuthUserFile "%s%s"', get_home_path(), $file);
1009 - $lines[] = ' Require valid-user';
1010 - $lines[] = '</IfModule>';
1011 - }
1012 -
1013 - return $lines;
1014 -}
1015 -
1016 -function apache_auth_credentials() {
1017 - if (get_option('hh_www_authenticate') == 1) {
1018 - $type = get_option('hh_www_authenticate_type');
1019 - $usernames = get_option('hh_www_authenticate_user', array());
1020 - $passwords = get_option('hh_www_authenticate_pswd', array());
1021 - if (!is_array($usernames)) {
1022 - $usernames = array($usernames);
1023 - }
1024 - if (!is_array($passwords)) {
1025 - $passwords = array($passwords);
1026 - }
1027 - $realm = get_option('hh_www_authenticate_realm');
1028 - $auth = array();
1029 - switch ($type) {
1030 - case 'Basic':
1031 - $ht_file = get_home_path().'.hh-htpasswd';
1032 - foreach ($usernames as $k => $user) {
1033 - $auth[] = sprintf('%s:{SHA}%s', $user, base64_encode(sha1($passwords[$k], true)));
1034 - }
1035 - break;
1036 - case 'Digest':
1037 - $ht_file = get_home_path().'.hh-htdigest';
1038 - foreach ($usernames as $k => $user) {
1039 - $auth[] = sprintf('%s:%s:%s', $user, $realm, md5($user.':'.$realm.':'.$passwords[$k]));
1040 - }
1041 - break;
1042 - }
1043 - $auth = join("\n", $auth);
1044 -
1045 - return compact('ht_file', 'auth');
1046 - }
1047 - return false;
1048 -}
1049 -
1050 -function apache_cookie_security_directives() {
1051 - $lines = array();
1052 - if (get_option('hh_cookie_security') == 1) {
1053 - $value = get_option('hh_cookie_security_value', array());
1054 - if (isset($value['HttpOnly'])) {
1055 - $lines[] = 'php_flag session.cookie_httponly on';
1056 - }
1057 - if (isset($value['Secure'])) {
1058 - $lines[] = 'php_flag session.cookie_secure on';
1059 - }
1060 - if (isset($value['SameSite']) && in_array($value['SameSite'], array('None', 'Lax', 'Strict'))) {
1061 - $lines[] = sprintf('php_value session.cookie_samesite "%s"', $value['SameSite']);
1062 - }
1063 - }
1064 -
1065 - return $lines;
1066 -}
1067 -
1068 -function apache_check_requirements() {
1069 - return check_filename(get_home_path().'.htaccess');
1070 -}
1071 -
1072 -function update_headers_directives() {
1073 - $lines = array();
1074 - if (get_option('hh_method') == 'htaccess') {
1075 - $lines = apache_headers_directives();
1076 - }
1077 -
1078 - return insert_with_markers(get_home_path().'.htaccess', "HttpHeaders", $lines);
1079 -}
1080 -
1081 -function update_content_encoding_directives() {
1082 - $lines = array();
1083 - if (get_option('hh_method') == 'htaccess') {
1084 - $lines = apache_content_encoding_directives();
1085 - }
1086 -
1087 - return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersCompression", $lines);
1088 -}
1089 -
1090 -function update_expires_directives() {
1091 - $lines = array();
1092 - if (get_option('hh_method') == 'htaccess') {
1093 - $lines = apache_expires_directives();
1094 - }
1095 -
1096 - return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersExpires", $lines);
1097 -}
1098 -
1099 -function update_timing_directives() {
1100 - $lines = array();
1101 - if (get_option('hh_method') == 'htaccess') {
1102 - $lines = apache_timing_directives();
1103 - }
1104 -
1105 - return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersTiming", $lines);
1106 -}
1107 -
1108 -function update_auth_directives() {
1109 - $lines = array();
1110 - if (get_option('hh_method') == 'htaccess') {
1111 - $lines = apache_auth_directives();
1112 - }
1113 -
1114 - return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersAuth", $lines);
1115 - }
1116 -
1117 -function update_auth_credentials() {
1118 - if (get_option('hh_method') == 'htaccess') {
1119 - $credentials = apache_auth_credentials();
1120 -
1121 - return @file_put_contents($credentials['ht_file'], $credentials['auth']);
1122 - }
1123 -
1124 - return false;
1125 -}
1126 -
1127 -function update_cookie_security_directives() {
1128 - $lines = array();
1129 - $is_apache = get_option('hh_method') == 'htaccess';
1130 - $htaccess = get_home_path().'.htaccess';
1131 - if (strpos(PHP_SAPI, 'cgi') !== false) {
1132 - $filename = get_home_path().ini_get('user_ini.filename');
1133 - $lines = php_cookie_security_directives();
1134 - } elseif ($is_apache) {
1135 - $filename = $htaccess;
1136 - $lines = apache_cookie_security_directives();
1137 - }
1138 -
1139 - if (!$is_apache) {
1140 - insert_with_markers($htaccess, "HttpHeadersCookieSecurity", array());
1141 - }
1142 -
1143 - return insert_with_markers($filename, "HttpHeadersCookieSecurity", $lines);
1144 -}
1145 -
1146 -function is_samesite_supported() {
1147 - return version_compare(PHP_VERSION, '7.3.0', '>=');
1148 -}
1149 -
1150 -function http_headers_text_domain() {
1151 - load_plugin_textdomain('http-headers', false, basename( dirname( __FILE__ ) ) . '/languages/');
1152 -}
1153 -
1154 -function http_headers_settings_link( $links ) {
1155 - $url = get_admin_url() . 'options-general.php?page=http-headers';
1156 - $settings_link = '<a href="' . $url . '">' . __('Settings', 'http-headers') . '</a>';
1157 - array_unshift( $links, $settings_link );
1158 - return $links;
1159 -}
1160 -
1161 -function http_headers_after_setup_theme() {
1162 - add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'http_headers_settings_link');
1163 -}
1164 -
1165 217 function http_headers_enqueue($hook) {
1166 218 if ( 'http-headers.php' != $hook ) {
1167 219 # FIXME
1168 220 //return;
@@ -1167,187 +219,17 @@
1167 219 # FIXME
1168 220 //return;
1169 221 }
1170 222
1171 - wp_enqueue_script('http_headers_admin_scripts', plugin_dir_url( __FILE__ ) . 'assets/scripts.js', array(), '1.13.0', true);
1172 - wp_localize_script('http_headers_admin_scripts', 'hh', array(
1173 - 'lbl_delete' => __('Delete', 'http-headers'),
1174 - 'lbl_value' => __('Value', 'http-headers'),
1175 - ));
223 + wp_enqueue_script('http_headers_admin_scripts', plugin_dir_url( __FILE__ ) . 'assets/scripts.js');
1176 224 wp_enqueue_style('http_headers_admin_styles', plugin_dir_url( __FILE__ ) . 'assets/styles.css');
1177 225 }
1178 226
1179 -function http_headers_ajax_inspect() {
1180 - check_ajax_referer('inspect');
1181 - if (current_user_can('manage_options')) {
1182 - include 'views/ajax-inspect.php';
1183 - }
1184 - wp_die();
1185 -}
1186 227
1187 -function http_headers_post_import() {
1188 - check_admin_referer('import');
1189 - global $wpdb;
1190 - if (!(isset($_FILES['file']['tmp_name'])
1191 - && is_uploaded_file($_FILES['file']['tmp_name'])
1192 - && $_FILES['file']['error'] == UPLOAD_ERR_OK
1193 - )) {
1194 - wp_redirect(sprintf("%soptions-general.php?page=http-headers&tab=advanced&status=ERR&code=100", get_admin_url()));
1195 - exit;
1196 - }
1197 -
1198 - $string = @file_get_contents($_FILES['file']['tmp_name']);
1199 - if ($string === false) {
1200 - wp_redirect(sprintf("%soptions-general.php?page=http-headers&tab=advanced&status=ERR&code=101", get_admin_url()));
1201 - exit;
1202 - }
1203 -
1204 - $arr = preg_split('/;(\s+)?\n/', $string);
1205 - foreach ($arr as $statement) {
1206 - $wpdb->query($statement);
1207 - }
1208 -
1209 - wp_redirect(sprintf("%soptions-general.php?page=http-headers&tab=advanced&status=OK", get_admin_url()));
1210 - exit;
1211 -}
1212 -
1213 -function http_headers_post_export() {
1214 - check_admin_referer('export');
1215 - global $wpdb;
1216 - $options = include dirname(__FILE__) . '/views/includes/options.inc.php';
1217 - $opts = array();
1218 - foreach ($options as $option)
1219 - {
1220 - $opts[] = $option[0];
1221 - }
1222 - $statement = sprintf("SELECT * FROM %s WHERE option_name IN ('%s');", $wpdb->options, join("','", $opts));
1223 - $results = $wpdb->get_results($statement, ARRAY_A);
1224 - $sql = array();
1225 -
1226 - $indexes = array();
1227 - foreach ($options as $option)
1228 - {
1229 - foreach ($results as $item)
1230 - {
1231 - if ($item['option_name'] == $option[0])
1232 - {
1233 - $indexes[$option[0]] = 1;
1234 -
1235 - $value = str_replace("'", "''", $item['option_value']);
1236 - $query = array();
1237 - $query[] = sprintf("INSERT INTO %s (option_id, option_name, option_value, autoload)", $wpdb->options);
1238 - $query[] = sprintf("VALUES (NULL, '%s', '%s', '%s')", $item['option_name'], $value, $item['autoload']);
1239 - $query[] = sprintf("ON DUPLICATE KEY UPDATE option_value = '%s', autoload = '%s';", $value, $item['autoload']);
1240 - $sql[] = join("\n", $query);
1241 - break;
1242 - }
1243 - }
1244 -
1245 - if (!isset($indexes[$option[0]]))
1246 - {
1247 - $query = array();
1248 - $query[] = sprintf("INSERT INTO %s (option_id, option_name, option_value, autoload)", $wpdb->options);
1249 - $query[] = sprintf("VALUES (NULL, '%s', '%s', 'yes')", $option[0], $option[1]);
1250 - $query[] = sprintf("ON DUPLICATE KEY UPDATE option_value = '%s', autoload = 'yes';", $option[1]);
1251 - $sql[] = join("\n", $query);
1252 - }
1253 - }
1254 -
1255 - $sql = join("\n\n", $sql);
1256 - $length = function_exists('mb_strlen') ? mb_strlen($sql) : strlen($sql);
1257 - $name = sprintf('WP-HTTP-Headers-%u.sql', time());
1258 -
1259 - # Send headers
1260 - header('Pragma: public');
1261 - header('Expires: 0');
1262 - header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
1263 - header('Cache-Control: private', false);
1264 - header('Content-Transfer-Encoding: binary');
1265 - header('Content-Disposition: attachment; filename="'.$name.'";');
1266 - header('Content-Type: application/sql');
1267 - header('Content-Length: ' . $length);
1268 -
1269 - echo $sql;
1270 - exit;
1271 -}
1272 -
1273 -function check_filename($filename) {
1274 - if (!is_file($filename)) {
1275 - return -1;
1276 - }
1277 -
1278 - clearstatcache();
1279 - if (!is_writable($filename)) {
1280 - return -2;
1281 - }
1282 -
1283 - return true;
1284 -}
1285 -
1286 -function check_webserver_requirements() {
1287 - $method = get_option('hh_method');
1288 - if ($method == 'htaccess') {
1289 - return apache_check_requirements();
1290 - }
1291 -
1292 - return true;
1293 -}
1294 -
1295 -function check_php_requirements() {
1296 - if (strpos(PHP_SAPI, 'cgi') !== false) {
1297 - // cgi, cgi-fcgi, fpm-fcgi
1298 - return check_filename(get_home_path().ini_get('user_ini.filename'));
1299 - }
1300 -
1301 - return true;
1302 -}
1303 -
1304 -function http_headers_logout() {
1305 - if (get_option('hh_clear_site_data') == 1) {
1306 - $values = get_option('hh_clear_site_data_value', array());
1307 - $tmp = array_keys($values);
1308 - if ($tmp) {
1309 - header(sprintf('Clear-Site-Data: "%s"', join('", "', $tmp)));
1310 - }
1311 - }
1312 -}
1313 -
1314 -function http_headers_activate() {
1315 - update_headers_directives();
1316 - update_auth_credentials();
1317 - update_auth_directives();
1318 - update_content_encoding_directives();
1319 - update_expires_directives();
1320 - update_cookie_security_directives();
1321 - update_timing_directives();
1322 -}
1323 -
1324 -function http_headers_deactivate() {
1325 - $filename = get_home_path().'.htaccess';
1326 -
1327 - insert_with_markers($filename, "HttpHeaders", array());
1328 - insert_with_markers($filename, "HttpHeadersCompression", array());
1329 - insert_with_markers($filename, "HttpHeadersExpires", array());
1330 - insert_with_markers($filename, "HttpHeadersTiming", array());
1331 - insert_with_markers($filename, "HttpHeadersAuth", array());
1332 - insert_with_markers($filename, "HttpHeadersCookieSecurity", array());
1333 -}
1334 -
1335 -register_activation_hook(__FILE__, 'http_headers_activate');
1336 -register_deactivation_hook(__FILE__, 'http_headers_deactivate');
1337 -add_action('wp_logout', 'http_headers_logout');
1338 -
1339 228 if ( is_admin() ){ // admin actions
1340 229 add_action('admin_menu', 'http_headers_admin_add_page');
1341 230 add_action('admin_init', 'http_headers_admin');
1342 - add_action("added_option", 'http_headers_option');
1343 - add_action("updated_option", 'http_headers_option');
1344 231 add_action('admin_enqueue_scripts', 'http_headers_enqueue');
1345 - add_action('after_setup_theme', 'http_headers_after_setup_theme');
1346 - add_action('plugins_loaded', 'http_headers_text_domain');
1347 - add_action('wp_ajax_inspect', 'http_headers_ajax_inspect');
1348 - add_action('admin_post_import', 'http_headers_post_import');
1349 - add_action('admin_post_export', 'http_headers_post_export');
1350 232 } else {
1351 233 // non-admin enqueues, actions, and filters
1352 234 add_action('send_headers', 'http_headers');
1353 235 }
@@ -1352,6 +234,6 @@
1352 234 add_action('send_headers', 'http_headers');
1353 235 }
1354 236
1355 237 function http_headers_admin_page() {
1356 - include 'views/index.php';
238 + include 'views/admin.php';
1357 239 }