Fraud detection: how to detect if a user lied about its OS and infer its real OS?
In the context of fraud detection, you may want to detect
the user's OS, e.g. to know whether or not the user pays with its credit card from a known device. The
usual way to obtain the user OS is to parse the user agent or the client hints HTTP header. However, when it
comes to fraud detection, you can't always assume the user agent has been left untouched. Fraudsters use different
kinds of anti-detect browsers and browser extensions that may lie about the user agent, including the
OS.
In this article, we present different techniques that can be used to detect whether or not a user
lied about its OS and user agent, and try to infer the real OS even when the user agent has been
modified.
Before we go through the advanced techniques to infer the real user OS, let’s see how we can
extract the OS from HTTP headers, in the case where the user didn’t forge them:
The simple way: detecting the OS using the
user-agent
and sec-ch-ua-platform
HTTP headers
The user agent is an HTTP header that provides information
about the user’s browser, OS, and version. For example, a user using Chrome 125 on MacOS may have the
following
user-agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36
while a user on Mobile Safari on IOS may have the following user agent
Mozilla/5.0 (iPhone; CPU iPhone OS 17_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1
In these user agents, we can identify the type of browser, the OS, and their versions. However, user agents are not standardized and may be challenging to parse. I recommend you use existing libraries such as UAParser.js and Python user agents to parse them.
Another more recent HTTP header that can be used to infer
the user OS is sec-ch-ua-platform
. It may have some of the following values:
"macOS"
"Android"
"Linux"
"Windows"
If you want a more exhaustive and up-to-date list of
possible values for the sec-ch-ua-platform
, you can look at this
page, which is frequently updated. Note that as of June 2024, only Chromium-based browsers send this
HTTP header.
Inferring the OS the hard way: using JavaScript APIs
In the context of fraud detection, you may want to verify the nature of the OS claimed in the user-agent by leveraging other signals collected using JavaScript.
navigator.userAgentData.platform
provides
information about the device platform, e.g. macOS
. You can combine it with
userAgentData.getHighEntropyValues(...).platformVersion
to obtain more information about the
platform version.
Similarly, you can leverage
navigator.platform
. The value is slightly different than the one returned by
navigator.userAgentData.platform
, but it should be consistent/correlated with it. You can find
a list of the possible values of the navigator.platform
attribute on this page.
Inferring the OS through observable side effects
While the previous APIs explicitly returned information
about the OS, keep in mind that they may also be overridden by malicious actors. Thus, you may want to
verify the OS claimed by these APIs by leveraging other APIs whose values are correlated with the OS. For
example, we can use attributes related to the screen resolution, such as
screen.width/height
and screen.availWidth/height
. Certain screen resolutions are
incompatible with certain OS, e.g. an iPhone with a screen resolution as big as a connected TV. Depending on
the OS, you may be able to detect the presence of the toolbar and certain native UI elements specific to
this OS or to a family of devices like an iPhone.
GPU-related attributes: APIs related to the GPU often leak information about the underlying OS and can be used to verify the authenticity of the OS claimed in the user agent. Indeed, certain GPU models are only available on certain types of devices. Moreover, some of these APIs leak information about the OS. You can obtain information about the device GPU using the WebGL and the WebGPU APIs.
- With WebGL, you can collect information about the GPU vendor and renderer
using
UNMASKED_VENDOR_WEBGL
andUNMASKED_RENDERER_WEBGL
. On a Mac M2 with Chrome, you may have the following GPU vendorGoogle Inc. (Apple)
and the following GPU rendererANGLE (Apple, ANGLE Metal Renderer: Apple M2 Pro, Unspecified Version)
which indicates the user is on a Mac M2.
- With the WebGPU API
GPUAdapterInfo.requestAdapterInfo()
, you can also obtain information about the user GPU model. On Mac OS it may look as follows{"vendor":"apple","architecture":"common-3","device":"","description":""}
. On Android, you may see a GPU linked to Qualcomm with an Adreno architecture:
{
"vendor": "qualcomm",
"architecture": "adreno-6xx",
"device": "",
"description": ""
}
Canvas fingerprinting challenges, in particular those that include emojis can be used to infer the user OS. Indeed, graphics rendering, and specifically emojis rendering depends on the OS. The three canvas challenges below come from different devices on different OSes. We observe significant differences in the rendering of the emojis. Thus, you can build a database that maps certain canvas values to a given OS.
Font enumeration: Finally, you can also leverage font enumeration to infer the presence and absence of fonts. By testing key fonts that are linked to specific OS, you may be able to infer the true user OS. By default, the browser fingerprinting test of device and browser info verifies the presence of the following fonts:
[
'sans-serif-thin',
'ARNO PRO',
'Agency FB',
'Arabic Typesetting',
'Arial Unicode MS',
'AvantGarde Bk BT',
'BankGothic Md BT',
'Batang',
'Bitstream Vera Sans Mono',
'Calibri',
'Century',
'Century Gothic',
'Clarendon',
'EUROSTILE',
'Franklin Gothic',
'Futura Bk BT',
'Futura Md BT',
'GOTHAM',
'Gill Sans',
'HELV',
'Haettenschweiler',
'Helvetica Neue',
'Humanst521 BT',
'Leelawadee',
'Letter Gothic',
'Levenim MT',
'Lucida Bright',
'Lucida Sans',
'Menlo',
'MS Mincho',
'MS Outlook',
'MS Reference Specialty',
'MS UI Gothic',
'MT Extra',
'MYRIAD PRO',
'Marlett',
'Meiryo UI',
'Microsoft Uighur',
'Minion Pro',
'Monotype Corsiva',
'PMingLiU',
'Pristina',
'SCRIPTINA',
'Segoe UI Light',
'Serifa',
'SimHei',
'Small Fonts',
'Staccato222 BT',
'TRAJAN PRO',
'Univers CE 55 Medium',
'Vrinda',
'ZWAdobeF',
];
Conclusion
Verifying the nature of a user OS is key in the context of fraud detection. It can be used to verify if a user is doing a critical action from a known device. However, fraudsters know it and may be tempted to lie about their real OS to imitate the fingerprint of their victim.
In this article, we showed that by verifying the
consistency of the OS claimed in the user agent with the different signals presented in this article, such
as navigator.platform
, UNMASKED_RENDERER_WEBGL
, and the rendering of emojis in a
canvas fingerprint, you can detect inconsistencies that indicate that the user altered the OS claimed in its
user agent.
Disclaimer: you should keep in mind that all the APIs and attributes presented in this article can also be overridden by an attacker. Thus, it’s important to leverage as many signals as possible to verify their consistency between each other.