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

create screen test and capture css media fingerprint #97

Open
5 tasks done
abrahamjuliot opened this issue Dec 5, 2020 · 17 comments
Open
5 tasks done

create screen test and capture css media fingerprint #97

abrahamjuliot opened this issue Dec 5, 2020 · 17 comments
Labels
enhancement New feature or request

Comments

@abrahamjuliot
Copy link
Owner

abrahamjuliot commented Dec 5, 2020

https://developer.mozilla.org/en-US/docs/Web/CSS/@media

matchMedia(`(min-device-height:${screen.height}px)`).matches
matchMedia(`(min-device-width:${screen.width}px)`).matches
matchMedia(`(max-device-height:${screen.height}px)`).matches
matchMedia(`(max-device-width:${screen.width}px)`).matches
matchMedia(`(device-height:${screen.height}px)`).matches
matchMedia(`(device-width:${screen.width}px)`).matches
@abrahamjuliot abrahamjuliot added the enhancement New feature or request label Dec 5, 2020
@abrahamjuliot abrahamjuliot changed the title expand screen fingreprint create screen test Jan 3, 2021
abrahamjuliot added a commit that referenced this issue Jan 3, 2021
abrahamjuliot added a commit that referenced this issue Jan 4, 2021
@abrahamjuliot abrahamjuliot changed the title create screen test create screen test and capture css media fingerprint Jan 4, 2021
abrahamjuliot added a commit that referenced this issue Jan 4, 2021
@Thorin-Oakenpants
Copy link

https://abrahamjuliot.github.io/creepjs/tests/screen.html

orientation and viewport are undefined - FF nightly 86, and yes my inner is square :)

undefined

tzp has a scrollbar hence viewport is not 1000x1000
tzp

@abrahamjuliot abrahamjuliot reopened this Jan 10, 2021
@Thorin-Oakenpants
Copy link

https://jsfiddle.net/873kspn4/1/

FF nightly 86 RFP off = prefersColorScheme: "", prefersReducedMotion: ""
FF nightly 86 RFP on = prefersColorScheme: "", prefersReducedMotion: "no-preference"

What does import gain over just a straight css (besides the fact that JS can read it quickly)

@abrahamjuliot
Copy link
Owner Author

viewport

I'm now discovering, FF has visualViewport behind the flag dom.visualviewport.enabled. This should now yield the unsupported label if both dimensions are undefined.

orientation

Oops, that's a bug I left in there. Fixed.

@import

@media and @import are pretty much the same. I might add this later to test if Chromium's proposed privacy budget covers both and matchMedia.

@Thorin-Oakenpants
Copy link

https://bugzilla.mozilla.org/show_bug.cgi?id=1579584#c5 and subsequent comments

I've been letting android tests lapse. Anyway, if I read that right, then we can detect if dynamic toolbar is enabled? I should make a test: i.e if enabled 100vh - inner = toolbar height ... if disabled 100vh - inner = zero

wanna test that for me?

@Thorin-Oakenpants
Copy link

I do not know what you mean by @media and by MediaQueryList. What is the difference? Which one is @matchmedia if any?

I have questions. Using Firefox Nightly on Android. RFP off on the left, RFP on on the right

screen test

  • Both
    • why the fake screen returns
    • why is the height different in visualViewport
      • note: how are you getting this. In TZP we use a binary search in matchmedia to get subpixels (decimals) for measurements (screen, inner etc) which show up when the devicePixelRatio != 1 = almost always on android = entropy galore!!
  • RFP on
    • why undefined for heights
    • why is aspect ratio fake? in TZP with RFP on this is all portrait (all 8 values). What are you using to calculate 16/9 or 6/13 etc
    • FWIW I don't think it's worthwhile returning e.g. 16/9 when that entropy is already in the width + height measurements: but maybe you're trying to catch something out here, like an extension lie? Please explain yourself young man, or you won't get any pudding.

screen


creepy test

  • green boxes on RFP=on

creepy

@abrahamjuliot
Copy link
Owner Author

100vh - inner = toolbar height ... if disabled 100vh - inner = zero

This seems the same as obtaining 100vh and inner (the difference is only unspoken). I'm not sure how 100vh were obtained to verify this, but document.documentElement.clientHeight should match window.innerHeight. I don't have a dynamic tooldbar (?) on my devices.

 const hasToolbar = !!(document.documentElement.clientHeight - window.innerHeight)

@abrahamjuliot
Copy link
Owner Author

MediaQueryList and matchMedia are the same. MediaQueryList is the object returned.

@Thorin-Oakenpants
Copy link

I don't have a dynamic toolbar

Android > Firefox > Settings > General > Customize > Scroll to hide toolbar (default = on)

@abrahamjuliot
Copy link
Owner Author

