Skip to content

Comments

Fix #970: Block local file read bypasses via UNC paths and protocol-relative URLs#972

Merged
freekmurze merged 1 commit intomainfrom
fix/local-file-read-bypasses
Feb 9, 2026
Merged

Fix #970: Block local file read bypasses via UNC paths and protocol-relative URLs#972
freekmurze merged 1 commit intomainfrom
fix/local-file-read-bypasses

Conversation

@freekmurze
Copy link
Member

Summary

Addresses the security issue raised in #970 (local file read via \\localhost/... and //127.0.0.1/... bypasses), but with a corrected approach:

  • UNC paths: Added \\ to unsafeProtocols, blocking HTML containing double-backslash patterns like <iframe src="\\localhost/etc/passwd">
  • Protocol-relative local URLs: Added a targeted regex in setHtml() that blocks // followed by local addresses (localhost, 127.x.x.x, 0.0.0.0, [::1])

Why not just add // to unsafeProtocols?

The original PR #970 added // to the unsafeProtocols array. This would break setHtml() completely because the check uses str_contains() — every HTML document with a URL like https://example.com contains //. The regex approach targets only local addresses while allowing legitimate protocol-relative URLs like //cdn.example.com/style.css.

Test plan

  • Tests for UNC path payloads (\\localhost, \\127.0.0.1)
  • Tests for protocol-relative local URLs (//localhost, //127.x.x.x, //0.0.0.0, //[::1])
  • Test that legitimate protocol-relative URLs still work
  • All existing tests pass (116 passed)

🤖 Generated with Claude Code

…elative URLs

- Add `\\` to unsafeProtocols to block UNC path attacks (e.g. `\\localhost/etc/passwd`)
- Add targeted regex check in setHtml() for protocol-relative URLs pointing to
  local addresses (localhost, 127.x.x.x, 0.0.0.0, [::1])
- Does NOT add `//` to unsafeProtocols as that would break all HTML containing URLs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@freekmurze freekmurze merged commit ced78b8 into main Feb 9, 2026
18 checks passed
@freekmurze freekmurze deleted the fix/local-file-read-bypasses branch February 9, 2026 15:09
@dllsystem
Copy link

dllsystem commented Feb 10, 2026

I am receiving this error after this change:

Spatie\Browsershot\Exceptions\HtmlIsNotAllowedToContainFile
The specified HTML contains file:// or file:/. This is not allowed.

Here is an excerpt from the code:

function renderPdf(string $view, array $data = [], string $filename = 'document.pdf'): \Illuminate\Http\Response
{
        return \Spatie\LaravelPdf\Facades\Pdf::view($view, $data)
            ->withBrowsershot(function (\Spatie\Browsershot\Browsershot $browsershot) {
                $browsershot->waitUntilNetworkIdle(false);
                $browsershot->showBackground();

                if (config('app.env') === 'local') {
                    $browsershot->addChromiumArguments([
                        'no-sandbox',
                        'disable-setuid-sandbox',
                        'disable-dev-shm-usage',
                        'disable-gpu',
                        'disable-web-security',
                        'disable-features=VizDisplayCompositor',
                        'single-process',
                        'no-zygote',
                        'disable-background-timer-throttling',
                        'disable-backgrounding-occluded-windows',
                        'disable-renderer-backgrounding',
                    ]);
                }
            })
            ->format(\Spatie\LaravelPdf\Enums\Format::A4)
            ->margins(10, 10, 10, 10, \Spatie\LaravelPdf\Enums\Unit::Millimeter)
            ->name($filename)
            ->toResponse(request());
}

@freekmurze
Copy link
Member Author

This has been fixed in the latest release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants