224 lines
6.4 KiB
PHP
224 lines
6.4 KiB
PHP
<?php
|
|
/**
|
|
* IQON Phase 1 hardening snippet.
|
|
*
|
|
* Purpose: temporary WordPress hardening for iqon.com before the redesign
|
|
* replaces or modernizes the legacy theme.
|
|
*
|
|
* Created: 2026-05-20
|
|
* Updated: 2026-05-20
|
|
* Deployment: Code Snippets plugin, "Run snippet everywhere".
|
|
*
|
|
* Safety:
|
|
* - No credentials are stored here.
|
|
* - This is reversible by disabling the snippet.
|
|
* - Physical files such as /readme.html may be served before WordPress;
|
|
* block those at the hosting/nginx layer for guaranteed enforcement.
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
return;
|
|
}
|
|
|
|
add_action('send_headers', 'iqon_phase1_send_security_headers', 100);
|
|
add_action('wp_head', 'iqon_phase1_head_fallbacks', 1);
|
|
add_filter('xmlrpc_enabled', '__return_false');
|
|
add_filter('rest_endpoints', 'iqon_phase1_restrict_rest_users', 20);
|
|
add_filter('the_generator', '__return_empty_string');
|
|
add_filter('wpseo_opengraph_site_name', 'iqon_phase1_site_name');
|
|
add_filter('wpseo_json_ld_output', 'iqon_phase1_rewrite_recursive_urls', 20);
|
|
add_filter('wpseo_opengraph_image', 'iqon_phase1_rewrite_url_string', 20);
|
|
add_action('template_redirect', 'iqon_phase1_install_doc_fallback_block', 0);
|
|
add_action('template_redirect', 'iqon_phase1_start_output_buffer', 0);
|
|
|
|
function iqon_phase1_send_security_headers()
|
|
{
|
|
if (headers_sent()) {
|
|
return;
|
|
}
|
|
|
|
header('X-Content-Type-Options: nosniff');
|
|
header('X-Frame-Options: SAMEORIGIN');
|
|
header('Referrer-Policy: strict-origin-when-cross-origin');
|
|
header('Permissions-Policy: camera=(), microphone=(), geolocation=()');
|
|
header(
|
|
"Content-Security-Policy: default-src 'self' https: data:; " .
|
|
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://ajax.googleapis.com https://maps.google.com https://maps.googleapis.com; " .
|
|
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " .
|
|
"img-src 'self' https: data:; " .
|
|
"font-src 'self' https://fonts.gstatic.com data:; " .
|
|
"frame-src https://www.google.com https://maps.google.com https://maps.googleapis.com; " .
|
|
"connect-src 'self' https:; base-uri 'self'; frame-ancestors 'self'; upgrade-insecure-requests"
|
|
);
|
|
}
|
|
|
|
function iqon_phase1_head_fallbacks()
|
|
{
|
|
echo "\n" . '<style id="iqon-phase1-emergency-css">
|
|
html { -webkit-text-size-adjust: 100%; }
|
|
body { overflow-x: hidden; }
|
|
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible {
|
|
outline: 3px solid #fbc100;
|
|
outline-offset: 3px;
|
|
}
|
|
.iqon-skip-link {
|
|
position: absolute;
|
|
left: -999px;
|
|
top: 8px;
|
|
z-index: 9999;
|
|
padding: 8px 12px;
|
|
background: #000;
|
|
color: #fff;
|
|
}
|
|
.iqon-skip-link:focus { left: 8px; }
|
|
img, iframe { max-width: 100%; }
|
|
@media (max-width: 980px) {
|
|
#wrapper, #header, #menu, #header-image-home, #header-image, #breadcrumb, .download_case_file {
|
|
width: auto !important;
|
|
max-width: 960px;
|
|
}
|
|
#wrapper { margin-left: 12px !important; margin-right: 12px !important; }
|
|
#menu { height: auto !important; min-height: 40px; background-repeat: repeat !important; }
|
|
#menu a { float: none !important; display: block !important; padding: 0 16px !important; }
|
|
.contentleft, .contentright, .homeleft, .homeright {
|
|
float: none !important;
|
|
width: auto !important;
|
|
}
|
|
.rowInput, .rowTextarea textarea, .rowInput input {
|
|
width: 100% !important;
|
|
box-sizing: border-box;
|
|
}
|
|
}
|
|
</style>' . "\n";
|
|
}
|
|
|
|
function iqon_phase1_restrict_rest_users($endpoints)
|
|
{
|
|
if (!is_array($endpoints)) {
|
|
return $endpoints;
|
|
}
|
|
|
|
foreach (array('/wp/v2/users', '/wp/v2/users/(?P<id>[\d]+)') as $route) {
|
|
if (isset($endpoints[$route])) {
|
|
unset($endpoints[$route]);
|
|
}
|
|
}
|
|
|
|
return $endpoints;
|
|
}
|
|
|
|
function iqon_phase1_install_doc_fallback_block()
|
|
{
|
|
$request_uri = isset($_SERVER['REQUEST_URI']) ? (string) $_SERVER['REQUEST_URI'] : '';
|
|
$path = parse_url($request_uri, PHP_URL_PATH);
|
|
|
|
if (!is_string($path)) {
|
|
return;
|
|
}
|
|
|
|
if (preg_match('~/(readme|license)\.html$~i', $path)) {
|
|
status_header(404);
|
|
nocache_headers();
|
|
exit;
|
|
}
|
|
}
|
|
|
|
function iqon_phase1_start_output_buffer()
|
|
{
|
|
$doing_ajax = function_exists('wp_doing_ajax') ? wp_doing_ajax() : (defined('DOING_AJAX') && DOING_AJAX);
|
|
|
|
if (is_admin() || $doing_ajax || (defined('REST_REQUEST') && REST_REQUEST)) {
|
|
return;
|
|
}
|
|
|
|
ob_start('iqon_phase1_rewrite_html');
|
|
}
|
|
|
|
function iqon_phase1_rewrite_html($html)
|
|
{
|
|
if (!is_string($html) || $html === '') {
|
|
return $html;
|
|
}
|
|
|
|
$html = iqon_phase1_rewrite_url_string($html);
|
|
|
|
if (stripos($html, 'name="viewport"') === false && stripos($html, "name='viewport'") === false) {
|
|
$html = preg_replace(
|
|
'~</head>~i',
|
|
'<meta name="viewport" content="width=device-width, initial-scale=1">' . "\n" . '</head>',
|
|
$html,
|
|
1
|
|
);
|
|
}
|
|
|
|
if (stripos($html, 'class="iqon-skip-link"') === false) {
|
|
$html = preg_replace(
|
|
'~<body([^>]*)>~i',
|
|
'<body$1><a class="iqon-skip-link" href="#content">Skip to content</a>',
|
|
$html,
|
|
1
|
|
);
|
|
}
|
|
|
|
$html = preg_replace(
|
|
'~(<img\b(?![^>]*\balt=)(?=[^>]*\b(?:homepage|header|logo|case)[^>]*)[^>]*)>~i',
|
|
'$1 alt="">',
|
|
$html
|
|
);
|
|
|
|
return $html;
|
|
}
|
|
|
|
function iqon_phase1_site_name()
|
|
{
|
|
return 'IQON';
|
|
}
|
|
|
|
function iqon_phase1_rewrite_recursive_urls($value)
|
|
{
|
|
if (is_array($value)) {
|
|
foreach ($value as $key => $item) {
|
|
$value[$key] = iqon_phase1_rewrite_recursive_urls($item);
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
if (is_object($value)) {
|
|
foreach ($value as $key => $item) {
|
|
$value->{$key} = iqon_phase1_rewrite_recursive_urls($item);
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
if (is_string($value)) {
|
|
return iqon_phase1_rewrite_url_string($value);
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
function iqon_phase1_rewrite_url_string($value)
|
|
{
|
|
if (!is_string($value) || $value === '') {
|
|
return $value;
|
|
}
|
|
|
|
return str_replace(
|
|
array(
|
|
'http://www.iqon.com',
|
|
'http://iqon.com',
|
|
'http://maps.google.com',
|
|
'http://maps.googleapis.com',
|
|
),
|
|
array(
|
|
'https://iqon.com',
|
|
'https://iqon.com',
|
|
'https://maps.google.com',
|
|
'https://maps.googleapis.com',
|
|
),
|
|
$value
|
|
);
|
|
}
|