Closed Bug 1546832 Opened 7 months ago Closed 6 months ago

Opening/Resizing developer tools causes incorrect content letterboxing

Categories

(Core :: Window Management, defect, P5)

x86_64
Linux
defect

Tracking

()

RESOLVED FIXED
mozilla69
Tracking Status
firefox69 --- fixed

People

(Reporter: johnp, Assigned: tjr)

References

Details

Attachments

(5 files, 1 obsolete file)

Opening/Resizing the developer tools with privacy.resistFingerprinting.letterboxing results in pixel-by-pixel window.innerHeight changes with no margin resizing. The same issue occurs when opening the find bar (not sure if that's a separate bug). The content should behave the same as when resizing the sidebar, optimally allowing pixel-perfect encasement of the content at the top right by adjusting sidebar and developer tools sizes.

findbar is a per tab, while the letterboxing is applied globally to all tabs per "window", so I'm not sure what the answer for that is: eventually one day make the findbar into an overlay?

Devtools, can reproduce Johannes results, but only with docked dev tools at the bottom, using [1] with real time css @media resolution info (just use a reasonable window size as the css range is from 500-3000)

  • e.g letterbox opened at 1200x800, shift-f9 docked bottom, result in my case is 1200x552
  • tested the reverse, started with a privileged page, dev tools docked bottom, loaded page, 1200x552

when docked left or right it seems to be already covered

  • e.g letterbox opened at 1200x800, shift-f9 docked right, result in my case is 1000x800`
  • tested the reverse, started with a privileged page, dev tools docked side, loaded page, 1000x800

[1] https://ghacksuserjs.github.io/TorZillaPrint/TorZillaPrint.html#screen

I believe the problem is that these events are not triggering a resize event, so the letterboxing update is not issued. We should identify these events and handle them here: https://searchfox.org/mozilla-central/source/browser/components/BrowserGlue.jsm#245

Priority: -- → P5

ni? to investigate resize issues with devtools

Flags: needinfo?(jdescottes)

An alert() on load can also bypass letterboxing.

Steps to reproduce:

  • open a small window
  • navigate to a site that calls alert() early/on load
  • resize window
  • the website will not be letterboxed and will see the real resolution
  • confirm/cancel alert
  • the website will become letterboxed

simple test page:
<script>alert("test")</script>

does the job, confirmed running on a web server as well, not just file:///
tested on version 67.0

and I'm sure it is known but TorZillaPrint's 'new window' trick also gets the real resolution.

if you visit this [1] and resize the window you can see all intermediate by 1x pixel sizes until it resets to letterboxing size,
ie. javascript can see you resizing

[1] https://www.whatismybrowser.com/detect/how-big-is-my-web-browser

Thanks for these comments! I am very glad people are poking at this and trying to break it!!!

I think that this behavior is okay, if I understand it correctly. The goal of letterboxing is to hide per-pixel differences in users' resolutions that stem from their font size, taskbar/dock size, toolbars size, etc. If you resize the window, and javascript can observe intermediate values (like 1200-> 1201 -> 1202 -> 1200) you aren't revealing anything other than that the user was resizing the window, and I suppose how fast they were dragging their mouse to do it.

If one could figure out a way to obtain the original resolution before letterboxing is applied the first time - that would be a break of the feature and reveal what we are trying to hide. But these examples, and in particular these steps:

(In reply to Tad from comment #5)

Steps to reproduce:

  • open a small window
  • navigate to a site that calls alert() early/on load
  • resize window
  • the website will not be letterboxed and will see the real resolution

Make me believe we are not revealing the original resolution, but are instead revealing some extra pixels the user has given the window by resizing it (before letterboxing might reclaim those pixels.)

Flags: needinfo?(jdescottes)

I thought Tad in Comment 5 was referring to something completely different, which would in fact reveal real resolution. But I'm not proficient enough to be able to reproduce his example, I tried:

<script>alert("test " + window.innerHeight+" " + window.innerWidth+ " " +screen.width+" " + screen.availWidth)</script>

in /tmp/index.html but that just shows my letterboxing values, perhaps because I'm doing it wrong?!

I even tried saving that page that I linked above and put the above alert in the Google Analytics section of script, loaded it as file:///tmp/How big is my web browser%3F - WhatIsMyBrowser.com.html but no dice. Still seeing my letterboxing values. Again, maybe I'm doing it wrong... but if not, then letterboxing seems to be doing its job.

Additionally, if you disable privacy.resistFingerprinting, and click the new window test, that too leaks. It's just the RFP controls "new window" sizes, so is mitigated. Tor Browser also mitigates this by making new windows open as new tabs, and also returns 10x10 as a clamp

Attached file vendor.js

uuu, the new window test leaked real window resolution(eg. [ i ] new window 1265 x 1111 [outer] 1265 x 1111 [inner]) even though it only opened an about:blank in a new tab! and I have privacy.resistFingerprinting=true ! (yes, really)

The full screen test required [api] full screen enabled (ie. about:config full-screen-api.enabled=true(which is the default, I believe)) and it leaked full screen real size! (yes, I still have privacy.resistFingerprinting true)

But if I set privacy.resistFingerprinting=false then every reported resolution is the real one except:
inner window
[ i ] [css] inner window 1, 2
viewport 3
and the one that /only shows the real resolution when refreshing the page/ : [ i ] [css] screen resolution 1 otherwise via just clicking [ re-run tests ] it shows letter-boxing resolution.

Thanks Simon. Looks like letterboxing can be bypassed!

tested with mozilla-central commit:
changeset: 474872:267ddc3595fe
tag: tip
date: Wed May 22 02:47:22 2019 +0200
summary: Bug 1553227 - followup: fix animation-type-longhand.js.

I'm attaching vendor.js where I've set all about:config settings... in case anyone is wondering if some other setting is set or not that might be causing the new window test to reveal real resolution.

In addition, all modified preferences(I patched) minus some obvious ones related to timestamps, are the following:

All Modified Preferences
Name 	Value 
app.normandy.first_run	false
browser.bookmarks.editDialog.confirmationHintShowCount	6
browser.cache.disk.amount_written	250
browser.contentblocking.category	strict
browser.display.background_color	#000000
browser.display.document_color_use	1
browser.display.foreground_color	#ffffff
browser.download.lastDir	/tmp
browser.download.save_converter_index	0
browser.migration.version	82
browser.newtabpage.storageVersion	1
browser.pageActions.persistedActions	{"ids":["bookmark","pinTab","bookmarkSeparator","copyURL","emailLink","addSearchEngine"],"idsInUrlbar":["bookmark"],"ver
browser.pagethumbnails.storage_version	3
browser.sessionstore.upgradeBackup.latestBuildID	20190522102016
browser.startup.lastColdStartupCheck	1558612020
browser.uiCustomization.state	{"currentVersion":16,"dirtyAreaCache":["nav-bar","toolbar-menubar","TabsToolbar","PersonalToolbar"],"newElementCount":2,
browser.urlbar.placeholderName	Searx
devtools.toolbox.selectedTool	inspector
devtools.toolsidebar-width.inspector	416
distribution.iniFile.exists.appversion	69.0a1
distribution.iniFile.exists.value	false
extensions.activeThemeID	firefox-compact-dark@mozilla.org
extensions.blocklist.pingCountVersion	-1
extensions.databaseSchema	31
extensions.incognito.migrated	true
extensions.lastAppBuildId	20190522102016
extensions.lastAppVersion	69.0a1
extensions.lastPlatformVersion	69.0a1
extensions.pendingOperations	false
extensions.systemAddonSet	{"addons":{},"schema":1}
extensions.webextensions.ExtensionStorageIDB.migrated.https-everywhere@eff.org	true
extensions.webextensions.ExtensionStorageIDB.migrated.uBlock0@raymondhill.net	true
extensions.webextensions.ExtensionStorageIDB.migrated.uMatrix@raymondhill.net	true
extensions.webextensions.uuids	{"amazondotcom@search.mozilla.org":"f5edafcf-a08c-4a5f-b5a4-4e38ddd1a38f","bing@search.mozilla.org":"93fcee8c-33f5-46d5-
media.gmp-manager.buildID	20190522102016
media.gmp-manager.lastCheck	1558611253
media.gmp.storage.version.observed	1
pdfjs.enabledCache.state	false
places.history.expiration.transient_current_max_pages	58141
pref.privacy.disable_button.cookie_exceptions	false
privacy.sanitize.pending	[{"id":"newtab-container","itemsToClear":[],"options":{}}]
security.sandbox.content.tempDirSuffix	09b29504-2e3d-4ab6-b349-fe6815862992
security.sandbox.plugin.tempDirSuffix	34431f13-b700-4741-b75a-8b41b83ecafb
signon.importedFromSqlite	true
storage.vacuum.last.index	1

Make me believe we are not revealing the original resolution, but are instead revealing some extra pixels the user has given the window by resizing it (before letterboxing might reclaim those pixels.)

I have tweaked TorZillaPrint to open an alert on load, and another that can be clicked to open.

With letterboxing disabled, and the window maximized, I get 1920x1018 as the screen resolution for all values.

With letterboxing enabled, on load in a new window, I get 1000x900 for most values, and 988x900 for the viewport.
Any resizes with letterboxing enabled properly snap up to the next size, but briefly show the intermediate values.

But, with an alert open letterboxing will not start or update.
While an alert is open I can maximize the window, and it will show 1920x1018.
As in a new window that hadn't been letterbox won't have any letterboxing when maximized.
And a window that had been letterboxed won't snap up to the next size.

Test it here: https://skewedzeppelin.github.io/TorZillaPrint/TorZillaPrint.html

Confirmed, thanks Tad!
ie. when I see popup resizes now while this popup is shouldn't be letterboxed
the following two report some form of real (inner)window size:
[css] screen resolution
[css] inner window

Apparently, after every 1 minute the (inner)window snaps back to its letterboxing size. (while that popup is active)

So I guess fixing but briefly show the intermediate values would also fix this one.

Would you be able to share what systems you're using?

On OSX, with resistFingerprinting disabled:

https://ghacksuserjs.github.io/TorZillaPrint/TorZillaPrint.html#screen 's new window test shows the original values and is a bypass. (With RFP enabled it restricts the popup size and thus doesn't work.)

However when I load https://skewedzeppelin.github.io/TorZillaPrint/TorZillaPrint.html (and it shows the alert) the values I see behind the alert are the letterboxed values.

The [test] pause on https://skewedzeppelin.github.io/TorZillaPrint/TorZillaPrint.html does show the intermediate values while I resize. (But I'm not overly concerned about that.)

(In reply to howaboutsynergy from comment #11)

uuu, the new window test leaked real window resolution(eg. [ i ] new window 1265 x 1111 [outer] 1265 x 1111 [inner]) even though it only opened an about:blank in a new tab! and I have privacy.resistFingerprinting=true ! (yes, really)

This I can't reproduce - what OS are you on?

This I can't reproduce - what OS are you on?
I'm on Arch Linux. Perhaps the other settings in vendor.js are having an effect.

Let me try with pristine firefox from upstream (ie. sudo pacman -S firefox)

Package (3)            Old Version               New Version  Net Change    Download Size

firefox-hg             r474872+.267ddc3595fe+-1               -1350.06 MiB               
extra/ mozilla-common                            1.4-5            0.00 MiB       0.00 MiB
extra/ firefox                                   67.0-1         180.32 MiB      46.91 MiB

and an new empty profile!

Ah, in order to reproduce this you have to have:
browser.link.open_newwindow.restriction=0
(instead of 2 which is default)
this will open the new window in a new tab instead.
also:
privacy.resistFingerprinting.letterboxing=true
privacy.resistFingerprinting.letterboxing.dimensions=1300x1000
(^ for example)
privacy.resistFingerprinting=true

RFP=true, LB (letterboxing) = true, open test page, click new window: you are restricted to 1000x1000 (as an example), it's an about:blank page so no content is loaded, and no LBing takes place. Change the page loaded to something with content, e.g var newWin = window.open("extra.html","","width=9000,height=9000"); - the new window RFP protects you.

*But ... STR:

  • RFP=true, LB=true
  • Restrict the new window=> new tab
    • user_pref("browser.link.open_newwindow", 3); // (default)
    • user_pref("browser.link.open_newwindow.restriction", 0); // default is 2
  • resize your window so you can see some LBing <-- important
  • load test page and click new window
  • the code executes before LBing and can reveal your unique resized chrome's inner window

Will attach an image where my inner is unique, but my viewport is controlled (200sx100s), and the resulting leak (the new page shouldn't be about:blank: it needs to execute JS)

Attached image LB-newWin.png

Recommend we clamp the output, like TB, but to return the current LB dimensions

Attached image LB-newWin-TB.png

The last attachment upload seems corrupted, here it is again

Attachment #9067204 - Attachment is obsolete: true

I've updated the TZP test to load a wee html file on the new window test so you can replicate without fluffing around

I'm going to land this patch and this weekend or next weekend catch up on and open a new bug about the other things we've been discussing.

Keywords: checkin-needed

Pushed by csabou@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/f712de0c8a7c
Adjust letterboxing to take the FindBar and Devtools into account r=johannh

Keywords: checkin-needed
Status: NEW → RESOLVED
Closed: 6 months ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla69

I've decided to disable letterboxing completely(privacy.resistFingerprinting.letterboxing=false), because opening Findbar and/or devtools causes shrinkage of the inner window to some of the previous letterboxing states from privacy.resistFingerprinting.letterboxing.dimensions, and for me that's the last straw... it's too much of a headache to have it enabled and ensure it doesn't bother me in all kinds of ways that having it disabled wouldn't.

QA Whiteboard: [qa-69b-p2]
You need to log in before you can comment on or make changes to this bug.