-
Notifications
You must be signed in to change notification settings - Fork 1
fix referrer encoding #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0fb5c73
04100dc
0dbd313
9dc4f41
f4a454d
6753e2a
85c0a2e
8b6f64f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| const encodedReferrerPrefix = /^https?%(?:25)*3a%(?:25)*2f%(?:25)*2f/i; | ||
| const controlCharacters = /[\u0000-\u001f\u007f]/g; | ||
| const MAX_REFERRER_LENGTH = 512; | ||
|
|
||
| export function normaliseReferrer(referrer: string): string; | ||
| export function normaliseReferrer(referrer: undefined): undefined; | ||
| export function normaliseReferrer( | ||
| referrer: string | undefined | ||
| ): string | undefined; | ||
| export function normaliseReferrer(referrer: string | undefined) { | ||
|
Comment on lines
+5
to
+10
|
||
| if (referrer === undefined) return undefined; | ||
|
|
||
| let current = referrer.trim(); | ||
|
|
||
| for (let i = 0; i < 3 && encodedReferrerPrefix.test(current); i += 1) { | ||
| try { | ||
| const decoded = decodeURIComponent(current); | ||
| if (decoded === current) break; | ||
| current = decoded; | ||
| } catch { | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| return current.replace(controlCharacters, "").slice(0, MAX_REFERRER_LENGTH); | ||
| } | ||
|
|
||
| export function getSafeHttpReferrer(referrer: string | undefined) { | ||
| const cleanedReferrer = normaliseReferrer(referrer)?.trim(); | ||
|
|
||
| if (!cleanedReferrer) return undefined; | ||
|
|
||
| try { | ||
| const referrerUrl = new URL(cleanedReferrer); | ||
|
|
||
| if (!["http:", "https:"].includes(referrerUrl.protocol)) { | ||
| return undefined; | ||
| } | ||
|
|
||
| referrerUrl.search = ""; | ||
| referrerUrl.hash = ""; | ||
|
|
||
| return referrerUrl.toString().slice(0, MAX_REFERRER_LENGTH); | ||
| } catch { | ||
| return undefined; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cookie values can’t safely contain certain separator characters (notably
;,,, and whitespace). Since this now stores the rawexternalReferrerstring, a referrer path containing one of those characters could lead to a truncated/invalid cookie in browsers. Consider ensuring the value is cookie-safe here (e.g. rely on a cookie serializer that encodes, or explicitly encode/sanitize before callingcookies.set).