Real changes since 1.0.0, all live-verified before this release: - Firewall: rule corpus expanded 19 -> 43 rules, real OWASP-CRS-equivalent coverage (XXE, SSRF, session fixation, Log4Shell/JNDI, scanner-tool detection, deeper SQL injection/XSS/PHP-injection). - Fixed a real bug: a quarantined file's severity badge and its content analysis score could disagree with no explanation (e.g. a benign file showing CRITICAL next to Score 0); both are now derived consistently and shown together. - ARGUS now always keeps itself updated, and can optionally do the same for every other installed plugin and theme (Settings, on by default) -- uses WordPress's own native update system, nothing custom. - Global Threat Intelligence is now opt-in, not automatic -- a single click on its own page, with an honest, specific description of exactly what's shared (an IP address, a reason code, a confidence score, a country). Previously connected automatically on activation. - New first-run Welcome screen after activation: confirms what's already protecting the site, and surfaces the few real optional choices in one place. - Dashboard: running version now visible in the header; new "IPs Tracked" and "ANIS Protections" metrics. - Full WordPress.org Plugin Directory readiness audit performed against this codebase. Two real compliance issues found and fixed (see above: Global Threat Intelligence's default, and the self-update mechanism, which is excluded from this build entirely -- WordPress.org prohibits a plugin from using any update channel other than its own, even an inert one). This release is still self-distributed, not a WordPress.org submission -- that remains a future step. Verified before publishing: this exact ZIP was installed, activated (14 admin pages loaded clean, zero PHP errors/warnings), and uninstalled (zero leftover database tables or options) in a fresh, disposable WordPress + MySQL environment. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
223 lines
14 KiB
PHP
223 lines
14 KiB
PHP
<?php
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
$argus_active_page = 'settings';
|
|
include ARGUS_WPD_DIR . 'admin/views/partials/header.php';
|
|
?>
|
|
|
|
<h1 class="argus-wpd-page-title"><?php esc_html_e( 'Settings', 'argus-wordpress-defence' ); ?></h1>
|
|
<p style="color:var(--muted);font-size:13px;margin:0 0 24px;"><?php esc_html_e( 'Start in Monitor mode, review findings, then switch to Block once you trust legitimate traffic is not being flagged.', 'argus-wordpress-defence' ); ?> <a href="<?php echo esc_url( admin_url( 'admin.php?page=argus-wpd-welcome' ) ); ?>"><?php esc_html_e( 'Revisit the setup guide', 'argus-wordpress-defence' ); ?></a>.</p>
|
|
|
|
<?php if ( ! empty( $saved ) ) : ?>
|
|
<div class="notice notice-success" style="padding:14px 18px;margin:0 0 20px;"><p style="margin:0"><?php esc_html_e( 'Settings saved.', 'argus-wordpress-defence' ); ?></p></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ( ! empty( $template_applied ) ) : ?>
|
|
<div class="notice notice-success" style="padding:14px 18px;margin:0 0 20px;"><p style="margin:0">
|
|
<?php
|
|
printf(
|
|
|
|
esc_html__( '"%s" protection template applied. You can still fine-tune anything below.', 'argus-wordpress-defence' ),
|
|
esc_html( $template_applied )
|
|
);
|
|
?>
|
|
</p></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ( ! empty( $templates ) ) : ?>
|
|
<div class="argus-wpd-panel">
|
|
<h2><?php esc_html_e( 'Site Type', 'argus-wordpress-defence' ); ?></h2>
|
|
<p style="color:var(--faint);font-size:12.5px;margin:-8px 0 16px;"><?php esc_html_e( 'A starting point, not a lock-in -- applying a template sets sensible defaults below, which you can still hand-tune afterward.', 'argus-wordpress-defence' ); ?></p>
|
|
<div class="argus-wpd-template-grid">
|
|
<?php foreach ( $templates as $key => $template ) : ?>
|
|
<div class="argus-wpd-template-card<?php echo $active_template === $key ? ' active' : ''; ?>">
|
|
<div class="argus-wpd-template-title">
|
|
<?php echo esc_html( $template['label'] ); ?>
|
|
<?php if ( $recommended_template === $key ) : ?><span class="argus-wpd-template-badge"><?php esc_html_e( 'Recommended -- store plugin detected', 'argus-wordpress-defence' ); ?></span><?php endif; ?>
|
|
<?php if ( $active_template === $key ) : ?><span class="argus-wpd-template-badge active"><?php esc_html_e( 'Currently applied', 'argus-wordpress-defence' ); ?></span><?php endif; ?>
|
|
</div>
|
|
<p class="argus-wpd-template-desc"><?php echo esc_html( $template['description'] ); ?></p>
|
|
<form method="post" onsubmit="return confirm('<?php echo esc_js( sprintf( __( 'Apply the "%s" template? This will overwrite your current Protection Mode and Engine settings below.', 'argus-wordpress-defence' ), $template['label'] ) ); ?>')">
|
|
<?php wp_nonce_field( 'argus_wpd_apply_template', 'argus_wpd_apply_template_nonce' ); ?>
|
|
<input type="hidden" name="template" value="<?php echo esc_attr( $key ); ?>" />
|
|
<button type="submit" class="button<?php echo $active_template === $key ? '' : ' button-primary'; ?>"><?php echo $active_template === $key ? esc_html__( 'Re-apply', 'argus-wordpress-defence' ) : esc_html__( 'Apply', 'argus-wordpress-defence' ); ?></button>
|
|
</form>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="argus-wpd-panel">
|
|
<form method="post">
|
|
<?php wp_nonce_field( 'argus_wpd_save_settings', 'argus_wpd_settings_nonce' ); ?>
|
|
|
|
<table class="form-table">
|
|
<tr>
|
|
<th><?php esc_html_e( 'Protection Mode', 'argus-wordpress-defence' ); ?></th>
|
|
<td>
|
|
<select name="mode">
|
|
<option value="monitor" <?php selected( $settings['mode'], 'monitor' ); ?>><?php esc_html_e( 'Monitor -- detect and log, never block', 'argus-wordpress-defence' ); ?></option>
|
|
<option value="block" <?php selected( $settings['mode'], 'block' ); ?>><?php esc_html_e( 'Block -- normal production protection', 'argus-wordpress-defence' ); ?></option>
|
|
<option value="strict" <?php selected( $settings['mode'], 'strict' ); ?>><?php esc_html_e( 'Strict -- aggressive protection', 'argus-wordpress-defence' ); ?></option>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th><?php esc_html_e( 'Engines', 'argus-wordpress-defence' ); ?></th>
|
|
<td>
|
|
<label><input type="checkbox" name="waf_enabled" <?php checked( $settings['waf_enabled'] ); ?> /> <?php esc_html_e( 'Local WAF', 'argus-wordpress-defence' ); ?></label><br>
|
|
<label><input type="checkbox" name="login_protection_enabled" <?php checked( $settings['login_protection_enabled'] ); ?> /> <?php esc_html_e( 'Login / brute-force protection', 'argus-wordpress-defence' ); ?></label><br>
|
|
<label><input type="checkbox" name="xmlrpc_block_pingback" <?php checked( $settings['xmlrpc_block_pingback'] ); ?> /> <?php esc_html_e( 'Block XML-RPC pingback (recommended)', 'argus-wordpress-defence' ); ?></label><br>
|
|
<label><input type="checkbox" name="rest_api_protection_enabled" <?php checked( $settings['rest_api_protection_enabled'] ); ?> /> <?php esc_html_e( 'REST API abuse protection', 'argus-wordpress-defence' ); ?></label><br>
|
|
<label><input type="checkbox" name="integrity_scan_enabled" <?php checked( $settings['integrity_scan_enabled'] ); ?> /> <?php esc_html_e( 'File integrity scanning', 'argus-wordpress-defence' ); ?></label><br>
|
|
<label><input type="checkbox" name="malware_scan_enabled" <?php checked( $settings['malware_scan_enabled'] ); ?> /> <?php esc_html_e( 'Malware scanning', 'argus-wordpress-defence' ); ?></label><br>
|
|
<label><input type="checkbox" name="upload_scan_enabled" <?php checked( $settings['upload_scan_enabled'] ); ?> /> <?php esc_html_e( 'Scan file uploads before they reach your website', 'argus-wordpress-defence' ); ?></label><br>
|
|
<label><input type="checkbox" name="vuln_intel_enabled" <?php checked( $settings['vuln_intel_enabled'] ); ?> /> <?php esc_html_e( 'Vulnerability intelligence', 'argus-wordpress-defence' ); ?></label><br>
|
|
<label><input type="checkbox" name="geoip_rir_enabled" <?php checked( $settings['geoip_rir_enabled'] ); ?> /> <?php esc_html_e( 'Self-hosted GeoIP (country flags/statistics)', 'argus-wordpress-defence' ); ?></label>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<?php submit_button(); ?>
|
|
</form>
|
|
</div>
|
|
|
|
<?php if ( null !== $geoip_status ) : ?>
|
|
<div class="argus-wpd-panel">
|
|
<h2><?php esc_html_e( 'GeoIP Database', 'argus-wordpress-defence' ); ?></h2>
|
|
<p style="color:var(--faint);font-size:12.5px;margin:-8px 0 16px;"><?php esc_html_e( 'Self-hosted, same public RIR delegation-file data source argus-appliance itself uses -- no MaxMind account, no manual step. Refreshes automatically once a day; nothing to click.', 'argus-wordpress-defence' ); ?></p>
|
|
<?php if ( $geoip_status['range_count'] > 0 ) : ?>
|
|
<p style="font-size:13px;color:var(--text);margin:0 0 6px;">
|
|
<?php
|
|
printf(
|
|
|
|
esc_html__( '%1$s IPv4 ranges loaded -- last refreshed %2$s ago.', 'argus-wordpress-defence' ),
|
|
esc_html( number_format_i18n( $geoip_status['range_count'] ) ),
|
|
esc_html( human_time_diff( strtotime( $geoip_status['last_refresh'] . ' UTC' ) ) )
|
|
);
|
|
?>
|
|
</p>
|
|
<?php elseif ( $geoip_status['cursor'] > 0 ) : ?>
|
|
<p style="font-size:13px;color:var(--muted);margin:0 0 6px;">
|
|
<?php
|
|
printf(
|
|
|
|
esc_html__( 'First build in progress -- %1$d of %2$d sources loaded so far, continuing automatically.', 'argus-wordpress-defence' ),
|
|
(int) $geoip_status['cursor'],
|
|
5
|
|
);
|
|
?>
|
|
</p>
|
|
<?php else : ?>
|
|
<p style="font-size:13px;color:var(--muted);margin:0 0 6px;"><?php esc_html_e( 'Not built yet -- the first daily refresh will populate this automatically, no action needed.', 'argus-wordpress-defence' ); ?></p>
|
|
<?php endif; ?>
|
|
<?php if ( ! empty( $geoip_status['last_error'] ) ) : ?>
|
|
<p style="font-size:12.5px;color:var(--amber);margin:6px 0 0;"><?php echo esc_html( $geoip_status['last_error'] ); ?></p>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="argus-wpd-panel">
|
|
<h2><?php esc_html_e( 'Automatic Security Updates', 'argus-wordpress-defence' ); ?></h2>
|
|
<p style="font-size:13px;color:var(--emerald);margin:0 0 6px;display:flex;align-items:center;gap:8px;"><span class="argus-wpd-status-chip chip-emerald" style="padding:2px 10px;"><span class="dot"></span><span class="state"><?php echo esc_html( strtoupper( Argus_Auto_Update::status()['label'] ) ); ?></span></span></p>
|
|
<p style="color:var(--faint);font-size:12.5px;margin:8px 0 0 0 0 16px;"><?php echo esc_html( Argus_Auto_Update::status()['detail'] ); ?></p>
|
|
<form method="post" style="margin-top:14px;">
|
|
<?php wp_nonce_field( 'argus_wpd_save_auto_update_all', 'argus_wpd_auto_update_all_nonce' ); ?>
|
|
<label style="display:block;"><input type="checkbox" name="auto_update_all_enabled" <?php checked( $settings['auto_update_all_enabled'] ); ?> /> <?php esc_html_e( 'Also auto-update every other installed plugin and theme (recommended)', 'argus-wordpress-defence' ); ?></label>
|
|
<button type="submit" class="button" style="margin-top:10px;"><?php esc_html_e( 'Save', 'argus-wordpress-defence' ); ?></button>
|
|
</form>
|
|
<?php if ( class_exists( 'Argus_Update_Client' ) ) : ?>
|
|
<?php $update_status = Argus_Update_Client::status(); ?>
|
|
<table class="widefat" style="border:none;background:transparent;margin-top:14px;">
|
|
<tbody>
|
|
<tr>
|
|
<td style="border:none;padding:6px 0;color:var(--faint);font-size:12px;width:160px;"><?php esc_html_e( 'Current Version', 'argus-wordpress-defence' ); ?></td>
|
|
<td style="border:none;padding:6px 0;color:var(--text);font-size:13px;font-weight:600;"><?php echo esc_html( $update_status['current_version'] ); ?></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border:none;padding:6px 0;color:var(--faint);font-size:12px;"><?php esc_html_e( 'Update Status', 'argus-wordpress-defence' ); ?></td>
|
|
<td style="border:none;padding:6px 0;color:var(--text);font-size:13px;">
|
|
<?php if ( ! empty( $update_status['pending']['version'] ) ) : ?>
|
|
<?php echo esc_html( sprintf( __( 'Update to %s available', 'argus-wordpress-defence' ), $update_status['pending']['version'] ) ); ?>
|
|
<?php elseif ( empty( $update_status['configured'] ) ) : ?>
|
|
<?php esc_html_e( 'Update channel not configured', 'argus-wordpress-defence' ); ?>
|
|
<?php else : ?>
|
|
<?php esc_html_e( 'Up to date', 'argus-wordpress-defence' ); ?>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border:none;padding:6px 0;color:var(--faint);font-size:12px;"><?php esc_html_e( 'Last Successful Update', 'argus-wordpress-defence' ); ?></td>
|
|
<td style="border:none;padding:6px 0;color:var(--text);font-size:13px;">
|
|
<?php
|
|
if ( ! empty( $update_status['last_success']['installed_at'] ) ) {
|
|
echo esc_html( sprintf( '%s (%s)', $update_status['last_success']['version'], wp_date( 'd M Y, H:i', strtotime( $update_status['last_success']['installed_at'] . ' UTC' ) ) ) );
|
|
} else {
|
|
esc_html_e( 'None yet', 'argus-wordpress-defence' );
|
|
}
|
|
?>
|
|
</td>
|
|
</tr>
|
|
<?php if ( ! empty( $update_status['last_failure']['message'] ) ) : ?>
|
|
<tr>
|
|
<td style="border:none;padding:6px 0;color:var(--faint);font-size:12px;"><?php esc_html_e( 'Last Failed Update', 'argus-wordpress-defence' ); ?></td>
|
|
<td style="border:none;padding:6px 0;color:var(--rose);font-size:13px;"><?php echo esc_html( $update_status['last_failure']['message'] ); ?></td>
|
|
</tr>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php if ( ! empty( $update_check_result ) ) : ?>
|
|
<p style="font-size:12.5px;margin:12px 0 0;color:<?php echo ! empty( $update_check_result['success'] ) ? 'var(--emerald)' : 'var(--rose)'; ?>;"><?php echo esc_html( $update_check_result['message'] ); ?></p>
|
|
<?php endif; ?>
|
|
<form method="post" style="margin-top:14px;">
|
|
<?php wp_nonce_field( 'argus_wpd_check_updates', 'argus_wpd_check_updates_nonce' ); ?>
|
|
<button type="submit" class="button"><?php esc_html_e( 'Check for Updates Now', 'argus-wordpress-defence' ); ?></button>
|
|
</form>
|
|
<?php else : ?>
|
|
<p style="color:var(--faint);font-size:12.5px;margin:14px 0 0;"><?php esc_html_e( 'Updates for this plugin are delivered through WordPress.org, the same way as any other WordPress plugin -- you\'ll see a notification in your dashboard when a new version is available.', 'argus-wordpress-defence' ); ?></p>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="argus-wpd-panel">
|
|
<h2><?php esc_html_e( 'Website Acceleration', 'argus-wordpress-defence' ); ?></h2>
|
|
<p style="color:var(--faint);font-size:12.5px;margin:-8px 0 12px;"><?php esc_html_e( 'Cache & Performance now has its own dedicated page -- speed up your website, reduce load, and see what\'s being accelerated.', 'argus-wordpress-defence' ); ?></p>
|
|
<a href="<?php echo esc_url( admin_url( 'admin.php?page=argus-wpd-cache' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Open Cache & Performance', 'argus-wordpress-defence' ); ?></a>
|
|
</div>
|
|
|
|
<div class="argus-wpd-panel">
|
|
<h2><?php esc_html_e( 'IP Whitelist', 'argus-wordpress-defence' ); ?></h2>
|
|
<p style="color:var(--faint);font-size:12.5px;margin:-8px 0 16px;"><?php esc_html_e( 'Whitelisted IPs always pass -- WAF, login protection, and bans never apply to them. Use for your own office/VPN IP, monitoring services, etc.', 'argus-wordpress-defence' ); ?></p>
|
|
|
|
<?php $exceptions = Argus_Settings::get( 'exceptions', array() ); ?>
|
|
<?php if ( empty( $exceptions ) ) : ?>
|
|
<p class="argus-wpd-empty" style="padding:10px 0;"><?php esc_html_e( 'No exceptions yet.', 'argus-wordpress-defence' ); ?></p>
|
|
<?php else : ?>
|
|
<?php foreach ( $exceptions as $exception ) : ?>
|
|
<?php if ( 'ip' !== ( $exception['type'] ?? '' ) ) { continue; } ?>
|
|
<div class="argus-wpd-exception-row">
|
|
<code><?php echo esc_html( $exception['value'] ); ?></code>
|
|
<span class="note"><?php echo esc_html( $exception['note'] ?? '' ); ?></span>
|
|
<span class="added"><?php echo esc_html( $exception['added_at'] ?? '' ); ?></span>
|
|
<form method="post">
|
|
<?php wp_nonce_field( 'argus_wpd_remove_exception', 'argus_wpd_remove_exception_nonce' ); ?>
|
|
<input type="hidden" name="exception_value" value="<?php echo esc_attr( $exception['value'] ); ?>" />
|
|
<button type="submit" class="button"><?php esc_html_e( 'Remove', 'argus-wordpress-defence' ); ?></button>
|
|
</form>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
|
|
<form method="post" class="argus-wpd-inline-form" style="margin-top:16px;">
|
|
<?php wp_nonce_field( 'argus_wpd_add_exception', 'argus_wpd_add_exception_nonce' ); ?>
|
|
<input type="text" name="exception_ip" placeholder="203.0.113.10" required pattern="^[0-9a-fA-F:.]+$" />
|
|
<input type="text" name="exception_note" placeholder="<?php esc_attr_e( 'Note (optional)', 'argus-wordpress-defence' ); ?>" />
|
|
<button type="submit" class="button button-primary"><?php esc_html_e( 'Add to Whitelist', 'argus-wordpress-defence' ); ?></button>
|
|
</form>
|
|
</div>
|
|
|
|
<?php include ARGUS_WPD_DIR . 'admin/views/partials/footer.php'; ?>
|