Skip to content

Conversation

@datlechin
Copy link
Owner

Fix for v1.6.0 issue where HTTP errors exposed raw Guzzle exception messages with HTML content. Now returns translated site_cannot_be_reached message instead.

- Handle HTTP errors (403, 404, timeouts, etc.) gracefully
- Return translated 'site_cannot_be_reached' message instead of exposing raw Guzzle exception messages with HTML content
- Fixes issue where Cloudflare-protected sites showed ugly error messages
Copilot AI review requested due to automatic review settings January 9, 2026 03:24
@datlechin datlechin merged commit 61c1d6b into main Jan 9, 2026
9 of 10 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request improves error handling in the link preview service by returning user-friendly translated error messages instead of exposing raw Guzzle exception messages that could contain HTML content. Additionally, it enhances HTTP client configuration to better handle various websites.

Key changes:

  • Enhanced HTTP client with increased timeouts, browser-like headers, redirect handling, and cookie support
  • Added specific exception handling for RequestException with translated error messages
  • Standardized error responses across all exception handlers to use the translated message

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
src/Services/LinkPreviewService.php Enhanced HTTP client configuration with longer timeouts, comprehensive browser headers, redirect support, and cookie handling to improve compatibility with various websites
src/Api/Controllers/SingleLinkPreviewController.php Added RequestException catch block and updated generic exception handler to return translated user-friendly error message
src/Api/Controllers/BatchLinkPreviewController.php Updated all exception handlers to return translated user-friendly error messages instead of exposing raw exception details

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

'track_redirects' => true,
],
'headers' => [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The User-Agent string contains a hardcoded Chrome version (120.0.0.0) that will become outdated over time. Consider using a more generic or configurable User-Agent string to avoid maintenance issues and potential detection as an outdated client.

Copilot uses AI. Check for mistakes.
namespace Datlechin\LinkPreview\Api\Controllers;

use Datlechin\LinkPreview\Services\LinkPreviewService;
use GuzzleHttp\Exception\RequestException;
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RequestException class is imported but not used in this file. The generic Throwable catch block at line 25 handles all exceptions including RequestException. Consider removing this unused import or using it to provide more specific error handling if different error messages are needed for HTTP request failures versus other types of exceptions.

Suggested change
use GuzzleHttp\Exception\RequestException;

Copilot uses AI. Check for mistakes.
'connect_timeout' => 5,
'timeout' => 15,
'connect_timeout' => 10,
'verify' => false,
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Guzzle Client is created with verify => false, which completely disables TLS certificate validation for all HTTPS link preview requests. An attacker on the network path can impersonate any HTTPS site being previewed, inject arbitrary HTML/metadata into the response, or snoop on which URLs are being fetched despite HTTPS. Re-enable certificate verification (or make it configurable and only disabled for trusted development environments) so remote hosts are properly authenticated when fetching previews.

Copilot uses AI. Check for mistakes.

foreach ($urlsToFetch as $originalUrl => $normalizedUrl) {
try {
$promises[$originalUrl] = $this->service->getClient()->getAsync($originalUrl);
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BatchLinkPreviewController::fetchUrls passes user-supplied URLs (from the urls request body) into getClient()->getAsync($originalUrl), allowing attackers to make the server issue arbitrary HTTP(S) requests on their behalf. Since isValidUrl/isUrlAllowed only check syntax, DNS resolution, and optional lists, but do not forbid internal hostnames or private network targets, this endpoint exposes a high-impact SSRF vector against internal services accessible from the server. Introduce robust host validation (e.g., blocking private/internal ranges and restricting to a safe allowlist) before scheduling these asynchronous requests.

Copilot uses AI. Check for mistakes.
@datlechin datlechin deleted the fix/friendly-error-messages branch January 9, 2026 05:39
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