0,
'blocked_ips' => 0,
'suspicious_registrations' => 0,
'file_upload_blocks' => 0
];
// Count blocked IPs
$transients = $wpdb->get_results(
"SELECT option_name FROM {$wpdb->options}
WHERE option_name LIKE '_transient_king_addons_%_attempts_%'
AND option_value >= 3"
);
$stats['blocked_ips'] = count($transients);
// Get failed attempts from error log (simplified - would need actual log parsing)
$log_file = ini_get('error_log');
if ($log_file && file_exists($log_file)) {
$log_content = file_get_contents($log_file);
$stats['failed_logins_24h'] = substr_count($log_content, 'King Addons Security: Failed login');
$stats['suspicious_registrations'] = substr_count($log_content, 'Suspicious registration pattern');
$stats['file_upload_blocks'] = substr_count($log_content, 'File upload blocked');
}
return $stats;
}
/**
* Get currently blocked IPs
*/
private static function get_blocked_ips()
{
global $wpdb;
$blocked_ips = [];
$transients = $wpdb->get_results(
"SELECT option_name, option_value
FROM {$wpdb->options}
WHERE option_name LIKE '_transient_king_addons_%_attempts_%'"
);
foreach ($transients as $transient) {
$attempts = intval($transient->option_value);
if ($attempts >= Security_Manager::MAX_LOGIN_ATTEMPTS) {
// Extract IP from transient name
preg_match('/_transient_king_addons_\w+_attempts_(.+)/', $transient->option_name, $matches);
if (isset($matches[1])) {
$ip_hash = $matches[1];
// Get expiration time
$timeout_option = '_transient_timeout_' . str_replace('_transient_', '', $transient->option_name);
$expires = get_option($timeout_option, 0);
$blocked_ips[] = [
'ip' => 'IP Hash: ' . substr($ip_hash, 0, 8) . '...', // Don't expose full IPs
'attempts' => $attempts,
'last_attempt' => time() - 300, // Approximate
'expires' => $expires
];
}
}
}
return $blocked_ips;
}
/**
* Get recent failed attempts from logs
*/
private static function get_recent_failed_attempts()
{
$attempts = [];
// This would parse actual log files in a real implementation
// For now, return sample data structure
return $attempts;
}
/**
* AJAX handler to clear security logs
*/
public static function clear_security_logs()
{
if (!wp_verify_nonce($_POST['nonce'], 'king_addons_security_nonce')) {
wp_send_json_error(['message' => 'Invalid nonce']);
}
if (!current_user_can('manage_options')) {
wp_send_json_error(['message' => 'Insufficient permissions']);
}
// Clear all rate limiting transients
global $wpdb;
$wpdb->query(
"DELETE FROM {$wpdb->options}
WHERE option_name LIKE '_transient_king_addons_%_attempts_%'
OR option_name LIKE '_transient_timeout_king_addons_%_attempts_%'"
);
wp_send_json_success(['message' => 'Security logs cleared successfully']);
}
/**
* AJAX handler to unblock IP
*/
public static function unblock_ip()
{
if (!wp_verify_nonce($_POST['nonce'], 'king_addons_security_nonce')) {
wp_send_json_error(['message' => 'Invalid nonce']);
}
if (!current_user_can('manage_options')) {
wp_send_json_error(['message' => 'Insufficient permissions']);
}
$ip = sanitize_text_field($_POST['ip']);
if (empty($ip)) {
wp_send_json_error(['message' => 'Invalid IP address']);
}
// Clear attempts for this IP (simplified)
global $wpdb;
$ip_hash = md5($ip);
$wpdb->query($wpdb->prepare(
"DELETE FROM {$wpdb->options}
WHERE option_name LIKE %s
OR option_name LIKE %s",
'%_king_addons_%_attempts_' . $ip_hash,
'%_king_addons_%_attempts_' . $ip_hash . '%'
));
wp_send_json_success(['message' => 'IP unblocked successfully']);
}
/**
* AJAX handler to export security report
*/
public static function export_security_report()
{
if (!wp_verify_nonce($_POST['nonce'], 'king_addons_security_nonce')) {
wp_send_json_error(['message' => 'Invalid nonce']);
}
if (!current_user_can('manage_options')) {
wp_send_json_error(['message' => 'Insufficient permissions']);
}
// Generate security report
$stats = self::get_security_statistics();
$blocked_ips = self::get_blocked_ips();
$report = [
'generated_at' => current_time('Y-m-d H:i:s'),
'site_url' => get_site_url(),
'plugin_version' => defined('KING_ADDONS_VERSION') ? KING_ADDONS_VERSION : 'Unknown',
'statistics' => $stats,
'blocked_ips' => $blocked_ips,
'security_settings' => [
'max_login_attempts' => get_option('king_addons_max_login_attempts', 5),
'lockout_duration' => get_option('king_addons_lockout_duration', 15),
'security_logging_enabled' => get_option('king_addons_enable_security_logging', 1),
]
];
// Convert to JSON
$json_report = json_encode($report, JSON_PRETTY_PRINT);
// Create filename
$filename = 'king-addons-security-report-' . date('Y-m-d-H-i-s') . '.json';
// Return download URL
$upload_dir = wp_upload_dir();
$report_path = $upload_dir['path'] . '/' . $filename;
// Save file
if (file_put_contents($report_path, $json_report)) {
$download_url = $upload_dir['url'] . '/' . $filename;
wp_send_json_success([
'message' => 'Security report generated successfully',
'download_url' => $download_url,
'filename' => $filename
]);
} else {
wp_send_json_error(['message' => 'Failed to generate report file']);
}
}
}