PluginProbe
Patchstack – WordPress & Plugins Security / 2.2.7
Patchstack – WordPress & Plugins Security v2.2.7
2.3.7 trunk 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.16 2.1.17 2.1.18 2.1.19 2.1.2 2.1.20 2.1.21 2.1.22 2.1.23 2.1.24 2.1.25 2.1.3 2.1.4 2.1.5 2.1.6 All 49 releases
patchstack / includes / firewall.php

firewall.php in Patchstack – WordPress & Plugins Security 2.2.7, at includes/firewall.php

157 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // Do not allow the file to be called directly.
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8 /**
9 * This class provides the firewall functionality.
10 */
11 class P_Firewall extends P_Core {
12
13 /**
14 * Launch the firewall rule processor.
15 *
16 * @param bool $from_main Whether or not the firewall is loaded from the main script or not.
17 * @param Patchstack $core
18 * @param bool $skip Whether or not to process and execute the rules.
19 * @param bool $muCall Whether or not this was called from mu-plugin.
20 * @return void
21 */
22 public function __construct( $from_main = false, $core = null, $skip = false, $muCall = false ) {
23 if ( ! $from_main || ! $core ) {
24 if ( $core ) {
25 parent::__construct( $core );
26 }
27 return;
28 }
29
30 parent::__construct( $core );
31
32 // If we only want to initialize the firewall but not execute the rules.
33 if ( $skip || defined( 'DOING_CRON' ) ) {
34 return;
35 }
36
37 // Load the extension.
38 require_once __DIR__ . '/../lib/patchstack/vendor/autoload.php';
39 $extension = new Patchstack\Extensions\WordPress\Extension(
40 [
41 'patchstack_basic_firewall_roles' => $this->get_option( 'patchstack_basic_firewall_roles', [ 'administrator', 'editor', 'author' ] ),
42 'patchstack_whitelist' => get_option( 'patchstack_whitelist', '' )
43 ],
44 $this
45 );
46
47 // Initiate the firewall processor with our settings.
48 $firewall = new Patchstack\Processor(
49 $extension,
50 json_decode(get_option('patchstack_firewall_rules_v3', '[]'), true),
51 json_decode(get_option('patchstack_whitelist_rules_v3', '[]'), true),
52 [
53 'autoblockAttempts' => $this->get_option( 'patchstack_autoblock_attempts', 10 ),
54 'autoblockMinutes' => $this->get_option( 'patchstack_autoblock_minutes', 30 ),
55 'autoblockTime' => $this->get_option( 'patchstack_autoblock_blocktime', 60 ),
56 'whitelistKeysRules' => json_decode( get_option( 'patchstack_whitelist_keys_rules', '[]' ), true ),
57 'mustUsePluginCall' => $muCall
58 ],
59 json_decode(get_option('patchstack_firewall_rules', '[]'), true),
60 json_decode(get_option('patchstack_whitelist_rules', '[]'), true)
61 );
62
63 // Launch the firewall.
64 $firewall->launch();
65 }
66
67 /**
68 * Determine if the user is authenticated and in the list of whitelisted roles.
69 *
70 * @return bool
71 */
72 public function is_authenticated() {
73 if ( ! is_user_logged_in() ) {
74 return false;
75 }
76
77 // Get the whitelisted roles.
78 $roles = $this->get_option( 'patchstack_basic_firewall_roles', [ 'administrator', 'editor', 'author' ] );
79 if ( ! is_array( $roles ) ) {
80 return false;
81 }
82
83 // Special scenario for super admins on a multisite environment.
84 if ( in_array( 'administrator', $roles ) && is_multisite() && is_super_admin() ) {
85 return true;
86 }
87
88 // Get the roles of the user.
89 $user = wp_get_current_user();
90 if ( ! isset( $user->roles ) || count( (array) $user->roles ) == 0 ) {
91 return false;
92 }
93
94 // Is the user in the whitelist roles list?
95 $role_count = array_intersect( $user->roles, $roles );
96 return count( $role_count ) != 0;
97 }
98
99 /**
100 * Display error page.
101 *
102 * @param integer $fid
103 * @return void
104 */
105 public function display_error_page( $fid = 1 ) {
106 if ( $fid != 22 && $fid != 23 && $fid != 24 && $fid != 'login' ) {
107 $this->log_request( $fid );
108 }
109
110 // Supported by a number of popular caching plugins.
111 if ( ! defined( 'DONOTCACHEPAGE' ) ) {
112 define( 'DONOTCACHEPAGE', true );
113 }
114
115 // Send forbidden headers and no-caching headers as well.
116 status_header(403);
117 send_nosniff_header();
118 nocache_headers();
119
120 if ( $fid == 'login' ) {
121 require_once dirname( __FILE__ ) . '/views/access-denied-login.php';
122 } else {
123 require_once dirname( __FILE__ ) . '/views/access-denied.php';
124 }
125
126 exit;
127 }
128
129 /**
130 * Log the blocked request.
131 *
132 * @param int $fid
133 * @return void
134 */
135 private function log_request( $fid = 1 ) {
136 global $wpdb;
137 if ( ! $wpdb || $fid == 22 || $fid == 23 || $fid == 24 || $fid == 'login' ) {
138 return;
139 }
140
141 // Insert into the logs.
142 $wpdb->insert(
143 $wpdb->prefix . 'patchstack_firewall_log',
144 array(
145 'ip' => $this->get_ip(),
146 'request_uri' => isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '',
147 'user_agent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '',
148 'method' => isset( $_SERVER['REQUEST_METHOD'] ) ? $_SERVER['REQUEST_METHOD'] : '',
149 'fid' => $fid,
150 'flag' => '',
151 'post_data' => '',
152 'block_type' => 'BLOCK',
153 )
154 );
155 }
156 }
157