@@ -17,6 +17,13 @@ class Processor
1717 */
1818 private $ firewallRules = array ();
1919
20+ /**
21+ * The legacy firewall rules to process.
22+ *
23+ * @var array
24+ */
25+ private $ firewallRulesLegacy = array ();
26+
2027 /**
2128 * The whitelist rules to process.
2229 *
@@ -61,17 +68,20 @@ class Processor
6168 * Creates a new processor instance.
6269 *
6370 * @param array $firewallRules
71+ * @param array $firewallRulesLegacy
6472 * @param array $whitelistRules
6573 * @param array $options
6674 * @param ExtensionInterface $extension
6775 */
6876 public function __construct (
6977 $ firewallRules ,
78+ $ firewallRulesLegacy ,
7079 $ whitelistRules ,
7180 $ options ,
7281 ExtensionInterface $ extension
7382 ) {
7483 $ this ->firewallRules = $ firewallRules ;
84+ $ this ->firewallRulesLegacy = $ firewallRulesLegacy ;
7585 $ this ->whitelistRules = $ whitelistRules ;
7686 $ this ->options = array_merge ($ this ->options , $ options );
7787 $ this ->extension = $ extension ;
@@ -104,7 +114,7 @@ public function launch()
104114
105115 // Determine if the user is temporarily blocked from the site before we do anything else.
106116 if ($ this ->extension ->isBlocked ($ this ->autoblockMinutes , $ this ->autoblockTime , $ this ->autoblockAttempts ) && !$ this ->extension ->canBypass ()) {
107- // $this->extension->forceExit(22);
117+ $ this ->extension ->forceExit (22 );
108118 }
109119
110120 // Since the Opis/Closure package does not support PHP 8.1+,
@@ -121,38 +131,23 @@ public function launch()
121131 return ;
122132 }
123133
124- // Run the legacy firewall rules processor.
125- // Only used for general firewall rules.
126- $ this ->legacyProcessor ();
127-
128-
129-
130-
134+ // Run the legacy firewall rules processor for backwards compatibility.
135+ if (count ($ this ->firewallRulesLegacy ) > 0 ){
136+ $ this ->legacyProcessor ();
137+ }
131138
132139 $ ip = $ this ->extension ->getIpAddress ();
133-
134- SerializableClosure::setSecretKey ('secret ' );
135-
136- $ test = function () {
137- if (!isset ($ _GET ['test ' ])) {
138- return false ;
139- }
140-
141- $ decode = json_decode (base64_decode ($ _GET ['test ' ]), true );
142- return $ decode && isset ($ decode ['test ' ]);
143- };
144-
145- // Wrap the closure
146- $ wrapper = new SerializableClosure ($ test );
147-
148- // Now it can be serialized
149- $ serialized = serialize ($ wrapper );
150140 SerializableClosure::setSecretKey ('secret ' );
141+
151142 foreach ($ this ->firewallRules as $ rule ) {
152143
153144 // Get the firewall rule and extract it.
154- $ firewall_rule = json_decode ($ rule ['rule ' ]);
155- $ vpatch = unserialize ($ serialized );
145+ $ vpatch = base64_decode ($ rule ->rule );
146+ if (!$ vpatch ) {
147+ continue ;
148+ }
149+
150+ $ vpatch = unserialize ($ vpatch );
156151 if (!$ vpatch ) {
157152 continue ;
158153 }
@@ -167,20 +162,19 @@ public function launch()
167162 }
168163
169164 // If the payload did not match the rule, continue.
170- var_dump ($ rule_hit );
171165 if (!$ rule_hit ) {
172166 continue ;
173167 }
174168
175169 // Determine what action to perform.
176- if ($ firewall_rule ->type == 'BLOCK ' ) {
177- $ this ->extension ->logRequest ($ rule[ ' id ' ] , $ request , 'BLOCK ' );
178- $ this ->extension ->forceExit ($ rule[ ' id ' ] );
179- } elseif ($ firewall_rule ->type == 'LOG ' ) {
180- $ this ->extension ->logRequest ($ rule[ ' id ' ] , $ request , 'LOG ' );
181- } elseif ($ firewall_rule ->type == 'REDIRECT ' ) {
182- $ this ->extension ->logRequest ($ rule[ ' id ' ] , $ request , 'REDIRECT ' );
183- $ this ->response ->redirect ($ firewall_rule ->type_params );
170+ if ($ rule ->type == 'BLOCK ' ) {
171+ $ this ->extension ->logRequest ($ rule-> id , $ request , 'BLOCK ' );
172+ $ this ->extension ->forceExit ($ rule-> id );
173+ } elseif ($ rule ->type == 'LOG ' ) {
174+ $ this ->extension ->logRequest ($ rule-> id , $ request , 'LOG ' );
175+ } elseif ($ rule ->type == 'REDIRECT ' ) {
176+ $ this ->extension ->logRequest ($ rule-> id , $ request , 'REDIRECT ' );
177+ $ this ->response ->redirect ($ rule ->type_params );
184178 exit ;
185179 }
186180 }
@@ -199,8 +193,7 @@ public function legacyProcessor($mustExit = true)
199193 $ requests = $ this ->request ->capture ();
200194
201195 // Iterate through all root objects.
202- foreach ($ this ->firewallRules as $ firewall_rule ) {
203- $ blocked_count = 0 ;
196+ foreach ($ this ->firewallRulesLegacy as $ firewall_rule ) {
204197 $ rule_terms = json_decode ($ firewall_rule ['rule ' ]);
205198
206199 // Determine if we should match the IP address.
@@ -222,14 +215,6 @@ public function legacyProcessor($mustExit = true)
222215 }
223216 }
224217
225- // If matches on all request methods, only 1 rule match is required to block
226- if ($ rule_terms ->method === 'ALL ' ) {
227- $ count_rules = 1 ;
228- } else {
229- $ count_rules = json_decode (json_encode ($ rule_terms ->rules ), true );
230- $ count_rules = $ this ->countRules ($ count_rules );
231- }
232-
233218 // Loop through all request data that we captured.
234219 foreach ($ requests as $ key => $ request ) {
235220
@@ -244,41 +229,33 @@ public function legacyProcessor($mustExit = true)
244229 $ exp = explode ('-> ' , $ test );
245230
246231 // Determine if a rule exists for this request.
247- $ rule = array_reduce (
248- $ exp ,
249- function ($ o , $ p ) {
250- if (!isset ($ o ->$ p )) {
251- return null ;
252- }
253-
254- return $ o ->$ p ;
255- },
256- $ rule_terms
257- );
232+ $ rule = $ rule_terms ;
233+ foreach ($ exp as $ var ){
234+ if (!isset ($ rule ->$ var )){
235+ $ rule = null ;
236+ continue ;
237+ }
238+ $ rule = $ rule ->$ var ;
239+ }
258240
259241 // Determine if the rule matches the request.
260242 if (!is_null ($ rule ) && substr ($ key , 0 , 4 ) == 'rule ' && $ this ->isRuleMatch ($ rule , $ request )) {
261- $ blocked_count ++;
262- }
263- }
264- }
265-
266- // Determine if the user should be blocked.
267- if ( $ blocked_count >= $ count_rules ) {
268- if ( $ rule_terms -> type == ' BLOCK ' ) {
269- $ this -> extension -> logRequest ( $ firewall_rule [ ' id ' ], $ request , ' BLOCK ' );
270-
271- // Do we have to exit the page or simply return false?
272- if ( $ mustExit ) {
273- $ this ->extension ->forceExit ($ firewall_rule ['id ' ]);
274- } else {
275- return false ;
243+ if ( $ rule_terms -> type == ' BLOCK ' ) {
244+ $ this -> extension -> logRequest ( $ firewall_rule [ ' id ' ], $ request , ' BLOCK ' );
245+
246+ // Do we have to exit the page or simply return false?
247+ if ( $ mustExit ){
248+ $ this -> extension -> forceExit ( $ firewall_rule [ ' id ' ]);
249+ } else {
250+ return false ;
251+ }
252+ } elseif ( $ rule_terms -> type == ' LOG ' ) {
253+ $ this -> extension -> logRequest ( $ firewall_rule [ ' id ' ], $ request , ' LOG ' );
254+ } elseif ( $ rule_terms -> type == ' REDIRECT ' ) {
255+ $ this ->extension ->logRequest ($ firewall_rule ['id ' ], $ request , ' REDIRECT ' );
256+ $ this -> response -> redirect ( $ rule_terms -> type_params , $ mustExit );
257+ }
276258 }
277- } elseif ($ rule_terms ->type == 'LOG ' ) {
278- $ this ->extension ->logRequest ($ firewall_rule ['id ' ], $ request , 'LOG ' );
279- } elseif ($ rule_terms ->type == 'REDIRECT ' ) {
280- $ this ->extension ->logRequest ($ firewall_rule ['id ' ], $ request , 'REDIRECT ' );
281- $ this ->response ->redirect ($ rule_terms ->type_params , $ mustExit );
282259 }
283260 }
284261 }
@@ -308,32 +285,4 @@ private function isRuleMatch( $rule, $request ) {
308285
309286 return $ is_matched ;
310287 }
311-
312- /**
313- * Count the number of rules.
314- *
315- * @param array $array
316- * @return integer
317- */
318- private function countRules ($ array )
319- {
320- $ counter = 0 ;
321- if (is_object ($ array )) {
322- $ array = (array ) $ array ;
323- }
324-
325- if ($ array ['uri ' ]) {
326- $ counter ++;
327- }
328-
329- foreach (array ('body ' , 'params ' , 'headers ' ) as $ type ) {
330- foreach ($ array [$ type ] as $ key => $ value ) {
331- if (!is_null ($ value )) {
332- $ counter ++;
333- }
334- }
335- }
336-
337- return $ counter ;
338- }
339288}
0 commit comments