PHPackages                             j0k3r/httplug-ssrf-plugin - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. j0k3r/httplug-ssrf-plugin

ActiveLibrary[HTTP &amp; Networking](/categories/http)

j0k3r/httplug-ssrf-plugin
=========================

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

v3.0.1(1y ago)4346.5k↑201.7%5[2 issues](https://github.com/j0k3r/httplug-ssrf-plugin/issues)3MITPHPPHP &gt;=7.4CI passing

Since Nov 1Pushed 4d ago3 watchersCompare

[ Source](https://github.com/j0k3r/httplug-ssrf-plugin)[ Packagist](https://packagist.org/packages/j0k3r/httplug-ssrf-plugin)[ Docs](https://github.com/j0k3r/httplug-ssrf-plugin)[ GitHub Sponsors](https://github.com/j0k3r)[ RSS](/packages/j0k3r-httplug-ssrf-plugin/feed)WikiDiscussions master Synced today

READMEChangelog (6)Dependencies (13)Versions (8)Used By (3)

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

[](#server-side-request-forgery-ssrf-protection-plugin-for-httplug)

[![CI](https://github.com/j0k3r/httplug-ssrf-plugin/workflows/CI/badge.svg)](https://github.com/j0k3r/httplug-ssrf-plugin/workflows/CI/badge.svg)[![Coverage Status](https://camo.githubusercontent.com/26cc5382fb0cbf6af511b04320791edc1e6566e588489cfe9093b082a5b5e966/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6a306b33722f687474706c75672d737372662d706c7567696e2f62616467652e7376673f6272616e63683d6d617374657226736572766963653d676974687562)](https://coveralls.io/github/j0k3r/httplug-ssrf-plugin?branch=master)

Inspired from [SafeCurl](https://github.com/j0k3r/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](https://docs.php-http.org/en/latest/).

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.

Installation
------------

[](#installation)

It can be included in any PHP project using [Composer](https://getcomposer.org).

```
composer require j0k3r/httplug-ssrf-plugin

```

Usage
-----

[](#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.

#### Options

[](#options)

The default options are to not allow access to any [private IP addresses](https://en.wikipedia.org/wiki/Private_network), and to only allow HTTP(S) connections.

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.

Domains are express using regex syntax, whilst IPs, scheme and ports are standard strings (IPs can be specified in [CIDR notation](https://en.wikipedia.org/wiki/Cidr)).

```
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

[](#optional-protections)

In addition to the standard checks, two more are available.

The first is to prevent [DNS Rebinding](https://en.wikipedia.org/wiki/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.

```
$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.

```
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);
```

#### Caveats

[](#caveats)

Since the libray uses [`gethostbynamel`](https://php.net/manual/en/function.gethostbynamel.php) to resolve domain names, which isn't IPv6 compatible, the class will only work with IPv4 at the moment.

###  Health Score

52

—

FairBetter than 96% of packages

Maintenance63

Regular maintenance activity

Popularity41

Moderate usage in the ecosystem

Community23

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~524 days

Recently: every ~540 days

Total

6

Last Release

543d ago

Major Versions

v1.0.0 → v2.0.02019-02-06

v2.0.2 → v3.0.02023-04-18

PHP version history (4 changes)v1.0.0PHP ^5.5 || ^7.0

v2.0.0PHP ^7.1

v2.0.2PHP &gt;=7.2.9

v3.0.0PHP &gt;=7.4

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/62333?v=4)[Jérémy Benoist](/maintainers/j0k3r)[@j0k3r](https://github.com/j0k3r)

![](https://avatars.githubusercontent.com/u/163941?v=4)[aaa2000](/maintainers/aaa2000)[@aaa2000](https://github.com/aaa2000)

---

Top Contributors

[![j0k3r](https://avatars.githubusercontent.com/u/62333?v=4)](https://github.com/j0k3r "j0k3r (39 commits)")[![aaa2000](https://avatars.githubusercontent.com/u/163941?v=4)](https://github.com/aaa2000 "aaa2000 (19 commits)")[![jtojnar](https://avatars.githubusercontent.com/u/705123?v=4)](https://github.com/jtojnar "jtojnar (19 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (5 commits)")[![Rudloff](https://avatars.githubusercontent.com/u/840125?v=4)](https://github.com/Rudloff "Rudloff (1 commits)")

---

Tags

httplugphppluginserver-side-request-forgeryssrfhttppluginsecurityhttplugssrf

###  Code Quality

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/j0k3r-httplug-ssrf-plugin/health.svg)

```
[![Health](https://phpackages.com/badges/j0k3r-httplug-ssrf-plugin/health.svg)](https://phpackages.com/packages/j0k3r-httplug-ssrf-plugin)
```

###  Alternatives

[guzzlehttp/psr7

PSR-7 message implementation that also provides common utility methods

8.0k1.1B4.0k](/packages/guzzlehttp-psr7)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28150.5k](/packages/phpro-http-tools)[laudis/neo4j-php-client

Neo4j-PHP-Client is the most advanced PHP Client for Neo4j

185702.8k43](/packages/laudis-neo4j-php-client)[flow-php/flow

PHP ETL - Extract Transform Load - Data processing framework

85036.3k](/packages/flow-php-flow)[php-http/httplug-bundle

Symfony integration for HTTPlug

39021.7M61](/packages/php-http-httplug-bundle)[telnyx/telnyx-php

Official Telnyx PHP SDK — APIs for Voice, SMS, MMS, WhatsApp, Fax, SIP Trunking, Wireless IoT, Call Control, and more. Build global communications on Telnyx's private carrier-grade network.

35789.4k2](/packages/telnyx-telnyx-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