screen test

  • fake screen: if a result is undefined, the screen is presumed fake. I added the output and limited the fake test to screen (the test just compares screen with matchMedia). I'm realizing this returns a false positive if the matchMedia only matches a float, but I've only noticed this in an android emulator (I presume it's the same in a virtual machine) and in those context, the screen size is technically fake. Are you getting a fake screen on an actual android device?
  • visualViewport: this returns a float height on FF Android. I'm now using Math.round in the template output, but the floating point might provide some entropy in a fingerprint.
const vViewport = 'visualViewport' in window ? visualViewport : { }
const { width: viewportWidth, height: viewportHeight } = vViewport
console.log(`${Math.round(viewportWidth)} x ${Math.round(viewportHeight)}`)
  • undefined heights/aspect ratio: since I'm searching for an integer (up to 10000px), if there is no match it's undefined.
  • 16/9 aspect ratio: this is really not that useful since width height reveals the same (aspect-ratio is only unspoken)
// gcd is based on https://stackoverflow.com/a/1186465
const gcd = (a, b) => b == 0 ? a : gcd(b, a%b)
const { innerWidth, innerHeight } = window
const { width: screenWidth, height: screenHeight } = screen
const ratio = gcd(innerWidth, innerHeight)
const screenRatio = gcd(screenWidth, screenHeight)
const aspectRatio = `${innerWidth/ratio}/${innerHeight/ratio}`
const deviceAspectRatio = `${screenWidth/screenRatio}/${screenHeight/screenRatio}`
/*css*/
@media (aspect-ratio: ${aspectRatio}) {
	body {--viewport-aspect-ratio: ${aspectRatio};}
}
@media (device-aspect-ratio: ${deviceAspectRatio}) {
	body {--device-aspect-ratio: ${deviceAspectRatio};}
}

@abrahamjuliot
Copy link
Owner Author

dynamic toolbar

I'm not sure there is practical method to detect this since the toolbar is only hidden when/if the user scrolls.

@abrahamjuliot
Copy link
Owner Author

creepy test

I use an iframe for the screen metrics on creep, and as far as I know RFP restricts screen metrics in iframes.

@Thorin-Oakenpants
Copy link

Thorin-Oakenpants commented Jan 11, 2021

what are you using for getting vunits?

function get_vunits() {
	let div, vh1, vw1
	div = document.createElement("vunits")
	div.style.height = "100vh"
	div.style.width = "100vw"
	div.style.maxHeight = "none"
	div.style.boxSizing = "content-box"
	document.body.appendChild(div)
	vw1 = div.clientWidth
	vh1 = div.clientHeight
	document.body.removeChild(div)
	console.log(vw1 +" x "+ vh1) // I get 0x0 .. approx 2ms

	function vh(v) {
		let h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
		return (v * h) / 100;
	}
	function vw(v) {
		let w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
		return (v * w) / 100;
	}
	function vmin(v) {
		return Math.min(vh(v), vw(v));
	}
	function vmax(v) {
		return Math.max(vh(v), vw(v));
	}
	console.log(vw(100), Math.max(document.documentElement.clientWidth, window.innerWidth || 0));
	console.log(vh(100), Math.max(document.documentElement.clientHeight, window.innerHeight || 0));
	console.log(vmin(100));
	console.log(vmax(100)); // approx 1 or 2 ms
}

@Thorin-Oakenpants
Copy link

Thorin-Oakenpants commented Jan 11, 2021

Are you getting a fake screen on an actual android device

Yes. The screen shots are from my realsies android

but the floating point might provide some entropy in a fingerprint

entropy is good: we get this (decimals) on TZP when devicePixelRatio is not 1. Just wondering why the value changed

edit: there is also this: https://devicepixelratio.glitch.me/

PS: I have been looking at expanding other measuring methods in the screen section for some time

  • v units was one on my list
  • visualViewport was also noted (and there's a change in FF coming to allow subpixel measurements: not sure if VViewport or just inner etc)
  • I wanted to look at that glitchme code
  • now you've listed
    • import
    • computedStyle
    • @media (I'm still not sure what that means)
    • matchMedia object
    • using an iframe
  • I also already have an element that is set to 100 width/height that I use for when you do the FS test

Would be nice to list get all this into TZP

@abrahamjuliot
Copy link
Owner Author

abrahamjuliot commented Jan 11, 2021

vh units

I use document.documentElement.clientHeight. It's the same as above. Where v is 100 and h is clientHeight, (v * h) / 100 yields the same result as h

@abrahamjuliot
Copy link
Owner Author

TZP when devicePixelRatio is not 1

That's sounds awesome. I'll take a look and try it out.

abrahamjuliot added a commit that referenced this issue Jan 11, 2021
@Thorin-Oakenpants
Copy link

Thorin-Oakenpants commented Jan 11, 2021

^^ big edit 3 posts up :)

edit: and intersection observer which I have a poc lying around

@Thorin-Oakenpants
Copy link

Thorin-Oakenpants commented Jan 11, 2021

TZP when devicePixelRatio is not 1

That's sounds awesome. I'll take a look and try it out.

the decimal places happen because of the real devicePixelRatio, not because I factor in the reported dPR

Here is my realsies android with RFP on

  • it hides dPR as 1, in reality it is 2.60.. something. Note my PoC that exposes an almost real value
  • I am not using that dPR PoC at all, but note the two matchMedia min height results have decimal places - revealing entropy and the existence of subpixels
    tzp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants