2017 © Pedro Peláez
 

library httplug-ssrf-plugin

Server-Side Request Forgery (SSRF) protection plugin for HTTPlug

image

j0k3r/httplug-ssrf-plugin

Server-Side Request Forgery (SSRF) protection plugin for HTTPlug

  • Saturday, November 11, 2017
  • by aaa2000
  • Repository
  • 3 Watchers
  • 3 Stars
  • 114 Installations
  • PHP
  • 2 Dependents
  • 0 Suggesters
  • 1 Forks
  • 0 Open issues
  • 3 Versions
  • 20 % Grown

The README.md

Server-Side Request Forgery (SSRF) protection plugin for HTTPlug

CI Coverage Status, (*1)

Inspired from SafeCurl, it intends to validate each part of the URL against a white or black list, to help protect against Server-Side Request Forgery attacks when using HTTPlug., (*2)

Each part of the URL is broken down and validated against a white or black list. This includes resolve a domain name to it's IP addresses., (*3)

Installation

It can be included in any PHP project using Composer., (*4)

composer require j0k3r/httplug-ssrf-plugin

Usage

use Graby\HttpClient\Plugin\ServerSideRequestForgeryProtection\ServerSideRequestForgeryProtectionPlugin;
use Http\Client\Common\PluginClient;
use Http\Discovery\Psr18ClientDiscovery;

$ssrfPlugin = new ServerSideRequestForgeryProtectionPlugin();

$pluginClient = new PluginClient(
    Psr18ClientDiscovery::find(),
    [$ssrfPlugin]
);

The plugin throws a Graby\HttpClient\Plugin\ServerSideRequestForgeryProtection\Exception\InvalidURLException if the url is not valid., (*5)

Options

The default options are to not allow access to any private IP addresses, and to only allow HTTP(S) connections., (*6)

If you wish to add your own options (such as to blacklist any requests to domains your control), simply get a new Graby\HttpClient\Plugin\ServerSideRequestForgeryProtection\Options object, add to the white or black lists, and pass it along with the method calls., (*7)

Domains are express using regex syntax, whilst IPs, scheme and ports are standard strings (IPs can be specified in CIDR notation)., (*8)

use Graby\HttpClient\Plugin\ServerSideRequestForgeryProtection\Options;
use Graby\HttpClient\Plugin\ServerSideRequestForgeryProtection\ServerSideRequestForgeryProtectionPlugin;
use Http\Discovery\Psr17FactoryDiscovery;
use Http\Discovery\Psr18ClientDiscovery;
use Http\Client\Common\PluginClient;

$options = new Options();
$options->addToList(Options::LIST_BLACKLIST, Options::TYPE_DOMAIN, '(.*)\.example\.com');

$pluginClient = new PluginClient(
    Psr18ClientDiscovery::find(),
    [new ServerSideRequestForgeryProtectionPlugin($options)]
);

// This will throw an Graby\HttpClient\Plugin\ServerSideRequestForgeryProtection\Exception\InvalidURLException\InvalidDomainException
$request = Psr17FactoryDiscovery::findRequestFactory()->createRequest('GET', 'https://www.example.com');
$response = $pluginClient->sendRequest($request);

$options = new Options();
$options->setList(Options::LIST_WHITELIST, [Options::TYPE_SCHEME => ['https']]);

$pluginClient = new PluginClient(
    Psr18ClientDiscovery::find(),
    [new ServerSideRequestForgeryProtectionPlugin($options)]
);

// This will be allowed, and return the response
$request = Psr17FactoryDiscovery::findRequestFactory()->createRequest('GET', 'https://www.example.com');
$response = $pluginClient->sendRequest($request);

// This will throw an Graby\HttpClient\Plugin\ServerSideRequestForgeryProtection\Exception\InvalidURLException\InvalidDomainException
$request = Psr17FactoryDiscovery::findRequestFactory()->createRequest('GET', 'https://www.example.com');
$response = $pluginClient->sendRequest($request);

Optional Protections

In addition to the standard checks, two more are available., (*9)

The first is to prevent DNS Rebinding attacks. This can be enabled by calling the enablePinDns method on an Options object. There is one major issue with this - the SSL certificate can't be validated. This is due to the real hostname being sent in the Host header, and the URL using the IP address., (*10)

$options = new Options();
$options->enablePinDns();

The second disables the use of credentials in a URL, since PHP's parse_url returns values which differ from ones cURL uses. This is a temporary fix., (*11)

use Graby\HttpClient\Plugin\ServerSideRequestForgeryProtection\Options;
use Graby\HttpClient\Plugin\ServerSideRequestForgeryProtection\ServerSideRequestForgeryProtectionPlugin;
use Http\Discovery\Psr17FactoryDiscovery;
use Http\Discovery\Psr18ClientDiscovery;
use Http\Client\Common\PluginClient;

$options = new Options();
$options->disableSendCredentials();

//This will throw an Http\Client\Exception\RequestException
$pluginClient = new PluginClient(
    Psr18ClientDiscovery::find(),
    [new ServerSideRequestForgeryProtectionPlugin($options)]
);
$request = Psr17FactoryDiscovery::findRequestFactory()->createRequest('GET', 'https://user:pass@google.com');
$response = $pluginClient->sendRequest($request);

Cavets

Since the libray uses gethostbynamel to resolve domain names, which isn't IPv6 compatible, the class will only work with IPv4 at the moment., (*12)

The Versions

11/11 2017

dev-master

9999999-dev https://github.com/j0k3r/httplug-ssrf-plugin

Server-Side Request Forgery (SSRF) protection plugin for HTTPlug

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar aaa2000
by Jack W

plugin security http ssrf httplug

11/11 2017

dev-obfuscating-ipv4

dev-obfuscating-ipv4 https://github.com/j0k3r/httplug-ssrf-plugin

Server-Side Request Forgery (SSRF) protection plugin for HTTPlug

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar aaa2000
by Jack W

plugin security http ssrf httplug

01/11 2017