shieldfy/shieldfy-php-client

View on GitHub
src/Monitors/RequestMonitor.php

Summary

Maintainability
A
45 mins
Test Coverage
<?php
namespace Shieldfy\Monitors;

use Shieldfy\Jury\Judge;
use Shieldfy\Collectors\RequestCollector;

class RequestMonitor extends MonitorBase
{
    use Judge;

    protected $name = "request";

    /**
     * Run the monitor.
     */
    public function run()
    {
        $request = $this->collectors['request'];
        $user = $this->collectors['user'];

        $result = $this->checkForCSRF($request);

        $this->events->listen('request.finish', function () {
            call_user_func([
                $this,
                'log'
            ]);
        });
    }


    public function log()
    {
        if ($this->dispatcher->hasData()) {
            return; // There is already a threat in the pipeline.
        }

        $request = $this->collectors['request'];
        $info = $request->getInfo();

        $params = array_merge($info['get'], $info['post']);

        $foundGuilty = false;
        $charge = [];
        $this->issue('request');
        foreach ($params as $key => $value) {
            // Found parameter.
            // Check infection.
            $charge = $this->sentence($value);
            if ($charge && $charge['score']) {
                $foundGuilty = true;
                $charge['value'] = $value;
                $charge['key'] = $key;
                $severity = $this->parseScore($charge['score']);
                if ($severity == 'high') {
                    $severity = 'med';
                }
                $this->sendToJail($severity, $charge);
            }
        }
    }

    private function checkForCSRF(RequestCollector $request)
    {
        $request = $this->collectors['request'];

        if ($request->requestMethod !== 'POST') {
            return false;
        }

        if (!isset($request->server['HTTP_ORIGIN'])) {
            return false;
        }

        if (strpos($request->server['HTTP_ORIGIN'], 'http') !== 0) {
            $request->server['HTTP_ORIGIN'] = 'http://'.$request->server['HTTP_ORIGIN'];
        }

        if (strpos($request->server['HTTP_HOST'], 'http') !== 0) {
            $request->server['HTTP_HOST'] = 'http://'.$request->server['HTTP_HOST'];
        }

        $origin = parse_url(trim($request->server['HTTP_ORIGIN']), PHP_URL_HOST);
        $host = parse_url(trim($request->server['HTTP_HOST']), PHP_URL_HOST);


        if (strtolower($origin) !== strtolower($host)) {
            //csrf attack found
            //since most of frameworks now uses csrf token & many of endpoint are ajax/api
            //and modern browsers default block violation of origin ( CORS : https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS )
            //so kind of violation of origin is not critical but worth reporting to the developer
            //so he can fix anything if needed
            $this->sendToJail('low', [
                'score' => 30,
                'rulesIds' => [300],
                'infection'  => [
                    'server.HTTP_ORIGIN' => $origin
                ]
            ]);
        }
    }
}