Opened 5 months ago

Last modified 4 months ago

#30605 new defect

accept-language header leaks browser localization

Reported by: sysrqb Owned by: tbb-team
Priority: High Milestone:
Component: Applications/Tor Browser Version:
Severity: Normal Keywords: tbb-mobile, tbb-parity, user-feedback, blog
Cc: sigil12, dujaus Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description (last modified by sysrqb)

A blog user mentions each request includes the chosen browser language. Do we normalize this on desktop such that we only send en-US regardless of the browser's localization?

Using https://wtfismyip.com/headers

With en-US as the browser locale:

host: wtfismyip.com
connection: close
user-agent: Mozilla/5.0 (Android 6.0; Mobile; rv:60.0) Gecko/20100101 Firefox/60.0
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language: en-US,en;q=0.5
accept-encoding: gzip, deflate, br
upgrade-insecure-requests: 1

With ru-RU as the browser locale:

host: wtfismyip.com
connection: close
user-agent: Mozilla/5.0 (Android 6.0; Mobile; rv:60.0) Gecko/20100101 Firefox/60.0
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language: ru,ru-RU;q=0.8,en-US;q=0.5,en;q=0.3
accept-encoding: gzip, deflate, br
upgrade-insecure-requests: 1

Child Tickets

Change History (8)

comment:1 in reply to:  description Changed 5 months ago by sysrqb

Description: modified (diff)

comment:2 Changed 5 months ago by acat

I think what happens in desktop (with lang other than en-US) is that on first navigation there is the prompt asking whether to spoof to english, if the user accepts then it sets the privacy.spoof_english = 2 pref. Then, the pref listener in toolkit/components/resistfingerprinting/RFPHelper.jsm sets the intl.accept_languages = en-US,en. In Android I don't see privacy.spoof_english pref, and then even if set manually to 2, intl.accept_languages is not changed. I wonder what is failing here... Changing intl.accept_languages = en-US,en manually works, and then the accept-language header is spoofed correctly.

Last edited 5 months ago by acat (previous) (diff)

comment:3 in reply to:  2 ; Changed 5 months ago by sysrqb

Keywords: tbb-mobile added

Replying to acat:

I think what happens in desktop (with lang other than en-US) is that on first navigation there is the prompt asking whether to spoof to english, if the user accepts then it sets the privacy.spoof_english = 2 pref. Then, the pref listener in toolkit/components/resistfingerprinting/RFPHelper.jsm sets the intl.accept_languages = en-US,en. In Android I don't see privacy.spoof_english pref, and then even if set manually to 2, intl.accept_languages is not changed. I wonder what is failing here... Changing intl.accept_languages = en-US,en manually works, and then the accept-language header is spoofed correctly.

Ah, thanks! That sounds like something we want on Android, too. It seems it was only implemented on Desktop (not surprisingly). I wonder what we should do on Android. Maybe we should start with always spoofing the header for now, and implement a better fix later?

comment:4 in reply to:  3 ; Changed 5 months ago by gk

Keywords: tbb-parity added

Replying to sysrqb:

Replying to acat:

I think what happens in desktop (with lang other than en-US) is that on first navigation there is the prompt asking whether to spoof to english, if the user accepts then it sets the privacy.spoof_english = 2 pref. Then, the pref listener in toolkit/components/resistfingerprinting/RFPHelper.jsm sets the intl.accept_languages = en-US,en. In Android I don't see privacy.spoof_english pref, and then even if set manually to 2, intl.accept_languages is not changed. I wonder what is failing here... Changing intl.accept_languages = en-US,en manually works, and then the accept-language header is spoofed correctly.

Ah, thanks! That sounds like something we want on Android, too. It seems it was only implemented on Desktop (not surprisingly). I wonder what we should do on Android. Maybe we should start with always spoofing the header for now, and implement a better fix later?

I am inclined to say "no" as the usability issues are potentially quite severe. There are a bunch of ways to get the browser locale (we still have some open for desktop) even though header spoofing *is* active (see e.g. #30304). So the benefit might not be as expected (this is *not* meant in the sense that we should not fix it because there are other ways to obtain the locale).

comment:5 in reply to:  4 Changed 5 months ago by sysrqb

Replying to gk:

Replying to sysrqb:

[snip]

I wonder what we should do on Android. Maybe we should start with always spoofing the header for now, and implement a better fix later?

I am inclined to say "no" as the usability issues are potentially quite severe. There are a bunch of ways to get the browser locale (we still have some open for desktop) even though header spoofing *is* active (see e.g. #30304). So the benefit might not be as expected (this is *not* meant in the sense that we should not fix it because there are other ways to obtain the locale).

Maybe we should add a warning/notification somewhere? Maybe we should check the current locale when the app starts and show a warning if locale != en-US? It makes me a little uncomfortable that we default to en-US, but I don't have a better answer right now.

From a usability perspective, I agree we should send the correct language header.

Last edited 5 months ago by sysrqb (previous) (diff)

comment:6 Changed 5 months ago by wayward

Keywords: user-feedback blog added

comment:7 Changed 4 months ago by gk

Cc: sigil12 added

#30772 is a duplicate.

comment:8 Changed 4 months ago by gk

Cc: dujaus added
Priority: MediumHigh

#30925 is a duplicate.

Note: See TracTickets for help on using tickets.