When a visitor opens a page that needs a login, the shop sends them to the login page with the page they wanted in next: /login?next=/orders. After a good password, the login route answers 302 with a Location header, and the browser goes to that page. The starting code copies next into Location without looking at it: that is an open redirect.
The attack: someone mails Ana a link to the real shop, /login?next=https://evil.example/login. She logs in on the real shop, then lands on a copy of its login page that says her password was wrong. The attacker gets Ana's password when she types it again.
A safe next is a page of the shop itself, so it starts with one /. Two slashes are a trap: a browser reads //evil.example/login as another site. Python's startswith tells you how a text begins:
"kitchen-mug".startswith("kitchen") # True
"mug-kitchen".startswith("kitchen") # False
Every request below posts the form fields email=ana@example.com and password=ana-pass-123, except the last one, which has a wrong password. The login route must answer:
POST /login?next=/orders → 302 Location: /orders
POST /login?next=/products?category=kitchen → 302 Location: /products?category=kitchen
POST /login → 302 Location: /
POST /login?next=https://evil.example/login → 302 Location: /
POST /login?next=//evil.example/login → 302 Location: /
POST /login?next=https://evil.example/login → 401 {"error": "Wrong email or password"}
Your task: write a function is_safe_next(url) that answers False when url starts with //, and otherwise whether it starts with /. In login, when next_url isn't safe, set it to "/", the home page.
Assignment
Follow the Coding Tutorial to add is_safe_next and use it in login, so an outside address in next sends the visitor home instead.
Hint
Test for two slashes first: //evil.example also starts with one slash, so the one-slash test alone would let it through.
Free plan: 30 tutor messages. PRO is unlimited.
