Closed Bug 1805101 Opened 2 years ago Closed 2 years ago

Unable to login to sites using kasada.io anti-bot protection (eg twitch.tv and nike.com) if privacy.resistFingerprinting is enabled

Categories

(Core :: Privacy: Anti-Tracking, defect, P3)

Firefox 109
defect

Tracking

()

RESOLVED FIXED
115 Branch
Tracking Status
firefox115 --- fixed

People

(Reporter: code, Assigned: tjr)

References

(Blocks 2 open bugs)

Details

(Whiteboard: [fpp:m3])

Attachments

(13 files, 1 obsolete file)

383 bytes, text/html
Details
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/109.0

Steps to reproduce:

  • Have privacy.resistFingerprinting enabled
  • Visit https://www.twitch.tv/login, refresh the page with network tools open
  • Attempt to login

Actual results:

  • As a precursor step, Twitch will send a POST to https://passport.twitch.tv/integrity. With privacy.resistFingerprinting enabled, the "duration" field on the x-kpsdk-cd header for that request (based on using performance.now() to measure before and after a piece of work) will have rounded down to zero. This is apparently not acceptable and will block with a 400, and the website will display the misleading error message "Your browser is not currently supported. Please use a recommended browser or learn more here.".

Expected results:

When x-kpsdk-cd has a non-zero duration, the POST to https://passport.twitch.tv/integrity will return a 200 with a token used for the next part of the login process as normal.
I'm aware that ruining the timer accuracy is very much an intentional part of privacy.resistFingerprinting, and disabling it is a viable workaround for now. Really this should be on Twitch to fix their API, but I just wanted to document this here given that the site's error message blames the user's choice of browser.
This is based on my reverse-engineering the client-side integrity check code, more information can be found in the thread at https://digipres.club/web/@moralrecordings/109496071241946138

In an added bit of frustration it looks like CloudFront can sometimes cache the 400 response to the integrity check. On a couple of computers I had to change privacy.resistFingerprinting to false, then delete all of the Twitch cookies to force a cache miss, and logging in worked.

The Bugbug bot thinks this bug should belong to the 'Core::Networking' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → Networking
Product: Firefox → Core
Component: Networking → Privacy: Anti-Tracking
Severity: -- → S3
Priority: -- → P3

Very much like youtube's problem in Bug 1756970....

See Also: → 1803976, 1756970

The x-kpsdk-cd request header is reportedly used by Kasada anti-bot protection, so multiple sites will be affected including nike.com (mentioned in Bug 1621729 Comment 18).

Bug 1811567 removed some performance API restrictions but login still fails with duration value of 0 or 16.667.

Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: Unable to login to twitch.tv if privacy.resistFingerprinting is enabled → Unable to login to sites using kasada.io anti-bot protection (eg twitch.tv and nike.com) if privacy.resistFingerprinting is enabled

but login still fails

is this a false positive and the real reason is the OS header !== the JS navigator when on linux/mac? Or does this still happen on windows? We should close that anyway for Firefox RFP and put it behind a flag for Tor Browser

twitch.tv login works on Windows with RFP (including before Bug 1811567) but not on Linux (even with UA changed to Linux).

nike.com login fails on both Windows and Linux with RFP and the following loosened settings:

privacy.resistFingerprinting = true	
privacy.resistFingerprinting.autoDeclineNoUserInputCanvasPrompts = false	
privacy.resistFingerprinting.exemptedDomains = *.nike.com	
privacy.resistFingerprinting.randomDataOnCanvasExtract = false	
privacy.resistFingerprinting.reduceTimerPrecision.jitter = false	
privacy.resistFingerprinting.reduceTimerPrecision.microseconds = 1	
privacy.resistFingerprinting.testGranularityMask = 4
general.useragent.override = Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0

Kasada uses VM obfuscation.

with RFP and the following loosened settings ... general.useragent.override

general.useragent.override is ignored when RFP is enabled - just saying. You would need to use an extension to change any JS / HTTP header to test it ... or wait for RFP granularity

All the settings were used together and general.useragent.override does work for the HTTP header and navigator with an RFP domain exemption. It indicates the problem lies with features that have not yet been migrated to finer granularity control.

Without the RFP domain exemption, I used the extension User Agent Switcher to change UA.

It looks like it will be possible to toggle individual features with privacy.resistFingerprintingLite.overrides in the future which will be helpful for troubleshooting sites like this.

