Repository: fingerprintjs/fingerprintjs

Issue #493: hasLiedOs is unreliable and can be easily improved
Created: 2019-12-02T13:03:31Z
hasLiedOs is misdetecting the OS for many User-Agents because of the simplistic way it is detecting Windows and Macintosh. This is the relevant code:
if (userAgent.indexOf('windows phone') >= 0) {
  os = 'Windows Phone'
} else if (userAgent.indexOf('win') >= 0) {
  os = 'Windows'
} else if (userAgent.indexOf('android') >= 0) {
  os = 'Android'
} else if (userAgent.indexOf('linux') >= 0 || userAgent.indexOf('cros') >= 0) {
  os = 'Linux'
} else if (userAgent.indexOf('iphone') >= 0 || userAgent.indexOf('ipad') >= 0) {
  os = 'iOS'
} else if (userAgent.indexOf('mac') >= 0) {
  os = 'Mac'
} else {
  os = 'Other'
}

Thus, any User-Agent with a "win" lowercase substring would be detected as Windows, and any User-Agent with "mac" would be detected as Macintosh. These substrings are too short (only three characters long) and it is fairly for other User-Agents to contain them. This is especially prevalent in mobile device User-Agents, for which the device brand, model, build, etc. a usually part of the string.
The solution is making the substring matches more specific. The following code fixes these shortcoming, avoiding most false-positive "hasLiedOs" results:
if (userAgent.indexOf('windows phone') >= 0) {
  os = 'Windows Phone'
} else if (userAgent.indexOf('windows') >= 0 || userAgent.indexOf('win16') >= 0 || userAgent.indexOf('win32') >= 0 || userAgent.indexOf('win64') >= 0 || userAgent.indexOf('win95') >= 0 || userAgent.indexOf('win98') >= 0 || userAgent.indexOf('winnt') >= 0 || userAgent.indexOf('wow64') >= 0) {
  os = 'Windows'
} else if (userAgent.indexOf('android') >= 0) {
  os = 'Android'
} else if (userAgent.indexOf('linux') >= 0 || userAgent.indexOf('cros') >= 0 || userAgent.indexOf('x11') >= 0) {
  os = 'Linux'
} else if (userAgent.indexOf('iphone') >= 0 || userAgent.indexOf('ipad') >= 0 || userAgent.indexOf('ipod') >= 0 || userAgent.indexOf('crios') >= 0 || userAgent.indexOf('fxios') >= 0) {
  os = 'iOS'
} else if (userAgent.indexOf('macintosh') >= 0 || userAgent.indexOf('mac_powerpc)') >= 0) {
  os = 'Mac'
} else {
  os = 'Other'
}

Furthermore, Chrome OS is usually touch-enabled, but currently hasLiedOs returns true for any touch-enabled User-Agent which is not iOS, Android or Windows Phone. This has already been reported at #247
At least for Chrome OS, this could be fixed by replacing:
if (mobileDevice && os !== 'Windows Phone' && os !== 'Android' && os !== 'iOS' && os !== 'Other') {
  return true
}

with:
if (mobileDevice && os !== 'Windows Phone' && os !== 'Android' && os !== 'iOS' && os !== 'Other' && userAgent.indexOf('cros') === -1) {
  return true
}

Duplicate issue #396: has lied OS & has lied resolution accuracy 
Created: 2018-10-15T15:48:17Z
We have been recording fingerprints using fingerprintjs2 for nearly 10 months now across tons of unique users a month. In that time, we've realized that fingerprints can overlap and that has lied OS/has lied resolution may not be very accurate. We see this on some users, dig deep, and simply don't see any other signs of faking OS or resolution. In some cases, we ban those users only to have them reach out and verify they are in fact real.
I know there is one bug where touch screen laptops are considered lying about the OS, and we're fixing that. But, is there any other considerations with either? We're trying to get this data to a point that it's more actionable/less false positives.
Thanks!

Closing comment (2019-12-02T13:04:41Z): Related to #493 and #247