You are here

PerimeterSubscriber.php in Drupal Perimeter Defence 2.0.x

Same filename and directory in other branches
  1. 8 src/EventSubscriber/PerimeterSubscriber.php

File

src/EventSubscriber/PerimeterSubscriber.php
View source
<?php

namespace Drupal\perimeter\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Database\Database;
use Drupal\ban\BanIpManager;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;

/**
 * On page not found events, ban the IP if the request is suspicious.
 */
class PerimeterSubscriber implements EventSubscriberInterface {
  protected $loggerFactory;
  protected $configFactory;

  /**
   * {@inheritdoc}
   */
  public function __construct(LoggerChannelFactoryInterface $logger_factory, ConfigFactoryInterface $config_factory) {
    $this->loggerFactory = $logger_factory;
    $this->configFactory = $config_factory;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events['kernel.exception'][] = [
      'handleBannedUrls',
    ];
    return $events;
  }

  /**
   * On page not found events, ban the IP if the request is suspicious.
   */
  public function handleBannedUrls(Event $event) {
    $exception = $event
      ->getException();
    if ($exception instanceof NotFoundHttpException) {
      $request_path = $event
        ->getRequest()
        ->getPathInfo();
      $bannedPatterns = $this->configFactory
        ->get('perimeter.settings')
        ->get('not_found_exception_patterns');
      if (!empty($bannedPatterns)) {
        foreach ($bannedPatterns as $pattern) {
          $pattern = trim($pattern);
          if (preg_match($pattern, $request_path)) {
            $connection = Database::getConnection();
            $banManager = new BanIpManager($connection);
            $banManager
              ->banIp($event
              ->getRequest()
              ->getClientIp());
            $this->loggerFactory
              ->get('Perimeter')
              ->notice('Banned: %ip for requesting %pattern <br />Source: %source <br /> User Agent: %browser', [
              '%ip' => $event
                ->getRequest()
                ->getClientIp(),
              '%pattern' => Xss::filter($request_path),
              '%source' => isset($_SERVER['HTTP_REFERER']) ? Xss::filter($_SERVER['HTTP_REFERER']) : '',
              '%browser' => isset($_SERVER['HTTP_USER_AGENT']) ? Xss::filter($_SERVER['HTTP_USER_AGENT']) : '',
            ]);
            break;
          }
        }
      }
    }
  }

}

Classes

Namesort descending Description
PerimeterSubscriber On page not found events, ban the IP if the request is suspicious.