mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-07-16 22:05:20 +00:00
fix(security): block SSRF via the Gotenberg host setting (GHSA-mfxg) (#664)
gotenberg_host was validated only with Laravel's 'url' rule, which permits loopback/private/link-local hosts (e.g. http://127.0.0.1, http://10.0.0.1, the cloud metadata endpoint http://169.254.169.254). When a PDF renders, the server POSTs the document HTML to that host — an SSRF primitive. - Adds App\Rules\SafeRemoteUrl: requires http(s) and rejects any host that resolves to a loopback/private/link-local/CGNAT/reserved address (IPv4 and IPv6), including literal-IP hosts. - Wires it into PDFConfigurationRequest for gotenberg_host. - Adds a defensive re-check in GotenbergPDFDriver before the outbound call to cover hosts set via env/seed/stale config or DNS rebinding (TOCTOU). Adds unit tests for the rule + validator integration.
This commit is contained in:
committed by
GitHub
parent
e92b08ef6a
commit
d615cfb4ff
45
tests/Unit/Rules/SafeRemoteUrlTest.php
Normal file
45
tests/Unit/Rules/SafeRemoteUrlTest.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
use App\Rules\SafeRemoteUrl;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
test('rejects internal, private and reserved hosts', function (string $url) {
|
||||
expect(SafeRemoteUrl::isSafe($url))->toBeFalse();
|
||||
})->with([
|
||||
'http://127.0.0.1',
|
||||
'http://169.254.169.254', // cloud metadata
|
||||
'http://10.0.0.5',
|
||||
'http://192.168.1.1',
|
||||
'http://172.16.0.1',
|
||||
'http://100.64.0.1', // CGNAT
|
||||
'http://[::1]',
|
||||
'http://0.0.0.0',
|
||||
'ftp://8.8.8.8', // non-http scheme
|
||||
'not-a-url',
|
||||
]);
|
||||
|
||||
test('allows public http(s) addresses', function (string $url) {
|
||||
expect(SafeRemoteUrl::isSafe($url))->toBeTrue();
|
||||
})->with([
|
||||
'http://8.8.8.8',
|
||||
'https://1.1.1.1',
|
||||
'http://93.184.216.34',
|
||||
]);
|
||||
|
||||
test('fails validation for an internal gotenberg host', function () {
|
||||
$validator = Validator::make(
|
||||
['gotenberg_host' => 'http://169.254.169.254'],
|
||||
['gotenberg_host' => [new SafeRemoteUrl]]
|
||||
);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
});
|
||||
|
||||
test('passes validation for a public gotenberg host', function () {
|
||||
$validator = Validator::make(
|
||||
['gotenberg_host' => 'https://1.1.1.1'],
|
||||
['gotenberg_host' => [new SafeRemoteUrl]]
|
||||
);
|
||||
|
||||
expect($validator->fails())->toBeFalse();
|
||||
});
|
||||
Reference in New Issue
Block a user