Thanks for the update. We actually seem to have a bug that causes us to not apply the resist fingerprinting exemption in this case.

Assignee: nobody → tschuster

The problem comes down to Document::RecomputeResistFingerprinting(), which uses the mChannel for calculating the resist fingerprinting state. However the fingerprinting script on nike.com seems to create an about:blank iframe, where the channel is never non-null. I am going to attach a test case that shows this problem.

I think the only way to fix this is to use the NodePrincipal() and nsContentUtils::ShouldResistFingerprinting_dangerous. We can then call RecomputeResistFingerprinting at the end of Document::SetPrincipals.

Attachment #9325201 - Attachment description: WIP: Bug 1805101 → Bug 1805101 - Document::RecomputeResistFingerprinting should work with null mChannel. r?emilio!,tjr!

I've attached a test that extends your test - this one will fail tests A/B with the current version of central, which is what this bug is about - RFP isn't being exempted correctly when it should be.

With the current version of your patch, it fails on tests G/H, which is the cookiejarsettings preventing an exempted subframe from being exempted when the framer is non-exempted.

Attachment #9325201 - Attachment is obsolete: true
Whiteboard: [fpp:m?]
Assignee: tschuster → tom
See Also: → 1830070
Attachment #9328653 - Attachment description: Bug 1805101: Populate the ShouldRFP bit on an about:blank document from its parent r?smaug → WIP: Bug 1805101: If there _is_ a parent document, refer to it to determine if RFP should be exempted
Attachment #9328653 - Attachment description: WIP: Bug 1805101: If there _is_ a parent document, refer to it to determine if RFP should be exempted → Bug 1805101: If there _is_ a parent document, refer to it to determine if RFP should be exempted r?smaug

This is a dead-simple test that will run quickly and
be easily debuggable (via printf debugging).

Depends on D177087

Depends on D177088

Depends on D177089

Depends on D177090

Depends on D177091

Attachment #9331454 - Attachment description: Bug 1805101: Correct the event comparison in multiple RFP tests r?tschuster → Bug 1805101: Improve the event comparison in multiple RFP tests r?tschuster

This may not be possible.

Depends on D177193

Attachment #9331867 - Attachment description: WIP: Bug 1805101: Add a test for passing a blob cross-origin WIP → Bug 1805101: Add a test for a blob framed by a cross-origin document r?tschuster
Pushed by tritter@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/f79b0f21590a If there _is_ a parent document, refer to it to determine if RFP should be exempted r=smaug,emilio https://hg.mozilla.org/integration/autoland/rev/f78e24f7106d Add a RFP test that runs in an about:blank document r=tschuster https://hg.mozilla.org/integration/autoland/rev/e8c61d54bf1a Improve the event comparison in multiple RFP tests r=tschuster https://hg.mozilla.org/integration/autoland/rev/8bdd7a866d06 Improve the postMessage data object that is passed r=tschuster https://hg.mozilla.org/integration/autoland/rev/ff9f6f1fecc0 Replace JSON stringify with StructredClone and partial with Function.bind r=tschuster https://hg.mozilla.org/integration/autoland/rev/f79a9b025f85 Clarify the purpose of the cross-origin domain, and don't pass them everywhere r=tschuster https://hg.mozilla.org/integration/autoland/rev/0aab7f02e865 Add a hwconcurrency test that doesn't use about:blank r=tschuster https://hg.mozilla.org/integration/autoland/rev/3523dc5f0da4 Add a test for blob: documents r=tschuster https://hg.mozilla.org/integration/autoland/rev/6dd60d08cb1a Add a test for about:srcdoc r=tschuster https://hg.mozilla.org/integration/autoland/rev/c060ab2847e2 Add a test with a sandboxed iframe r=tschuster https://hg.mozilla.org/integration/autoland/rev/acb86e6b9a72 Add a test for data: documents r=tschuster https://hg.mozilla.org/integration/autoland/rev/a7fad82e97d9 Add a test for a blob framed by a cross-origin document r=tschuster
Duplicate of this bug: 1811505
Whiteboard: [fpp:m?] → [fpp:m4]
Whiteboard: [fpp:m4] → [fpp:m3]
Depends on: 1835987
QA Whiteboard: [qa-115b-p2]
Depends on: 1840385
No longer depends on: 1835987, 1840385
See Also: → 1835987, 1840385
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: