Security · Checked once per domain
No open redirect endpointsWhat it checks and how to fix it
What it checks
Requests twelve common redirect endpoints (/redirect, /redir, /go, /out, /click, /login, /logout and the root) with parameters such as url, to, next and redirect pointing at an external test address. Any that answers with a 3xx redirect to that external host fails; none does, it passes.
Why it matters
An open redirect lets anyone build a link on your trusted domain that sends visitors to a site of their choosing. Phishing campaigns use them because the link shows your domain and passes spam filters. They are also a stepping stone in OAuth token theft and in getting malicious URLs past allowlists.
How to fix it
Never redirect to a URL taken straight from a request parameter. Accept only relative paths, or check the destination host against an allowlist, and fall back to a safe default.
Rails
def safe_return_to
path = params[:next].to_s
# Only same-site paths: "/dashboard" yes, "//evil.com" or "https://evil.com" no
path.start_with?("/") && !path.start_with?("//") ? path : root_path
end
redirect_to safe_return_to
Rails 7+ also raises on external redirects unless you pass allow_other_host: true; keep that default on (config.action_controller.raise_on_open_redirects = true).
Generic allowlist
ALLOWED_HOSTS = %w[example.com www.example.com].freeze
host = URI.parse(target).host rescue nil
redirect_to(host.nil? || ALLOWED_HOSTS.include?(host) ? target : "/")
For outbound-link trackers (/out?url=), sign the destination with an HMAC and reject unsigned ones.