Newer
Older
<?php
namespace Drupal\perimeter\EventSubscriber;

Joshua Sedler
committed
use Symfony\Contracts\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
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;

Julian Pustkuchen
committed
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) {

Julian Pustkuchen
committed
if (\Drupal::currentUser()->hasPermission('bypass perimeter defence rules')) {
return;
}
$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) && !empty($request_path)) {

Julian Pustkuchen
committed
foreach ($bannedPatterns as $pattern) {
$pattern = trim($pattern);
if (!empty($pattern) && preg_match($pattern, $request_path)) {

Julian Pustkuchen
committed
$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;
}
}
}
}
}
}