Controlled and secure external site redirects
import 'package:shelf/shelf.dart' as shelf;
shelf.Response handleRequest(shelf.Request request) {
var redirectUrl = request.url.queryParameters['redirectUrl'];
return shelf.Response.found(redirectUrl);
}
In the above code, the
handleRequest
function handles incoming requests and retrieves a
redirectUrl
from the query parameters of the request. Then, it redirects the user to the provided
redirectUrl
without any validation or control.
This is a security vulnerability known as "Uncontrolled External Site Redirect" or "Open Redirect". An attacker could manipulate the
redirectUrl
to redirect users to malicious websites. For example, the attacker could send a link to a user that points to your application but includes a
redirectUrl
to a phishing site. If the user clicks on the link, they would be redirected to the phishing site while believing they are still interacting with your application. This could lead to various types of attacks like phishing, stealing user's credentials, or delivering malware.
import 'package:shelf/shelf.dart' as shelf;
const List trustedUrls = ['https://trustedurl1.com', 'https://trustedurl2.com'];
shelf.Response handleRequest(shelf.Request request) {
var redirectUrl = request.url.queryParameters['redirectUrl'];
if (!trustedUrls.contains(redirectUrl)) {
return shelf.Response.forbidden('Invalid redirect URL');
}
return shelf.Response.found(redirectUrl);
}
The updated code includes a list of
trustedUrls
which are the only URLs to which the application is allowed to redirect. When a request is received, the
redirectUrl
is extracted from the query parameters as before. However, before the redirection is made, the
redirectUrl
is checked against the
trustedUrls
list. If the
redirectUrl
is not in the list, a 403 Forbidden response is returned, indicating that the requested redirect URL is not allowed. If the
redirectUrl
is in the list, the redirection is made as before.
This approach ensures that only trusted URLs are used for redirection, preventing an attacker from manipulating the redirect URL to an untrusted site. It also avoids the direct use of user input in the
Response.found
method, as the input is validated before it is used.