TL;DR
Yes, a user can be redirected to a malicious website even if only part of the URL is controlled by user input. This happens through techniques like open redirects and clever use of URL encoding/decoding. Always validate and sanitise user-supplied URL components before using them in redirection logic.
Understanding the Risk
If your application takes a portion of a URL from user input (e.g., a return URL after login, or a forwarding address), it’s vulnerable if that input isn’t properly checked. Attackers can craft malicious URLs that appear legitimate but redirect users to phishing sites or malware downloads.
How an Attack Works
- Open Redirects: Imagine your site has a redirection feature like
https://example.com/redirect?url=https://safe-site.com. An attacker could change the URL to something likehttps://example.com/redirect?url=https://evil-phishing-site.com, sending users to their malicious site while appearing to come from your trusted domain. - URL Encoding: Attackers can use URL encoding (e.g., replacing spaces with %20) to bypass simple filters. For example,
https://example.com/redirect?url=https%3A%2F%2Fevil-site.commight slip past a filter looking for ‘evil-site’. - Relative URLs: If your application doesn’t require a full URL and accepts relative paths, an attacker could use something like
/../../evil-site.comto potentially escape the intended directory structure and redirect elsewhere.
How to Prevent Redirection Attacks
- Strict Whitelisting: The best approach is to only allow redirection to a predefined list of trusted domains or URLs. Do not accept arbitrary user input for the entire URL.
- Example (Python):
allowed_domains = ['safe-site.com', 'another-safe-site.org'] url = request.args.get('url') if url and any(domain in url for domain in allowed_domains): # Proceed with redirection else: # Reject the redirect or show an error message - Input Validation: If you can’t use whitelisting, thoroughly validate the user-supplied URL.
- Check that it starts with
http://orhttps://. - Verify the domain is legitimate (e.g., using a DNS lookup). Be careful about relying solely on this as attackers can control DNS records temporarily.
- Ensure the URL doesn’t contain suspicious characters or patterns.
- Check that it starts with
- URL Sanitisation: Remove any potentially harmful components from the URL.
- Decode URL-encoded characters before validation.
- Strip out relative path segments (e.g.,
../).
- Canonical URLs: Use canonical URLs to ensure that all redirects point to the expected destination.
- Content Security Policy (CSP): Implement a strong CSP to restrict where your application can load resources from, reducing the impact of successful redirection attacks.
- Regular Audits: Regularly review your code for potential vulnerabilities and test your redirection logic with various malicious inputs.
Example Code (PHP – Sanitisation)