NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky
Webhooks for Laravel

Bezpečnosť odosielania (SSRF)

Odchádzajúce URL adresy pochádzajú od vašich používateľov. Bez ochrany by https://169.254.169.254/… alebo meno, ktoré sa preloží do vašej privátnej siete, urobili z vašich workerov proxy k interným systémom. Ochranu zabezpečuje Safe Fetch for Laravel; Webhooks ju zapája pri uložení aj pri každom pokuse a kroku presmerovania, pretože DNS sa medzi nimi môže zmeniť.

Pravidlá

Pravidlá vychádzajú zo SafeFetch::policy() vašej aplikácie, pričom blokovania zostanú (blokovaní hostitelia a rozsahy, hostitelia aplikácie) a výnimky sa zahodia — privátni hostitelia, povolené rozsahy a zoznam povolených hostiteľov slúžia vašim vlastným požiadavkám, nie endpointom zákazníkov — a potom sa uplatnia webhooks.ssrf.* a webhooks.outbound.*. Ide o postup, ktorý Safe Fetch odporúča balíkom. Blokovanie má prednosť pred povolením:

PravidloNastavenie
Len https; pre lokálny vývoj aj httpoutbound.allow_http
Len kanonické URL: bez userinfo, bez % / spätnej lomky / medzier v autorite, bez číselných zápisov IPv4 (2130706433, 0x7f.1, 0177.0.0.1, 127.1), IDN cez UTS #46 (ext-intl)—
Každá preložená adresa (A + AAAA) verejná — loopback, RFC 1918, link-local vrátane 169.254.169.254, CGNAT vrátane 100.100.100.200, Azure 168.63.129.16, ULA vrátane fd00:ec2::254, multicast, rezervované, dokumentačné a IPv6 s vloženou IPv4 sa odmietnu; jedna privátna odpoveď zablokuje celé meno—
Odmietnuté podľa mena pred prekladom: localhost, *.localhost, vlastní hostitelia aplikácie, ssrf.blocked_hostsssrf.block_app_hosts
Ďalšie blokované CIDR (vždy vyhrávajú)ssrf.blocked_ranges
CIDR vyňaté z tabuľky privátnych sietíssrf.allowed_ranges
Prísny zoznam povolených hostiteľov — povolený hostiteľ sa aj tak preloží, overí voči blokovaným rozsahom a pripnessrf.allowed_hosts
Portyssrf.allowed_ports

Pri uložení

So zapnutým outbound.verify_on_save vytvorenie alebo úprava endpointu prejde všetkými pravidlami vrátane prekladu DNS; pri vypnutom všetkými okrem prekladu. V oboch prípadoch sa uloží kanonická URL. Odmietnutá alebo nepreložiteľná URL vyhodí DestinationBlockedException s jednou správou pre oba prípady — kto URL zadal, nezistí nič o internom DNS — kým reason(), blockedBy() a unresolved() povedia rozdiel vášmu kódu a prevádzke:

use RoundlyConsulting\Webhooks\Exceptions\DestinationBlockedException;

try {
    Webhooks::for($team)->outbound()->create($request->validated('url'), events: ['invoice.*']);
} catch (DestinationBlockedException $e) {
    // one message for refused and unresolvable hosts — no internal-DNS oracle for whoever typed the URL
    $e->reason();       // safe-fetch's Reason, for your code and your operators
    $e->blockedBy();    // the rule, or null
    $e->unresolved();   // true when the host did not resolve
}

Pri každom pokuse

  • Požiadavka prechádza cez SafeFetch::guard() s pravidlami — cez manažér, nikdy cez makro Http::safe(), ktoré by mohol nahradiť iný balík — a obmedzenie je pridané pred ním, takže na každý pokus beží jedno obmedzenie ešte pred prekladom DNS.
  • Pri každom kroku ochrana overí URL a meno preloží raz, pripne spojenie na overené adresy (CURLOPT_RESOLVE, nové spojenie, bez opätovného použitia, bez proxy z prostredia), vynúti vlastný curl handler, preruší spojenie mimo overenej množiny pred odoslaním prvého bajtu a pripojenú adresu skontroluje aj potom.
  • Zablokovaný cieľ doručenie natrvalo zlyhá (blocked, uložené s pravidlom, napríklad blocked (private_address)); nepreložiteľný hostiteľ sa opakuje (unresolved). Pripojená adresa sa zaznamená k pokusu.

Presmerovania

Predvolene vypnuté: 3xx je neúspešný pokus (redirect_not_followed, opakuje sa). S outbound.follow_redirects sa sledujú len 307 a 308 — 301, 302 a 303 by z POST urobili GET — najviac outbound.max_redirects (3), nikdy https → http (redirect_downgrade), každý krok sa znova overí a pripne v rámci jedného časového rozpočtu. Vlastné hlavičky a prihlasovacie údaje idú len na prvý origin; hlavičky webhook-id, webhook-timestamp a webhook-signature idú na každý krok.

Lokálny vývoj

Ak chcete doručovať príjemcovi na vlastnom počítači, povoľte http a potrebnú loopback adresu — nikdy v produkcii:

WEBHOOKS_ALLOW_HTTP=on
// config/webhooks.php
'ssrf' => ['allowed_ranges' => ['127.0.0.1/32'], /* … */],

WEBHOOKS_SSRF_GUARD=off ochranu úplne odstráni — bez pripnutia a bez overenia; presmerovania sa stále nesledujú — a patrí len za filtrujúcu výstupnú proxy, ktorej dôverujete; webhooks:doctor upozorní. Limit odpovede platí v oboch prípadoch: bez ochrany ide odpoveď cez sink, ktorý ponechá outbound.max_response_bytes a zvyšok zahodí. Odosielanie cez výstupnú proxy pri zapnutej ochrane nie je podporované. Ochrana potrebuje ext-curl; vlastný Guzzle handler pre celú aplikáciu ju neobíde.

Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

Ďalšie spôsoby podpory vrátane kryptomien

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.