Files
WP-Security-Pack/wp-security-pack.php
T
2026-01-25 23:14:49 +01:00

280 lines
7.4 KiB
PHP

<?php
/**
* Plugin Name: WP Security Pack
* Description: A free, lightweight security plugin with zero upsells. Login protection, IP blocking, hardening, and activity logging.
* Version: 1.0
* Requires at least: 5.0
* Requires PHP: 7.4
* Author: ArkHost
* Author URI: https://arkhost.com
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: wp-security-pack
* Domain Path: /languages
*
* @package WP_Security_Pack
*/
// Prevent direct access.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Plugin constants.
define( 'WPSP_VERSION', '1.0' );
define( 'WPSP_PLUGIN_FILE', __FILE__ );
define( 'WPSP_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'WPSP_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'WPSP_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
/**
* Main plugin class.
*/
final class WP_Security_Pack {
/**
* Single instance.
*
* @var WP_Security_Pack
*/
private static $instance = null;
/**
* Plugin components.
*
* @var array
*/
private $components = array();
/**
* Get single instance.
*
* @return WP_Security_Pack
*/
public static function instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor.
*/
private function __construct() {
$this->load_dependencies();
$this->init_hooks();
}
/**
* Load required files.
*/
private function load_dependencies() {
require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-helper.php';
require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-db.php';
require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-activity-log.php';
require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-ip-control.php';
require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-login-protection.php';
require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-hardening.php';
require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-geo-blocking.php';
require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-two-factor.php';
require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-file-integrity.php';
require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-malware-scanner.php';
if ( is_admin() ) {
require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-admin.php';
require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-updater.php';
}
}
/**
* Initialize hooks.
*/
private function init_hooks() {
register_activation_hook( WPSP_PLUGIN_FILE, array( 'WPSP_DB', 'activate' ) );
register_deactivation_hook( WPSP_PLUGIN_FILE, array( 'WPSP_DB', 'deactivate' ) );
add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
add_action( 'plugins_loaded', array( 'WPSP_DB', 'maybe_upgrade' ) );
add_action( 'init', array( $this, 'init_components' ), 1 );
// Schedule cleanup cron.
add_action( 'wpsp_daily_cleanup', array( 'WPSP_Activity_Log', 'cleanup_old_logs' ) );
if ( ! wp_next_scheduled( 'wpsp_daily_cleanup' ) ) {
wp_schedule_event( time(), 'daily', 'wpsp_daily_cleanup' );
}
}
/**
* Load plugin textdomain.
*/
public function load_textdomain() {
load_plugin_textdomain(
'wp-security-pack',
false,
dirname( WPSP_PLUGIN_BASENAME ) . '/languages/'
);
}
/**
* Initialize plugin components.
*
* Note: Order matters! Components that may exit early (like login_protection
* with custom login URLs) must be initialized AFTER components that need
* to register hooks (like two_factor for 2FA on login).
*/
public function init_components() {
$this->components['activity_log'] = new WPSP_Activity_Log();
$this->components['ip_control'] = new WPSP_IP_Control();
$this->components['hardening'] = new WPSP_Hardening();
$this->components['geo_blocking'] = new WPSP_Geo_Blocking();
$this->components['two_factor'] = new WPSP_Two_Factor();
$this->components['file_integrity'] = new WPSP_File_Integrity();
$this->components['malware_scanner'] = new WPSP_Malware_Scanner();
// Login protection must be last - custom login URL handling may exit early.
$this->components['login_protection'] = new WPSP_Login_Protection();
if ( is_admin() ) {
$this->components['admin'] = new WPSP_Admin();
$this->components['updater'] = new WPSP_Updater();
}
}
/**
* Get a component.
*
* @param string $name Component name.
* @return object|null
*/
public function get_component( $name ) {
return isset( $this->components[ $name ] ) ? $this->components[ $name ] : null;
}
/**
* Get default settings.
*
* @return array
*/
public static function get_default_settings() {
return array(
// Login Protection.
'login_limit_enabled' => true,
'login_max_attempts' => 5,
'login_lockout_duration' => 15,
'login_rename_enabled' => false,
'login_custom_url' => '',
'hide_wp_admin' => false,
'honeypot_enabled' => true,
'honeypot_ban_duration' => 60, // Minutes.
'hide_login_errors' => true,
'admin_login_notify' => false,
// Login Access Restriction.
'admin_access_restriction' => false,
'admin_allowed_countries' => array(),
'admin_allowed_ips' => '',
// IP Control.
'ip_whitelist' => '',
'ip_blacklist' => '',
'auto_blacklist_enabled' => false,
'auto_blacklist_threshold' => 3,
// Geo Blocking.
'geo_blocking_enabled' => false,
'geo_blocked_countries' => array(),
'geo_database_path' => '',
// Hardening.
'disable_xmlrpc' => true,
'disable_file_editing' => true,
'disable_application_passwords' => false,
'restrict_rest_api' => true,
'remove_wp_version' => true,
'remove_feed_links' => false,
'add_security_headers' => true,
'disable_user_enumeration' => true,
'disable_pingbacks' => true,
// Two-Factor Authentication.
'two_factor_enabled' => false,
'two_factor_enforce_admin' => false,
// File Integrity.
'file_integrity_enabled' => true,
// Malware Scanner.
'malware_scan_enabled' => true,
// Email Alerts.
'email_alerts_enabled' => false,
'email_alerts_address' => '',
'email_alert_threshold' => 3,
// Activity Log.
'log_retention_days' => 30,
);
}
/**
* Get a setting value.
*
* @param string $key Setting key.
* @param mixed $default Default value.
* @return mixed
*/
public static function get_setting( $key, $default = null ) {
$settings = get_option( 'wpsp_settings', array() );
$defaults = self::get_default_settings();
if ( isset( $settings[ $key ] ) ) {
return $settings[ $key ];
}
if ( null !== $default ) {
return $default;
}
return isset( $defaults[ $key ] ) ? $defaults[ $key ] : null;
}
/**
* Update a setting value.
*
* @param string $key Setting key.
* @param mixed $value Setting value.
* @return bool
*/
public static function update_setting( $key, $value ) {
$settings = get_option( 'wpsp_settings', array() );
$settings[ $key ] = $value;
return update_option( 'wpsp_settings', $settings );
}
/**
* Prevent cloning.
*/
private function __clone() {}
/**
* Prevent unserialization.
*/
public function __wakeup() {
throw new Exception( 'Cannot unserialize singleton' );
}
}
/**
* Get plugin instance.
*
* @return WP_Security_Pack
*/
function wpsp() {
return WP_Security_Pack::instance();
}
// Initialize plugin.
wpsp();