jeffersongoncalves/laravel-ssrf-guard 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

jeffersongoncalves/laravel-ssrf-guard

Composer 安装命令:

composer require jeffersongoncalves/laravel-ssrf-guard

包简介

A Laravel package that protects outbound HTTP requests from SSRF (Server-Side Request Forgery): it validates that a URL's host resolves only to public IPs (denying private, reserved, loopback and link-local ranges by default), pins the connection to the validated IP to close the DNS-rebinding TOCTOU

README 文档

README

Laravel SSRF Guard

Laravel SSRF Guard

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Whenever your application fetches a URL that came from a user — an avatar URL, a webhook target, a link preview, an imported og:image — it can be tricked into reaching internal services instead: http://localhost, http://10.0.0.1, or the cloud metadata endpoint http://169.254.169.254. That is Server-Side Request Forgery (SSRF).

Laravel SSRF Guard makes fetching untrusted URLs safe. It:

  • validates that a URL's host resolves only to public IP addresses, denying private, reserved, loopback and link-local ranges by default (both IPv4 A and IPv6 AAAA records);
  • pins the connection to the validated IP via curl's CURLOPT_RESOLVE, closing the DNS-rebinding (TOCTOU) window where a domain flips to an internal IP between validation and connection;
  • performs a safe GET that follows redirects but re-validates every hop, so a public host cannot 302 you into an internal one.

Installation

You can install the package via composer:

composer require jeffersongoncalves/laravel-ssrf-guard

You can publish the config file with:

php artisan vendor:publish --tag="ssrf-guard-config"

This is the published config file:

return [
    'timeout' => (int) env('SSRF_GUARD_TIMEOUT', 8),
    'max_redirects' => (int) env('SSRF_GUARD_MAX_REDIRECTS', 3),
    'allowed_schemes' => ['http', 'https'],
    'allow_private' => (bool) env('SSRF_GUARD_ALLOW_PRIVATE', false),
];

Usage

Resolve the guard from the container (it is registered as a singleton) or instantiate it directly.

Check whether a URL is safe to fetch

use JeffersonGoncalves\SsrfGuard\SsrfGuard;

$guard = app(SsrfGuard::class);

$guard->isPublicUrl('https://example.com');     // true
$guard->isPublicUrl('http://127.0.0.1');        // false (loopback)
$guard->isPublicUrl('http://10.0.0.1');         // false (private)
$guard->isPublicUrl('http://169.254.169.254');  // false (link-local / metadata)
$guard->isPublicUrl('ftp://example.com');       // false (scheme not allowed)

Use it to validate user input before storing or fetching it:

if (! app(SsrfGuard::class)->isPublicUrl($request->input('webhook_url'))) {
    abort(422, 'The URL must point to a public host.');
}

Fetch a URL safely

safeGet() performs the pinned, redirect-re-validating request and returns a standard Illuminate\Http\Client\Response. It throws JeffersonGoncalves\SsrfGuard\Exceptions\BlockedHostException if the URL — or any redirect hop — is not public:

use JeffersonGoncalves\SsrfGuard\SsrfGuard;
use JeffersonGoncalves\SsrfGuard\Exceptions\BlockedHostException;

try {
    $response = app(SsrfGuard::class)->safeGet($untrustedUrl);

    $body = $response->body();
} catch (BlockedHostException $e) {
    report($e);
    // The URL pointed at a non-public host — refuse to proxy it.
}

You can pass extra HTTP Client options; they are merged over the safe defaults:

$response = app(SsrfGuard::class)->safeGet($url, [
    'headers' => ['Accept' => 'image/*'],
]);

Important

safeGet() guarantees the transport is not pointed at an internal host. It does not validate the response body. If you re-serve fetched content from your own origin (images, HTML), still validate the Content-Type and sanitize/transform the body to avoid stored XSS.

Getting the curl resolve pin

If you build your own request and just want the validated CURLOPT_RESOLVE entries, call resolveEntries() — it returns null for any non-public/unsupported URL:

$resolve = app(SsrfGuard::class)->resolveEntries('https://example.com');
// ['example.com:443:93.184.216.34']  (or null if not public)

Configuration

Key Default Description
timeout 8 Maximum seconds a safeGet() request may run.
max_redirects 3 How many redirect hops to follow — each one is re-validated.
allowed_schemes ['http', 'https'] Schemes considered valid; everything else is rejected.
allow_private false DANGER — when true, skips the private/reserved/loopback/link-local check. For local development only; never enable in production.

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-20

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固