Open Redirect in Laravel
How Open Redirect Manifests in Laravel
Open Redirect vulnerabilities in Laravel applications occur when an attacker can control the destination URL of a redirect, typically by manipulating a query parameter, form field, or route parameter that is passed unchecked to Laravel's redirect responses. This is a common issue in authentication flows (e.g., post-login redirects) and any endpoint that accepts a 'return_to', 'redirect', or 'url' parameter.
Laravel-Specific Attack Patterns:
- Unauthenticated Redirects in Auth Controllers: The default Laravel authentication scaffolding (e.g.,
LoginController) often uses aredirectToproperty or method that can be influenced by user input. An attacker can craft a URL like/login?redirect=https://evil.com. If the application redirects to this URL after login without validation, it enables phishing. - Route Model Binding with User-Supplied URLs: If a route uses implicit binding for a model that includes a URL field (e.g.,
App\Models\Websitewith aurlattribute), and that model's URL is used in a redirect, an attacker could register a website with a malicious URL and trigger the redirect. - Misuse of
redirect()->away(): Laravel'sredirect()->away($url)method explicitly allows external redirects. If$urlcomes directly from user input (e.g.,redirect()->away(request('next'))), it creates a direct open redirect. - Dynamic Route Generation: Using
route($name, $parameters)where$nameis user-controlled can lead to open redirects if the route definition itself points to an external URL via aredirect()action.
Example Vulnerable Code (Laravel Controller):
public function redirectAfterLogin(Request $request)
{
// VULNERABLE: Direct use of query parameter without validation
$redirectUrl = $request->query('redirect', '/dashboard');
return redirect($redirectUrl);
}
// Attacker URL: /login?redirect=https://phishing-site.comHere, the redirect() helper will send the user to any URL provided, including external domains. Laravel's redirect() to an external URL is valid behavior, but the lack of validation is the flaw.
Laravel-Specific Detection
Detecting open redirects in Laravel requires both dynamic scanning (submitting malicious payloads) and static analysis of the application's routing and controller logic. middleBrick's scanner tests for this by submitting requests with external URLs in common redirect parameters (e.g., redirect, return_to, next) and observing if the application issues a 3xx redirect to an attacker-controlled domain.
How middleBrick Identifies This:
- Dynamic Probing: The scanner sends a request like
GET /login?redirect=https://attacker.comand checks if the response contains aLocation: https://attacker.comheader. It tests multiple parameter names and HTTP methods (GET/POST). - OpenAPI/Swagger Analysis: If the Laravel application provides an OpenAPI spec (e.g., via
l5-swagger), middleBrick resolves all$refand looks for parameters named 'redirect', 'url', 'return_to' that lack aurlformat validation in the spec. It cross-references these parameters with runtime findings. - Laravel-Specific Heuristics: The scanner checks for common Laravel authentication routes (
/login,/register) and social authentication callbacks (e.g.,/login/{provider}/callback), where redirect parameters are frequently used.
Using middleBrick to Scan a Laravel API:
Scan a Laravel application's unauthenticated endpoints with middleBrick's web dashboard or CLI. For example:
# Scan a Laravel API endpoint
middlebrick scan https://laravel-app.com/api/loginThe report will flag any endpoint that reflects an external URL in a redirect under the Input Validation or Authentication categories, with a severity based on the exploitability (e.g., unauthenticated access to the redirect parameter). It will also note if the OpenAPI spec defines a redirect parameter without proper constraints.
Laravel-Specific Remediation
Remediating open redirects in Laravel involves validating any user-supplied URL before using it in a redirect. Laravel provides built-in helpers and validation rules to ensure redirects are either relative (within the same application) or to an allowlisted domain.
1. Use Named Routes Relative Redirects:
The safest approach is to avoid user-supplied URLs altogether and use named routes or relative paths.
// Instead of: return redirect($request->redirect);
// Use: return redirect()->route('dashboard');
// Or if you must accept a path: return redirect($request->validated('path'));2. Validate Redirect URLs with validateRedirect:
Laravel's Illuminate\Validation\Rules\Url can be combined with a custom closure to restrict to relative URLs or specific domains.
use Illuminate\Validation\Rule;
public function redirectAfterLogin(Request $request)
{
$validated = $request->validate([
'redirect' => [
'nullable',
'string',
function ($attribute, $value, $fail) {
// Allow only relative URLs (starting with /)
if (Str::startsWith($value, ['http://', 'https://'])) {
$fail('The '.$attribute.' must be a relative path.');
}
// Alternatively, allow specific domains:
// $allowed = ['app.example.com', 'trusted.com'];
// if (parse_url($value, PHP_URL_HOST) && !in_array(parse_url($value, PHP_URL_HOST), $allowed)) {
// $fail('Unauthorized redirect domain.');
// }
},
],
]);
return redirect($validated['redirect'] ?? '/dashboard');
}3. Use Laravel's intended Method for Auth:
Laravel's authentication system uses the intended method, which stores the intended URL in the session (via the guest middleware) rather than trusting a query parameter. This is the recommended pattern for post-login redirects.
// In LoginController (default Laravel behavior)
protected function authenticated(Request $request, $user)
{
return redirect()->intended($this->redirectPath());
}
// The intended URL is set by the 'guest' middleware when it intercepts
// a request to a protected route. No user-controlled parameter is used.4. For APIs: Return a Relative Path in JSON Responses:
If your Laravel API returns a redirect URL in a JSON response (e.g., for SPA authentication), ensure it's a relative path and document it in your OpenAPI spec.
public function apiLogin(Request $request)
{
// ... authentication logic ...
return response()->json([
'redirect_to' => '/dashboard', // never an external URL
]);
}5. Global Middleware for Legacy Routes:
For applications with many legacy redirect endpoints, create a middleware that sanitizes redirect parameters.
// app/Http/Middleware/SanitizeRedirect.php
public function handle($request, Closure $next)
{
if ($request->has('redirect')) {
$url = $request->input('redirect');
// Only allow relative URLs
if (Str::startsWith($url, ['http://', 'https://'])) {
$request->merge(['redirect' => '/']);
}
}
return $next($request);
}Register this middleware on routes that accept redirect parameters. This ensures that even if a controller forgets validation, the URL is sanitized.
OpenAPI Spec Correction: Update your OpenAPI/Swagger definition to mark redirect parameters with a custom allowRelativeOnly: true extension or use a regex pattern that disallows http schemes. middleBrick will then validate the spec compliance.
Integrating Security into Laravel Development
To prevent open redirects proactively, integrate security scanning into your Laravel development workflow.
- CI/CD Pipeline Scanning: Use middleBrick's GitHub Action to scan your Laravel API on every push or pull request. Configure it to fail the build if an open redirect (or other high-severity issue) is detected. Example workflow snippet:
# .github/workflows/api-security.yml
name: API Security Scan
on: [pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: middlebrick/github-action@v1
with:
api_url: 'https://staging.your-laravel-app.com'
fail_on_risk: 'high,critical'- Local Development with CLI: Install the
middlebricknpm package and run scans against your local Laravel environment (e.g., usingvaletorlaragon):
npm install -g middlebrick
middlebrick scan http://laravel.test/login- IDE Integration: If you use an AI coding assistant like Claude with MCP support, install middleBrick's MCP Server to scan your Laravel API endpoints directly from your editor as you develop.
- Dashboard Monitoring: For production Laravel APIs, use middleBrick's Pro plan to continuously monitor endpoints. Set up Slack/Teams alerts for any new open redirect findings, especially after deployments.
By combining Laravel's built-in validation tools with automated scanning, you can eliminate open redirect vulnerabilities before they reach production.
FAQ
Q: Why is Laravel's redirect() helper potentially dangerous?
A: The redirect() helper will accept any string, including full external URLs (e.g., https://evil.com). If that string originates from user input (query parameters, form data) and is passed directly to redirect() without validation, it creates an open redirect. The helper itself is not unsafe—the unsafe practice is trusting user input for the destination.
Q: How does middleBrick detect open redirects in a Laravel API without credentials?
A: middleBrick performs unauthenticated black-box scanning. It submits requests to public Laravel endpoints (like /login, /api/logout) with a malicious redirect parameter (e.g., redirect=https://attacker.com). If the response includes a Location header pointing to attacker.com, it flags an open redirect. It also analyzes the OpenAPI spec (if available) for redirect parameters that lack URL validation constraints.