Skip to content
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

fix: seek subdomain correctly #888

Merged
merged 14 commits into from
Nov 15, 2023
Merged

fix: seek subdomain correctly #888

merged 14 commits into from
Nov 15, 2023

Conversation

pauldambra
Copy link
Member

@pauldambra pauldambra commented Nov 14, 2023

We relied on a regex for detecting subdomain in order to choose what cookie domain to set for PostHog storage.

This worked fine for example.com or www.example.com but it didn't work for example.co.uk or example.com.au because it would grab the first two parts and so try to set on the public suffix co.uk or com.au

A lot of suggested solutions on line involve keeping a list of public suffixes, or making DNS lookups to validate values which wouldn't fit here.

But... browsers reject cookies set on public suffixes - despite not offering an API to directly check if something is a public suffix.

So, we can split the current hostname up and then progressively try to set a cookie until the browser accepts it.

For a.long.domain.someone.is.using.com.au we would check:

  • .au rejected by browser
  • .com.au rejected by browser
  • .using.com.au accepted by browser

We call this method a lot and the browser can't maintain in-memory variables and navigate between sub-domains, so I also cache the result

I manually tested the code in the developer console of firefox, chrome, and safari

@pauldambra pauldambra added the bump patch Bump patch version when this PR gets merged label Nov 14, 2023
Copy link

github-actions bot commented Nov 14, 2023

Size Change: +2.2 kB (0%)

Total Size: 734 kB

Filename Size Change
dist/array.full.js 174 kB +551 B (0%)
dist/array.js 115 kB +550 B (0%)
dist/es.js 115 kB +550 B (0%)
dist/module.js 116 kB +550 B (0%)
ℹ️ View Unchanged
Filename Size
dist/exception-autocapture.js 12 kB
dist/recorder-v2.js 104 kB
dist/recorder.js 58.3 kB
dist/surveys.js 39.8 kB

compressed-size-action

Copy link
Collaborator

@benjackwhite benjackwhite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like something that needs tests.... can we test it or is it so browser specific that we would essentially be mocking out the whole logic?

testcafe/helpers.js Dismissed Show dismissed Hide dismissed
Comment on lines +6 to +20
const mockDocumentDotCookie = {
value_: '',

get cookie() {
return this.value_
},

set cookie(value) {
//needs to refuse known public suffixes, like a browser would
// value arrives like dmn_chk_1699961248575=1;domain=.uk
const domain = value.split('domain=')
if (['.uk', '.com', '.au', '.com.au', '.co.uk'].includes(domain[1])) return
this.value_ += value + ';'
},
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@benjackwhite I couldn't get testcafe to test this. But I was having to attach the function to the window and then have testcafe eval it and who knows why it wasn't working.

Sometimes it wasn't present, others it returned the empty string, I think even sometimes it worked, but it was horrible.

So instead I have a fake cookie jar to test the logic with.

And then in the actual code...

Comment on lines +58 to +64
if (!matchedSubDomain) {
const originalMatch = originalCookieDomainFn(hostname)
if (originalMatch !== matchedSubDomain) {
logger.info('Warning: cookie subdomain discovery mismatch', originalMatch, matchedSubDomain)
}
matchedSubDomain = originalMatch
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... if the new mechanism returns no match we fall back to the original.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other alternative I guess is to let people configure their subdomain.

And if that's present we use it without looking at location. Then folk that it's working for do nothing, everyone else has to configure it. That's yucky but safer

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still somewhat worried about this code but its more of a gut feeling than anything I can actually see wrong with it :D
Let's try it

Comment on lines +58 to +64
if (!matchedSubDomain) {
const originalMatch = originalCookieDomainFn(hostname)
if (originalMatch !== matchedSubDomain) {
logger.info('Warning: cookie subdomain discovery mismatch', originalMatch, matchedSubDomain)
}
matchedSubDomain = originalMatch
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still somewhat worried about this code but its more of a gut feeling than anything I can actually see wrong with it :D
Let's try it

@pauldambra pauldambra merged commit 8b289a3 into master Nov 15, 2023
13 checks passed
@pauldambra pauldambra deleted the fix/subdomain-discovery branch November 15, 2023 08:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bump patch Bump patch version when this PR gets merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants