Files
root df0f2fccb8 ARGUS WordPress Defence 1.0.0 — first production release
Automatic WordPress security: local firewall, malware and file-integrity
scanning, vulnerability protection, quarantine, scheduled backups, an
optional page cache, and automatic global threat intelligence.

See README.md for installation, update, and uninstall instructions.
2026-08-09 13:40:16 +00:00

77 lines
2.8 KiB
PHP

<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Argus_WAF {
protected static $already_ran = false;
public static function inspect_and_enforce() {
if ( self::$already_ran ) {
return;
}
self::$already_ran = true;
if ( ! Argus_Settings::get( 'waf_enabled', true ) ) {
return;
}
$ip = Argus_Request_Inputs::client_ip();
if ( Argus_Challenge::maybe_handle_submission( $ip ) ) {
return;
}
if ( Argus_Ban_Engine::is_banned( $ip ) ) {
Argus_Policy_Engine::deny_already_banned( $ip );
return;
}
if ( class_exists( 'Argus_ANIS_Client' ) && Argus_ANIS_Client::maybe_enforce( $ip ) ) {
Argus_Policy_Engine::deny_already_banned( $ip );
return;
}
$inputs = Argus_Request_Inputs::collect();
$hits = Argus_WAF_Rules::scan( $inputs );
if ( empty( $hits ) ) {
return;
}
$decision = Argus_Policy_Engine::evaluate( $ip, 'waf_match', array( 'hits' => $hits ) );
self::record_finding( $ip, $hits, $decision );
Argus_Policy_Engine::enforce_decision( $ip, 'waf_match', $decision, array( 'hits' => $hits ) );
}
protected static function record_finding( $ip, array $hits, array $decision ) {
$severity = Argus_WAF_Rules::highest_severity( $hits );
$categories = array_unique( wp_list_pluck( $hits, 'category' ) );
$rule_ids = array_values( array_unique( wp_list_pluck( $hits, 'id' ) ) );
$sources = array_unique( wp_list_pluck( $hits, 'source' ) );
Argus_Findings::record(
'waf',
$severity,
array(
'what_happened' => sprintf( 'A request from %s matched %d local WAF rule(s): %s', $ip, count( $rule_ids ), implode( ', ', $rule_ids ) ),
'why_it_matters' => 'This request contained a pattern associated with ' . implode( ', ', $categories ) . ', a common technique used to compromise WordPress sites.',
'what_argus_found' => sprintf( 'Matched in: %s. Action taken: %s (%s).', implode( ', ', $sources ), $decision['action'], $decision['observation_only'] ? 'observed only, MONITOR mode' : 'enforced' ),
'when_it_happened' => current_time( 'mysql' ),
'why_suspicious' => 'The matched pattern is not something a normal WordPress visitor, editor, or REST API client would ever legitimately send.',
'what_could_be_affected' => 'If successful, this class of request could read or modify site data, execute code, or access files outside what the request should be able to reach.',
'what_should_you_do' => $decision['observation_only']
? 'ARGUS is in MONITOR mode and did not block this request. Review recent WAF findings and switch to BLOCK mode once you are confident legitimate traffic is not being flagged.'
: 'No action needed -- ARGUS already blocked this request. If you believe this was a false positive, add an exception for this rule or IP in Settings.',
),
array( 'ip' => $ip, 'hits' => $hits, 'decision' => $decision )
);
}
}