The Ravens’ login page sends you after sign-in to the URL in the next parameter, and never checks that the URL belongs to the site. So you can craft a link that looks like login.ravens.lab but sends the victim to your site.
The Ravens login page sends you after sign-in to the URL in the next parameter, with no check that it belongs to the site. You type the URL, sign in, and see where the redirect landed and whether you left the site.
Make the redirect land on an external site you control, falcon.owl.lab.
You made the Ravens’ redirect land on an external site.
Why the solution worked
This is an open redirect: the site redirects to a user-supplied URL with no check, so the attacker makes a link on a trusted domain that sends the victim to a phishing site or leaks tokens in the redirect. The fix: do not accept a full URL from the user; accept only a relative path or an id from a known list of destinations, and verify the resulting URL belongs to your site after resolving it.
The root cause
The site redirects to a user-supplied URL with no check that the destination belongs to the site. The root is trusting a user-controlled destination.
How the code is fixed
Accept a relative path or an id from a list, never a full URL from the user.
Vulnerable code
app.post('/login', (req, res) => {
// Redirects to whatever the user put in next.
res.redirect(req.body.next);
});
Safe code
const DESTS = { home: '/dashboard', billing: '/billing' };
app.post('/login', (req, res) => {
// Map an id to a known internal path; never redirect to a user URL.
res.redirect(DESTS[req.body.next] ?? '/dashboard');
});
Impact in the real world
Open redirect builds phishing links on a trusted domain that steal credentials or leak tokens in the redirect URL.
How defenders detect it
Defenders alert on next values carrying full or absolute URLs and restrict redirects to relative paths or a known destination list.