If your app lets users submit URLs that you then fetch, for link previews, webhooks, or RSS feeds, you have a serious security problem waiting to happen.
An attacker can submit something like http://127.0.0.1/admin or http://169.254.169.254 (AWS metadata endpoint) and your server will happily fetch it.
That's called a Server-Side Request Forgery attack, or SSRF.
Symfony has a built-in solution: NoPrivateNetworkHttpClient.
So your code:
class LinkPreviewController
{
public function __construct(
private HttpClientInterface $client,
) {}
#[Route('/api/preview', methods: ['POST'])]
public function preview(
Request $request,
): JsonResponse {
$url = $request->getPayload()
->getString('url');
$response = $this->client
->request('GET', $url);
return new JsonResponse(
$response->getContent()
);
}
}
Becomes:
class LinkPreviewController
{
private HttpClientInterface $safeClient;
public function __construct(
HttpClientInterface $client,
) {
$this->safeClient =
new NoPrivateNetworkHttpClient(
$client
);
}
#[Route('/api/preview', methods: ['POST'])]
public function preview(
Request $request,
): JsonResponse {
$url = $request->getPayload()
->getString('url');
$response = $this->safeClient
->request('GET', $url);
return new JsonResponse(
$response->getContent()
);
}
}
It's a decorator, so you just wrap your existing client & no other changes needed. Follow the documentation to set your specific IPs or IP ranges that you want to disallow.
If you fetch user-submitted URLs and you're not using this, you should be.
Top comments (0)