Phase 6: AIOS security plugin with conservative login lockdown config (10 attempts)

This commit is contained in:
Hanson.xyz Dev
2025-11-28 17:19:54 -06:00
parent 78a744ef06
commit abbd3502e8
430 changed files with 137111 additions and 7 deletions
@@ -0,0 +1,156 @@
<?php
namespace AIOWPS\Firewall;
/**
* Rule that blocks certain kinds of data from the request string
*/
class Rule_Advanced_Character_Filter extends Rule {
/**
* Implements the action to be taken
*/
use Action_Forbid_and_Exit_Trait;
/**
* Construct our rule
*/
public function __construct() {
// Set the rule's metadata
$this->name = 'Advanced character filter';
$this->family = 'General';
$this->priority = 10;
}
/**
* Determines whether the rule is active
*
* @return boolean
*/
public function is_active() {
global $aiowps_firewall_config;
return (bool) $aiowps_firewall_config->get_value('aiowps_advanced_char_string_filter');
}
/**
* The condition to be satisfied for the rule to apply
*
* @return boolean
*/
public function is_satisfied() {
if (empty($_SERVER['REQUEST_URI'])) return Rule::NOT_SATISFIED;
// ensure we get the request uri without the query string
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules.
$uri = (string) parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
return Rule_Utils::contains_pattern($uri, array_merge($this->get_general_characters(), $this->get_common_patterns(), $this->get_specific_exploits()));
}
/**
* Get the list of 'specific exploits' patterns
*
* @return array
*/
private function get_specific_exploits() {
return array(
'/errors\./i',
'/config\./i',
'/include\./i',
'/display\./i',
'/register\./i',
'/password\./i',
'/maincore\./i',
'/authorize\./i',
'/macromates\./i',
'/head\_auth\./i',
'/submit\_links\./i',
'/change\_action\./i',
'/com\_facileforms\//i',
'/admin\_db\_utilities\./i',
'/admin\.webring\.docs\./i',
'/Table\/Latest\/index\./i',
);
}
/**
* Get the list of common patterns
*
* @return array
*/
private function get_common_patterns() {
return array(
'/\_vpi/i',
'/\.inc/i',
'/xAou6/i',
'/db\_name/i',
'/select\(/i',
'/convert\(/i',
'/\/query\//i',
'/ImpEvData/i',
'/\.XMLHTTP/i',
'/proxydeny/i',
'/function\./i',
'/remoteFile/i',
'/servername/i',
'/\&rptmode\=/i',
'/sys\_cpanel/i',
'/db\_connect/i',
'/doeditconfig/i',
'/check\_proxy/i',
'/system\_user/i',
'/\/\(null\)\//i',
'/clientrequest/i',
'/option\_value/i',
'/ref\.outcontrol/i',
);
}
/**
* Get the list of general characters
*
* @return array
*/
private function get_general_characters() {
return array(
'/\,/i',
'/\:/i',
'/\;/i',
'/\=/i',
'/\[/i',
'/\]/i',
'/\^/i',
'/\`/i',
'/\{/i',
'/\}/i',
'/\~/i',
'/\"/i',
'/\$/i',
'/\</i',
'/\>/i',
'/\|/i',
'/\.\./i',
'/\%0/i',
'/\%A/i',
'/\%B/i',
'/\%C/i',
'/\%D/i',
'/\%E/i',
'/\%F/i',
'/\%22/i',
'/\%27/i',
'/\%28/i',
'/\%29/i',
'/\%3C/i',
'/\%3E/i',
'/\%3F/i',
'/\%5B/i',
'/\%5C/i',
'/\%5D/i',
'/\%7B/i',
'/\%7C/i',
'/\%7D/i',
);
}
}
@@ -0,0 +1,56 @@
<?php
namespace AIOWPS\Firewall;
/**
* Rule that blocks certain data from the URL's query string
*/
class Rule_Bad_Query_Strings extends Rule {
/**
* Implements the action to be taken
*/
use Action_Forbid_and_Exit_Trait;
/**
* Construct our rule
*/
public function __construct() {
// Set the rule's metadata
$this->name = 'Bad query strings';
$this->family = 'General';
$this->priority = 10;
}
/**
* Determines whether the rule is active
*
* @return boolean
*/
public function is_active() {
global $aiowps_firewall_config;
return (bool) $aiowps_firewall_config->get_value('aiowps_deny_bad_query_strings');
}
/**
* The condition to be satisfied for the rule to apply
*
* @return boolean
*/
public function is_satisfied() {
if (empty($_SERVER['QUERY_STRING'])) return Rule::NOT_SATISFIED;
$patterns = array(
'/ftp:/i',
'/http:/i',
'/https:/i',
'/mosConfig/i',
'/^.*(globals|encode|loopback).*/i',
"/(\;|'|\"|%22).*(request|insert|union|declare|drop)/i",
);
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules.
return Rule_Utils::contains_pattern($_SERVER['QUERY_STRING'], $patterns);
}
}
@@ -0,0 +1,44 @@
<?php
namespace AIOWPS\Firewall;
/**
* Rule that blocks access to the xmlrpc.php file
*/
class Rule_Block_Xmlrpc extends Rule {
/**
* Implements the action to be taken
*/
use Action_Forbid_and_Exit_Trait;
/**
* Construct our rule
*/
public function __construct() {
// Set the rule's metadata
$this->name = 'Completely block XMLRPC';
$this->family = 'General';
$this->priority = 10;
}
/**
* Determines whether the rule is active
*
* @return boolean
*/
public function is_active() {
global $aiowps_firewall_config;
return (bool) $aiowps_firewall_config->get_value('aiowps_enable_pingback_firewall');
}
/**
* The condition to be satisfied for the rule to apply
*
* @return boolean
*/
public function is_satisfied() {
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules.
return (isset($_SERVER['SCRIPT_FILENAME']) && 1 === preg_match('/\/xmlrpc\.php$/i', $_SERVER['SCRIPT_FILENAME']));
}
}
@@ -0,0 +1,69 @@
<?php
namespace AIOWPS\Firewall;
/**
* Rule that blocks comments being posted if a proxy is detected.
*/
class Rule_Proxy_Comment_Posting extends Rule {
/**
* Implements the action to be taken
*/
use Action_Forbid_and_Exit_Trait;
/**
* Construct our rule
*/
public function __construct() {
// Set the rule's metadata
$this->name = 'Proxy comment posting';
$this->family = 'General';
$this->priority = 10;
}
/**
* Determines whether the rule is active
*
* @return boolean
*/
public function is_active() {
global $aiowps_firewall_config;
return (bool) $aiowps_firewall_config->get_value('aiowps_forbid_proxy_comments');
}
/**
* The condition to be satisfied for the rule to apply
*
* @return boolean
*/
public function is_satisfied() {
//Preconditions for the rule
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules.
$is_comment_form = (isset($_SERVER['SCRIPT_FILENAME']) && 1 === preg_match('/\/wp-comments-post\.php$/i', $_SERVER['SCRIPT_FILENAME']));
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules.
$is_post = (isset($_SERVER['REQUEST_METHOD']) && 0 === strcasecmp($_SERVER['REQUEST_METHOD'], "POST"));
if (!$is_post || !$is_comment_form) return Rule::NOT_SATISFIED;
//Headers that are present if a proxy is being used
$headers = array(
'HTTP_VIA',
'HTTP_FORWARDED',
'HTTP_USERAGENT_VIA',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED_HOST',
'HTTP_PROXY_CONNECTION',
'HTTP_XPROXY_CONNECTION',
'HTTP_PC_REMOTE_ADDR',
'HTTP_CLIENT_IP',
);
foreach ($headers as $header) {
if (!empty($_SERVER[$header])) return Rule::SATISFIED;
}
return Rule::NOT_SATISFIED;
}
}