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.