

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: Managing Secrets
incomplete
2: Injecting Secrets at Runtime
incomplete
3: Protecting Secrets
incomplete
4: Build Artifacts and Deployment Hygiene
incomplete
5: Limiting Build Context
incomplete
6: Source Code and Config Leaks
incomplete
7: Public File Leaks
incomplete
8: Server-Side Request Forgery
incomplete
9: Defending Against SSRF
incomplete
10: Open Redirects
incomplete
11: Risks of Dependencies
incomplete
12: Auditing Dependencies
incomplete
13: Dependency Maintenance
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
An open redirect sends a user to a destination supplied by the requester. Unlike SSRF, the server isn't fetching the destination itself. The app is lending its trusted domain to an attacker-controlled redirect.
Imagine a conference site that carries a returnTo value through login and redirects to it afterward:
const returnTo = String(req.body.returnTo ?? "/");
res.redirect(returnTo);
If an attacker puts an external URL in a legitimate conference login link, the victim sees the trusted domain, signs in, and is immediately sent to a phishing site.
To deal with this, I like to use a shared helper that returns the requested path when it's explicitly allow-listed and / otherwise:
const ALLOWED_RETURN_PATHS = new Set(["/", "/account", "/schedule"]);
export function safeReturnTo(value: unknown): string {
return typeof value === "string" && ALLOWED_RETURN_PATHS.has(value)
? value
: "/";
}
A check like value.startsWith("/") isn't enough. A scheme-relative URL like //evil.example starts with a slash but still sends the browser to another host. Exact matching also rejects crafted prefixes, encoded paths, and internal destinations the flow doesn't need.
Bearly Secure already has a shared safeReturnTo helper, but isn't using it for all login flows. Ensure the shared redirect policy is applied to every login handler.
With Bearly Secure still running, run and submit the CLI tests from the project root.