No SSRF protection for HTTP client. #60676
Replies: 2 comments 1 reply
|
This is an interesting proposal. One thing I'm wondering is where Laravel should draw the line between providing secure defaults and remaining a thin abstraction over the underlying HTTP client. For example, should SSRF protection be enabled by default for every request, or would it make more sense as an opt-in feature (or middleware) for cases where the destination URL comes from user input? I'm curious how you'd balance improved security with avoiding unexpected behavior for applications that intentionally make requests to internal services or private networks. |
|
I think the distinction should be between Http::get() with a developer-controlled URL and requests where the URL originates from user input. Enabling SSRF protection globally could indeed break legitimate internal-service calls in Docker/Kubernetes environments. But relying on every application developer to remember to validate user-controlled URLs is also easy to get wrong. An explicit opt-in API could be a good middle ground, for example a request middleware or client configuration that restricts private/link-local ranges while keeping the default HTTP client behavior unchanged. In particular, protection should probably cover redirects as well, since validating only the initial URL wouldn't prevent a public URL from redirecting to an internal address. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Laravel Version
13
PHP Version
8.5
Database Driver & Version
No response
Description
When a user-controlled $url is passed directly to Http::get(), it can be abused for SSRF attacks. An attacker can probe ports and internal services on your server (for example, checking whether MySQL is listening on port 3306) or access cloud metadata endpoints such as http://169.254.169.254/latest/meta-data/ on AWS, potentially exposing temporary IAM credentials and allowing further compromise.
Symfony has an implementation for this problem: https://symfony.com/blog/new-in-symfony-5-1-server-side-request-forgery-protection
Steps To Reproduce
If you have an AWS instance created before around 2024, IMDSv1 is enabled by default. Calling Http::get('http://169.254.169.254/latest/meta-data/...') can return the instance's temporary AWS credentials.
All reactions