Reference · Requests and pages
local_path
local_path(any) -> str | nullWhat it does
next if it is an address on this site, read as a browser reads it, else null. A
sign-in page sends the visitor back to where they were, /login?next=/orders/7, and a
check that next starts with / and not // lets /\evil.example through: browsers
read \ as /, and drop tabs and line breaks from an address. local_path reads it the
same way and refuses anything with a scheme or a host, so
redirect(local_path(next) ?? "/") cannot send a visitor to another site.
Examples
route POST /login { form: { email: str, password: str, next: str = "/" } } { sign_in(email, password)? redirect(local_path(next) ?? "/")}for n in ["/orders/7?tab=paid", "//evil.example", "/\\evil.example", "/\t/evil.example", "https://evil.example", "javascript:alert(1)", "orders"] { print(json.stringify(n), local_path(n))}"/orders/7?tab=paid" /orders/7?tab=paid"//evil.example" null"/\\evil.example" null"/\t/evil.example" null"https://evil.example" null"javascript:alert(1)" null"orders" nullEdge cases
- Spaces around the address are dropped; a query and a fragment are kept.
/%2Fand/%5Cat the start are refused too, as some servers decode them to//.- Anything that is not text is null, so a missing form field needs no check of its own. It runs the same in the browser.
print(local_path(" /a#b "), local_path("/%2F/evil"), local_path(null), local_path(3))/a#b null null nullErrors
None: what is not an address on the site is null.
Chaining
print("/me" | local_path() ?? "/")/meSee also
redirect, url_encode, set_session
Thread 0 posts
On local_path(): questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.
Edit this page on GitHub · every example's output was made by running it (tools/refcheck.mjs) · questions on Discord or r/quillo