PluginProbe
Patchstack – WordPress & Plugins Security / 2.2.4
Patchstack – WordPress & Plugins Security v2.2.4
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.4, at includes/firewall.php

158 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 ) {
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_custom_whitelist_rules' => get_option( 'patchstack_custom_whitelist_rules', '' )
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 /**
101 * Display error page.
102 *
103 * @param integer $fid
104 * @return void
105 */
106 public function display_error_page( $fid = 1 ) {
107 if ( $fid != 22 && $fid != 23 && $fid != 24 && $fid != 'login' ) {
108 $this->log_request( $fid );
109 }
110
111 // Supported by a number of popular caching plugins.
112 if ( ! defined( 'DONOTCACHEPAGE' ) ) {
113 define( 'DONOTCACHEPAGE', true );
114 }
115
116 // Send forbidden headers and no-caching headers as well.
117 status_header(403);
118 send_nosniff_header();
119 nocache_headers();
120
121 if ( $fid == 'login' ) {
122 require_once dirname( __FILE__ ) . '/views/access-denied-login.php';
123 } else {
124 require_once dirname( __FILE__ ) . '/views/access-denied.php';
125 }
126
127 exit;
128 }
129
130 /**
131 * Log the blocked request.
132 *
133 * @param int $fid
134 * @return void
135 */
136 private function log_request( $fid = 1 ) {
137 global $wpdb;
138 if ( ! $wpdb || $fid == 22 || $fid == 23 || $fid == 24 || $fid == 'login' ) {
139 return;
140 }
141
142 // Insert into the logs.
143 $wpdb->insert(
144 $wpdb->prefix . 'patchstack_firewall_log',
145 array(
146 'ip' => $this->get_ip(),
147 'request_uri' => isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '',
148 'user_agent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '',
149 'method' => isset( $_SERVER['REQUEST_METHOD'] ) ? $_SERVER['REQUEST_METHOD'] : '',
150 'fid' => $fid,
151 'flag' => '',
152 'post_data' => '',
153 'block_type' => 'BLOCK',
154 )
155 );
156 }
157 }
158