NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Safe Fetch for Laravel

Artisan commands

safe-fetch:check {url?} {--http} {--json}

php artisan safe-fetch:check                                   # the environment
php artisan safe-fetch:check https://hooks.example.com/in      # a URL's verdict under the configured policy
php artisan safe-fetch:check http://hooks.example.com/in --http # allow http for this check only
php artisan safe-fetch:check https://hooks.example.com/in --json
  • With a URL: the guard’s verdict under the configured policy — Allowed. with the rebuilt URL, every vetted address and the CURLOPT_RESOLVE entry (or “address literal”), exit 0; or Refused: <reason>. with the rule (blockedBy), exit 1. --http allows http for this check only.
  • Without one: the environment — DNS pinning (curl version or unavailable), the pre-send address check (on or off), international host names (ext-intl), the Guzzle version and the configuration (valid or the error). It exits 1 when curl is missing or the configuration is invalid.
  • Warnings: http allowed in production, allowed ranges broader than /8 (IPv4, or the IPv4 an IPv6 range carries) or /32 (IPv6), an app.url with no host the guard can read while the app-host block is on, redirects that may drop to http, and a pre-send check that is off.
  • It never prints the internal names or ranges you trust.
  • --json prints either as JSON with the same exit codes — for scripts and monitoring.
// a verdict
{"allowed": true, "url": "…", "addresses": ["…"], "pinned_as": "…"}      // pinned_as is null for an address literal
{"allowed": false, "reason": "blocked", "retryable": false, "blocked_by": "private_address"}

// the environment
{"dns_pinning": true, "curl": "…", "pre_send_check": true, "international_host_names": true,
 "guzzle": "…", "configuration_valid": true, "errors": [], "warnings": []}

php artisan about

php artisan about   # the Safe-fetch section: counts only

The package adds a section with counts only — the internal host names and ranges you trust never render:

RowShows
Schemeshttps, or http, https.
Portsany, or the list.
Allowed hostsany, or a count.
Private hosts · Allowed ranges · Blocked rangesCounts.
App hostsblocked or not blocked.
Redirectsoff, or e.g. 307, 308 · max 3.
DNS pinningcurl <version> or unavailable.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.