bsomeshwer /
firewall
| 1 | <?php |
||||
| 2 | |||||
| 3 | namespace Someshwer\Firewall\Middleware; |
||||
| 4 | |||||
| 5 | use Closure; |
||||
| 6 | use Illuminate\Support\Facades\Log; |
||||
|
0 ignored issues
–
show
|
|||||
| 7 | use Someshwer\Firewall\Lib\IPFilter; |
||||
| 8 | use Someshwer\Firewall\src\Entities\FirewallLog; |
||||
| 9 | |||||
| 10 | /** |
||||
| 11 | * @author Someshwer<[email protected]> |
||||
| 12 | * Date: 11-08-2018 |
||||
| 13 | * Time: 20:42 IST |
||||
| 14 | * |
||||
| 15 | * This class filters ip address of every incoming request before actual request is handled. |
||||
| 16 | * Filter in blacklist or whitelist are two configured options available. |
||||
| 17 | * |
||||
| 18 | * This also logs every incoming request to the application. |
||||
| 19 | * The log data is available in 'firewall_requests_log' table. |
||||
| 20 | * |
||||
| 21 | * FirewallMiddleware class |
||||
| 22 | */ |
||||
| 23 | class FirewallMiddleware |
||||
| 24 | { |
||||
| 25 | /** |
||||
| 26 | * The ip addresses defined in this variable can be rejected even if they white listed. |
||||
| 27 | * |
||||
| 28 | * @var array |
||||
| 29 | */ |
||||
| 30 | protected $reject; |
||||
| 31 | |||||
| 32 | /** |
||||
| 33 | * The ip addresses defined in this variable can be acceptable even if they are blacklisted. |
||||
| 34 | * |
||||
| 35 | * @var array |
||||
| 36 | */ |
||||
| 37 | protected $accept; |
||||
| 38 | |||||
| 39 | /** |
||||
| 40 | * IPFilter class object. |
||||
| 41 | * |
||||
| 42 | * @var object |
||||
| 43 | */ |
||||
| 44 | private $ip_filter; |
||||
| 45 | |||||
| 46 | /** |
||||
| 47 | * Redirect url for black and white list. |
||||
| 48 | * |
||||
| 49 | * @var string |
||||
| 50 | */ |
||||
| 51 | private $redirect_url; |
||||
| 52 | |||||
| 53 | /** |
||||
| 54 | * Determines request to be logged or not. |
||||
| 55 | * |
||||
| 56 | * @var \Illuminate\Config\Repository|mixed |
||||
|
0 ignored issues
–
show
The type
Illuminate\Config\Repository was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||||
| 57 | */ |
||||
| 58 | private $log_request; |
||||
| 59 | |||||
| 60 | /** |
||||
| 61 | * FirewallMiddleware constructor. |
||||
| 62 | * |
||||
| 63 | * @param IPFilter $ipFilter |
||||
| 64 | */ |
||||
| 65 | public function __construct(IPFilter $ipFilter) |
||||
| 66 | { |
||||
| 67 | $this->ip_filter = $ipFilter; |
||||
| 68 | $this->redirect_url = config('firewall.redirect_url'); |
||||
|
0 ignored issues
–
show
The function
config was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 69 | $this->accept = config('firewall.accept'); |
||||
| 70 | $this->reject = config('firewall.reject'); |
||||
| 71 | $this->log_request = config('firewall.firewall_log'); |
||||
| 72 | } |
||||
| 73 | |||||
| 74 | /** |
||||
| 75 | * This method assigns and stores the request |
||||
| 76 | * data into a firewall_log table. |
||||
| 77 | * |
||||
| 78 | * @param $request |
||||
| 79 | * |
||||
| 80 | * @return FirewallLog |
||||
| 81 | */ |
||||
| 82 | private function logRequest($request) |
||||
| 83 | { |
||||
| 84 | $firewall_log = new FirewallLog(); |
||||
| 85 | $firewall_log->fill([ |
||||
| 86 | 'path' => $request->path(), |
||||
| 87 | 'url' => $request->url(), |
||||
| 88 | 'full_url' => $request->fullUrl(), |
||||
| 89 | 'method' => $_SERVER['REQUEST_METHOD'], |
||||
| 90 | 'uri' => $_SERVER['REQUEST_URI'], |
||||
| 91 | 'query' => $request->query() ? $request->query() : null, |
||||
| 92 | 'file_name' => $_SERVER['SCRIPT_FILENAME'], |
||||
| 93 | 'http_host' => $_SERVER['HTTP_HOST'], |
||||
| 94 | 'http_user_agent' => $_SERVER['HTTP_USER_AGENT'], |
||||
| 95 | 'ip_address' => $request->ip(), |
||||
| 96 | 'all_request_data' => $_SERVER, |
||||
| 97 | ]); |
||||
| 98 | $firewall_log->save(); |
||||
| 99 | |||||
| 100 | return $firewall_log; |
||||
| 101 | } |
||||
| 102 | |||||
| 103 | /** |
||||
| 104 | * Checking accept list whether it has current request ip or not. |
||||
| 105 | * |
||||
| 106 | * @param object $request |
||||
| 107 | * |
||||
| 108 | * @return bool |
||||
| 109 | */ |
||||
| 110 | private function checkAcceptList($request) |
||||
| 111 | { |
||||
| 112 | $status = false; |
||||
| 113 | if (count($this->accept) > 0) { |
||||
| 114 | if (in_array($request->ip(), $this->accept)) { |
||||
| 115 | $status = true; |
||||
| 116 | } |
||||
| 117 | } |
||||
| 118 | |||||
| 119 | return $status; |
||||
| 120 | } |
||||
| 121 | |||||
| 122 | /** |
||||
| 123 | * Checking reject list whether it has current request ip or not. |
||||
| 124 | * |
||||
| 125 | * @param object $request |
||||
| 126 | * |
||||
| 127 | * @return bool |
||||
| 128 | */ |
||||
| 129 | private function checkRejectList($request) |
||||
| 130 | { |
||||
| 131 | $status = false; |
||||
| 132 | if (count($this->reject) > 0) { |
||||
| 133 | if (in_array($request->ip(), $this->reject)) { |
||||
| 134 | $status = true; |
||||
| 135 | } |
||||
| 136 | } |
||||
| 137 | |||||
| 138 | return $status; |
||||
| 139 | } |
||||
| 140 | |||||
| 141 | /** |
||||
| 142 | * Set default values to black_listed and accepted attributes. |
||||
| 143 | * |
||||
| 144 | * @param $log_request |
||||
| 145 | */ |
||||
| 146 | private function setDefaultsToBlackListAndAccepted($log_request) |
||||
| 147 | { |
||||
| 148 | if ($log_request) { |
||||
| 149 | $log_request->fill(['accepted' => false]); |
||||
| 150 | $log_request->fill(['black_listed' => false]); |
||||
| 151 | $log_request->save(); |
||||
| 152 | } |
||||
| 153 | } |
||||
| 154 | |||||
| 155 | /** |
||||
| 156 | * Set black_listed and accepted attributes and store in a table. |
||||
| 157 | * |
||||
| 158 | * @param $request |
||||
| 159 | * @param $log_request |
||||
| 160 | * @param $ip_filter |
||||
| 161 | */ |
||||
| 162 | private function saveLogForBlackAndAcceptList($request, $log_request, $ip_filter) |
||||
| 163 | { |
||||
| 164 | if ($ip_filter->filterBlackList($request)) { |
||||
| 165 | if ($log_request) { |
||||
| 166 | $log_request->fill(['black_listed' => true]); |
||||
| 167 | $log_request->save(); |
||||
| 168 | } |
||||
| 169 | } |
||||
| 170 | if ($this->checkAcceptList($request)) { |
||||
| 171 | if ($log_request) { |
||||
| 172 | $log_request->fill(['accepted' => true]); |
||||
| 173 | $log_request->save(); |
||||
| 174 | } |
||||
| 175 | } |
||||
| 176 | } |
||||
| 177 | |||||
| 178 | /** |
||||
| 179 | * This methods redirects to a specified url if the ip address is really blocked. |
||||
| 180 | * |
||||
| 181 | * @param $request |
||||
| 182 | * |
||||
| 183 | * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|null |
||||
|
0 ignored issues
–
show
The type
Illuminate\Routing\Redirector was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
The type
Illuminate\Http\RedirectResponse was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||||
| 184 | */ |
||||
| 185 | private function redirectIfBlocked($request) |
||||
| 186 | { |
||||
| 187 | // Checking accept list if blacklist is enabled |
||||
| 188 | if (!$this->checkAcceptList($request)) { |
||||
| 189 | // Checking request ip address is present in black list or not |
||||
| 190 | if ($this->ip_filter->filterBlackList($request)) { |
||||
| 191 | // If present redirect the request custom redirection url |
||||
| 192 | return redirect($this->redirect_url); |
||||
|
0 ignored issues
–
show
The function
redirect was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 193 | } |
||||
| 194 | } |
||||
| 195 | |||||
| 196 | return null; |
||||
| 197 | } |
||||
| 198 | |||||
| 199 | /** |
||||
| 200 | * Set values to white_listed and rejected attributes. |
||||
| 201 | * |
||||
| 202 | * @param $request |
||||
| 203 | * @param $log_request |
||||
| 204 | */ |
||||
| 205 | private function setValuesToWhiteListedAndRejected($request, $log_request) |
||||
| 206 | { |
||||
| 207 | if ($this->ip_filter->filterWhiteList($request)) { |
||||
| 208 | if ($log_request) { |
||||
| 209 | $log_request->fill(['white_listed' => true]); |
||||
| 210 | $log_request->fill(['rejected' => false]); |
||||
| 211 | $log_request->save(); |
||||
| 212 | } |
||||
| 213 | } |
||||
| 214 | } |
||||
| 215 | |||||
| 216 | /** |
||||
| 217 | * Redirecting to specified url if the ip in rejected list. |
||||
| 218 | * |
||||
| 219 | * @param $request |
||||
| 220 | * @param $log_request |
||||
| 221 | * |
||||
| 222 | * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|null |
||||
| 223 | */ |
||||
| 224 | private function redirectIfRejectListed($request, $log_request) |
||||
| 225 | { |
||||
| 226 | // Checking reject list if whitelist is enabled |
||||
| 227 | if ($this->checkRejectList($request)) { |
||||
| 228 | if ($log_request) { |
||||
| 229 | $log_request->fill(['rejected' => true]); |
||||
| 230 | $log_request->save(); |
||||
| 231 | } |
||||
| 232 | // If present redirect the request custom redirection url |
||||
| 233 | return redirect($this->redirect_url); |
||||
|
0 ignored issues
–
show
The function
redirect was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 234 | } |
||||
| 235 | |||||
| 236 | return null; |
||||
| 237 | } |
||||
| 238 | |||||
| 239 | /** |
||||
| 240 | * Redirects to a specified url if given ip is not white listed. |
||||
| 241 | * |
||||
| 242 | * @param $request |
||||
| 243 | * @param $log_request |
||||
| 244 | * |
||||
| 245 | * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|null |
||||
| 246 | */ |
||||
| 247 | private function redirectIfNotWhiteListed($request, $log_request) |
||||
| 248 | { |
||||
| 249 | // Checking request ip address is present in whitelist or not |
||||
| 250 | if (!$this->ip_filter->filterWhiteList($request)) { |
||||
| 251 | if ($log_request) { |
||||
| 252 | $log_request->fill(['white_listed' => false]); |
||||
| 253 | $log_request->save(); |
||||
| 254 | } |
||||
| 255 | // If not present redirect the request custom redirection url |
||||
| 256 | return redirect($this->redirect_url); |
||||
|
0 ignored issues
–
show
The function
redirect was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 257 | } |
||||
| 258 | |||||
| 259 | return null; |
||||
| 260 | } |
||||
| 261 | |||||
| 262 | /** |
||||
| 263 | * Handle an incoming request. |
||||
| 264 | * |
||||
| 265 | * @param \Illuminate\Http\Request $request |
||||
|
0 ignored issues
–
show
The type
Illuminate\Http\Request was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||||
| 266 | * @param \Closure $next |
||||
| 267 | * |
||||
| 268 | * @return mixed |
||||
| 269 | */ |
||||
| 270 | public function handle($request, Closure $next) |
||||
| 271 | { |
||||
| 272 | $log_request = null; |
||||
| 273 | if ($this->log_request) { |
||||
| 274 | $log_request = $this->logRequest($request); |
||||
| 275 | } |
||||
| 276 | // Checking if blacklist enabled or not |
||||
| 277 | if ($this->ip_filter->getFilterType() == 'BLACKLIST') { |
||||
| 278 | $this->setDefaultsToBlackListAndAccepted($log_request); |
||||
| 279 | $this->saveLogForBlackAndAcceptList($request, $log_request, $this->ip_filter); |
||||
| 280 | $redirect_response = $this->redirectIfBlocked($request); |
||||
| 281 | if ($redirect_response) { |
||||
| 282 | return $redirect_response; |
||||
| 283 | } |
||||
| 284 | } |
||||
| 285 | // Checking if whitelist enabled or not |
||||
| 286 | if ($this->ip_filter->getFilterType() == 'WHITELIST') { |
||||
| 287 | $this->setValuesToWhiteListedAndRejected($request, $log_request); |
||||
| 288 | $redirect_rej_response = $this->redirectIfRejectListed($request, $log_request); |
||||
| 289 | $redirect_non_white_response = $this->redirectIfNotWhiteListed($request, $log_request); |
||||
| 290 | $redirect_response = ($redirect_rej_response) ? $redirect_rej_response : |
||||
| 291 | (($redirect_non_white_response) ? $redirect_non_white_response : null); |
||||
| 292 | if ($redirect_response) { |
||||
| 293 | return $redirect_response; |
||||
| 294 | } |
||||
| 295 | } |
||||
| 296 | $response = $next($request); |
||||
| 297 | // Logging response data |
||||
| 298 | $response_data = $this->prepareResponseData($response); |
||||
| 299 | $this->logResponseData($response_data, $log_request); |
||||
| 300 | // Proceeding further with the actual request |
||||
| 301 | return $response; |
||||
| 302 | } |
||||
| 303 | |||||
| 304 | /** |
||||
| 305 | * Preparing response data to be stored. |
||||
| 306 | * |
||||
| 307 | * @param $response |
||||
| 308 | * |
||||
| 309 | * @return array |
||||
| 310 | */ |
||||
| 311 | private function prepareResponseData($response) |
||||
| 312 | { |
||||
| 313 | try { |
||||
| 314 | $response_data = [ |
||||
| 315 | 'status_code' => $response->getStatusCode(), |
||||
| 316 | 'headers' => [ |
||||
| 317 | 'cache_control' => $response->headers->get('cache-control'), |
||||
| 318 | 'content_type' => $response->headers->get('content-type'), |
||||
| 319 | 'date' => $response->headers->get('date'), |
||||
| 320 | ], |
||||
| 321 | // 'original_data'=>$response->getOriginalContent(), |
||||
| 322 | ]; |
||||
| 323 | } catch (\Exception $e) { |
||||
| 324 | Log::error($e); |
||||
| 325 | $response_data = null; |
||||
| 326 | } |
||||
| 327 | |||||
| 328 | return $response_data; |
||||
| 329 | } |
||||
| 330 | |||||
| 331 | /** |
||||
| 332 | * This logs and stores the response data to firewall_requests_log table. |
||||
| 333 | * |
||||
| 334 | * @param $response |
||||
| 335 | * @param $firewall_log |
||||
| 336 | * |
||||
| 337 | * @return mixed |
||||
| 338 | */ |
||||
| 339 | private function logResponseData($response, $firewall_log) |
||||
| 340 | { |
||||
| 341 | $firewall_log->response_data = $response; |
||||
| 342 | $firewall_log->save(); |
||||
| 343 | |||||
| 344 | return $firewall_log; |
||||
| 345 | } |
||||
| 346 | } |
||||
| 347 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths