matomo-org / device-detector

The Universal Device Detection library will parse any User Agent and detect the browser, operating system, device used (desktop, tablet, mobile, tv, cars, console, etc.), brand and model.

Home Page:http://devicedetector.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Fake iPhones UA + clienthints

sanchezzzhak opened this issue · comments

We started to find advertising clickers on our advertising platform, these are user agents that do not match the device's performance.

in general, this is 0.08% of the pre-day value 1M traffics.

Detect by ClientHints
My Fixture:

- user_agent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/21B101 [FBAN/FBIOS;FBAV/445.0.0.35.117;FBBV/548375166;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/17.1.2;FBSS/2;FBID/phone;FBLC/es_LA;FBOP/5;FBRV/550068703]'
  headers:
    brands:
      - brand: Not_A Brand
        version: '8'
      - brand: Chromium
        version: '120'
    fullVersionList:
      - brand: Not_A Brand
        version: 8.0.0.0
      - brand: Chromium
        version: 120.0.6099.71
      - brand: Google Chrome
        version: 120.0.6099.71
    mobile: '0'
    platform: Linux
    platformVersion: 5.19.0
    uaFullVersion: 120.0.6099.71
    wow64: '0'
    architecture: 'x86'
  meta:
    width: '2000'
    height: '2000'
    gpu: ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver)
  device:
    type: smartphone
    brand: Apple
    model: iPhone 11
    code: iPhone12,1
    trusted: false

Raw data:

Mozilla/5.0 (iPhone; CPU iPhone OS 17_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/21B101 [FBAN/FBIOS;FBAV/445.0.0.35.117;FBBV/548375166;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/17.1.2;FBSS/2;FBID/phone;FBLC/es_LA;FBOP/5;FBRV/550068703]

CLIENT HINTS + JS metrics {"width":"2000","height":"2000","ratio":"1","ram":"8","gpu":"ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader
driver)","colorDepth":"24","gamut":"srgb","cores":"2","hashG":"4863438259","hashC":"289.300","hints":{"architecture":"x86","bitness":"64","brands":[{"brand":"Not_A Brand","version":"8"},{"brand":"Chromium","version":"120"},{"brand":"Google Chrome","version":"120"}],"fullVersionList":[{"brand":"Not_A Brand","version":"8.0.0.0"},{"brand":"Chromium","version":"120.0.6099.71"},{"brand":"Google Chrome","version":"120.0.6099.71"}],"mobile":"0","platform":"Linux","platformVersion":"5.19.0","uaFullVersion":"120.0.6099.71","wow64":"0"}}

our result is similar to motomo/device-detector

{
  os: {
    name: 'GNU/Linux',
    version: '5.19.0',
    short_name: 'LIN',
    platform: 'x86',
    family: 'GNU/Linux'
  },
  client: { name: 'Facebook', type: 'mobile app', version: '445.0.0.35.117' },
  device: {
    type: 'smartphone',
    brand: 'Apple',
    model: 'iPhone 11',
    code: 'iPhone12,1',
    trusted: false
  }
}

What is wrong here:

1 the first thing that catches your eye is the OS, which does not match IOS/macOs/IpadOs.
2 headers are clienthints, which shouldn't be on real phones for IOS/macOs/IpadOs.
3 The GPU metric also doesn't match the Apple GPU for IOS.

I suggest not to identify the device and type if the OS is not part of the Apple family OS.
if exist are client hints for iOS.

other logs

Mozilla/5.0 (iPhone; CPU iPhone OS 12_5_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16H71 [FBAN/FBIOS;FBAV/376.0.0.27.108;FBBV/383940242;FBDV/iPhone7,1;FBMD/iPhone;FBSN/iOS;FBSV/12.5.6;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBRV/386155537]	5297540084	{"width":"375","height":"812","ratio":"1","gpu":"ANGLE (NVIDIA, NVIDIA GeForce MX330 Direct3D11 vs_5_0 ps_5_0, D3D11)","colorDepth":"24","gamut":"srgb","cores":"8","hashG":"5297540084","hashC":"176.612"}
Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/20C65 [FBAN/FBPageAdmin;FBDV/iPhone15,3;FBMD/iPhone;FBSN/iOS;FBSV/16.2;FBSS/3;FBID/phone;FBLC/th_TH;FBOP/5;FBDI/88D816D0-1116-42DC-BB72-9BBA1CD59FB9]	4847523881	{"width":"430","height":"932","ratio":"1","gpu":"ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver)","colorDepth":"24","gamut":"srgb","cores":"2","hashG":"4847523881","hashC":"143.140"}

Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/20C65 [FBAN/FBPageAdmin;FBDV/iPhone15,3;FBMD/iPhone;FBSN/iOS;FBSV/16.2;FBSS/3;FBID/phone;FBLC/th_TH;FBOP/5;FBDI/88D816D0-1116-42DC-BB72-9BBA1CD59FB9]	4847523881	{"width":"430","height":"932","ratio":"1","gpu":"ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver)","colorDepth":"24","gamut":"srgb","cores":"2","hashG":"4847523881","hashC":"375.725"}

Mozilla/5.0 (iPhone; CPU iPhone OS 17_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/21B101 [FBAN/FBIOS;FBAV/445.0.0.35.117;FBBV/548375166;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/17.1.2;FBSS/2;FBID/phone;FBLC/es_LA;FBOP/5;FBRV/550068703]	4863438259	{"width":"2000","height":"2000","ratio":"1","ram":"8","gpu":"ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver)","colorDepth":"24","gamut":"srgb","cores":"2","hashG":"4863438259","hashC":"289.300","hints":{"architecture":"x86","bitness":"64","brands":[{"brand":"Not_A Brand","version":"8"},{"brand":"Chromium","version":"120"},{"brand":"Google Chrome","version":"120"}],"fullVersionList":[{"brand":"Not_A Brand","version":"8.0.0.0"},{"brand":"Chromium","version":"120.0.6099.71"},{"brand":"Google Chrome","version":"120.0.6099.71"}],"mobile":"0","platform":"Linux","platformVersion":"5.19.0","uaFullVersion":"120.0.6099.71","wow64":"0"}}

Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/19F77 [FBAN/FBIOS;FBDV/iPhone9,1;FBMD/iPhone;FBSN/iOS;FBSV/15.5;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5]	5257587026	{"width":"375","height":"667","ratio":"1","gpu":"ANGLE (VMware, VMware SVGA 3D Direct3D11 vs_5_0 ps_5_0, D3D11)","colorDepth":"24","gamut":"srgb","cores":"2","hashG":"5257587026","hashC":"821.220"}
Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/19F77 [FBAN/FBIOS;FBDV/iPhone9,1;FBMD/iPhone;FBSN/iOS;FBSV/15.5;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5]	5257587026	{"width":"375","height":"667","ratio":"1","gpu":"ANGLE (VMware, VMware SVGA 3D Direct3D11 vs_5_0 ps_5_0, D3D11)","colorDepth":"24","gamut":"srgb","cores":"2","hashG":"5257587026","hashC":"3395.793"}
Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/19F77 [FBAN/FBIOS;FBDV/iPhone9,1;FBMD/iPhone;FBSN/iOS;FBSV/15.5;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5]	5257587026	{"width":"375","height":"667","ratio":"1","gpu":"ANGLE (VMware, VMware SVGA 3D Direct3D11 vs_5_0 ps_5_0, D3D11)","colorDepth":"24","gamut":"srgb","cores":"2","hashG":"5257587026","hashC":"257.786"}


Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/20C65 [FBAN/FBPageAdmin;FBDV/iPhone15,3;FBMD/iPhone;FBSN/iOS;FBSV/16.2;FBSS/3;FBID/phone;FBLC/th_TH;FBOP/5;FBDI/88D816D0-1116-42DC-BB72-9BBA1CD59FB9]	4847523881	{"width":"430","height":"932","ratio":"1","gpu":"ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver)","colorDepth":"24","gamut":"srgb","cores":"2","hashG":"4847523881","hashC":"375.725"}

Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/20C65 [FBAN/FBPageAdmin;FBDV/iPhone15,3;FBMD/iPhone;FBSN/iOS;FBSV/16.2;FBSS/3;FBID/phone;FBLC/th_TH;FBOP/5;FBDI/88D816D0-1116-42DC-BB72-9BBA1CD59FB9]	4847523881	{"width":"430","height":"932","ratio":"1","gpu":"ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver)","colorDepth":"24","gamut":"srgb","cores":"2","hashG":"4847523881","hashC":"143.140"}

Mozilla/5.0 (iPhone; CPU iPhone OS 17_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/21B101 [FBAN/FBIOS;FBAV/445.0.0.35.117;FBBV/548375166;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/17.1.2;FBSS/2;FBID/phone;FBLC/es_LA;FBOP/5;FBRV/550068703]	4863438259	{"width":"2000","height":"2000","ratio":"1","ram":"8","gpu":"ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader
driver)","colorDepth":"24","gamut":"srgb","cores":"2","hashG":"4863438259","hashC":"289.300","hints":{"architecture":"x86","bitness":"64","brands":[{"brand":"Not_A Brand","version":"8"},{"brand":"Chromium","version":"120"},{"brand":"Google Chrome","version":"120"}],"fullVersionList":[{"brand":"Not_A Brand","version":"8.0.0.0"},{"brand":"Chromium","version":"120.0.6099.71"},{"brand":"Google Chrome","version":"120.0.6099.71"}],"mobile":"0","platform":"Linux","platformVersion":"5.19.0","uaFullVersion":"120.0.6099.71","wow64":"0"}}

Mozilla/5.0 (iPhone; CPU iPhone OS 12_5_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16H71 [FBAN/FBIOS;FBAV/376.0.0.27.108;FBBV/383940242;FBDV/iPhone7,1;FBMD/iPhone;FBSN/iOS;FBSV/12.5.6;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBRV/386155537]	5297540084	{"width":"375","height":"812","ratio":"1","gpu":"ANGLE (NVIDIA, NVIDIA GeForce MX330 Direct3D11 vs_5_0 ps_5_0, D3D11)","colorDepth":"24","gamut":"srgb","cores":"8","hashG":"5297540084","hashC":"151.411"}
Mozilla/5.0 (iPhone; CPU iPhone OS 12_5_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16H71 [FBAN/FBIOS;FBAV/376.0.0.27.108;FBBV/383940242;FBDV/iPhone7,1;FBMD/iPhone;FBSN/iOS;FBSV/12.5.6;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBRV/386155537]	5297540084	{"width":"375","height":"812","ratio":"1","gpu":"ANGLE (NVIDIA, NVIDIA GeForce MX330 Direct3D11 vs_5_0 ps_5_0, D3D11)","colorDepth":"24","gamut":"srgb","cores":"8","hashG":"5297540084","hashC":"147.712"}
Mozilla/5.0 (iPhone; CPU iPhone OS 12_5_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16H71 [FBAN/FBIOS;FBAV/376.0.0.27.108;FBBV/383940242;FBDV/iPhone7,1;FBMD/iPhone;FBSN/iOS;FBSV/12.5.6;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBRV/386155537]	5297540084	{"width":"375","height":"812","ratio":"1","gpu":"ANGLE (NVIDIA, NVIDIA GeForce MX330 Direct3D11 vs_5_0 ps_5_0, D3D11)","colorDepth":"24","gamut":"srgb","cores":"8","hashG":"5297540084","hashC":"145.300"}

Mozilla/5.0 (iPhone; CPU iPhone OS 15_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/19H370 [FBAN/FBIOS;FBAV/444.0.0.29.113;FBBV/546116613;FBDV/iPhone9,3;FBMD/iPhone;FBSN/iOS;FBSV/15.8;FBSS/2;FBID/phone;FBLC/tr_TR;FBOP/5;FBRV/548173314]	4124039611	{"width":"640","height":"1136","ratio":"2","gpu":"Apple GPU","colorDepth":"32","gamut":"p3","cores":"4","hashG":"4124039611","hashC":"64.200"}
Mozilla/5.0 (iPhone; CPU iPhone OS 16_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBAV/438.1.0.31.114;FBBV/546523008;FBDV/iPhone11,6;FBMD/iPhone;FBSN/iOS;FBSV/16.1.1;FBSS/3;FBCR/;FBID/phone;FBLC/ru;FBOP/80]	4306187871	{"width":"1242","height":"2688","ratio":"3","gpu":"Apple GPU","colorDepth":"32","gamut":"p3","cores":"4","hashG":"4306187871","hashC":"41.300"}
how do we get hints from JS
export default function DeviceMeta() {
  let canvas = document.createElement('canvas');
  let gl;

  if (!gl) {
    try {
      gl = canvas.getContext('webgl') ||
        canvas.getContext('experimental-webgl');
    } catch (e) {}
  }

  let hints = {};
  if (navigator.userAgentData) {
    let requestHints = [
      'brands',
      'mobile',
      'platform',
      'platformVersion',
      'architecture',
      'bitness',
      'wow64',
      'model',
      'uaFullVersion',
      'fullVersionList'];

    navigator.userAgentData.getHighEntropyValues(requestHints).then((result) => {
      hints = JSON.parse(JSON.stringify(result));
    })
  }

  /** #################################
   *  private helper methods
   * ################################# */

  /**
   * get gpu name
   * @returns {string|null}
   */
  function getGPUName() {
    return gl
      ? gl.getParameter(gl.getExtension(
        'WEBGL_debug_renderer_info').UNMASKED_RENDERER_WEBGL)
      : null;
  }

  /**
   * get device pixel ratio
   */
  function getRatio() {
    return window.devicePixelRatio;
  }

  /**
   * get device width of the screen in pixels
   */
  function getWidth() {
    return window.screen.width * getRatio();
  }

  /**
   * get device height of the screen in pixels
   */
  function getHeight() {
    return window.screen.height * getRatio();
  }
  /**
   * get check is ua apply
   * @return {boolean}
   */
  function isAppleFamily() {
    return /iPhone|iPad|Macintosh|Ipod/.exec(navigator.userAgent) !== null;
  }

  /**
   * get timer stamp
   * @return {DOMHighResTimeStamp|number}
   */
  function performance() {
    return (new Date).getTime();
  }

  /**
   * get device memory
   * @return {number|null}
   */
  function getDeviceMemory() {
    return navigator.deviceMemory ? navigator.deviceMemory : null;
  }

  /**
   * Determines if the query is supported by the device.
   * @param {string} query
   * @returns {boolean}
   */
  function hasMediaSupport(query) {
    return window.matchMedia(query).matches;
  }

  function getMediaValue(name, values) {
    for (let i = 0; i < values.length; i++) {
      if (hasMediaSupport('(' + name + ': ' + values[i] + ')')) {
        return values[i];
      }
    }
    return '';
  }

  function getMediaColorGamut() {
    return getMediaValue('color-gamut', ['p3', 'srgb']);
  }

  /** #################################
   *  public methods
   * ################################# */

  this.info = function() {
    return  {
      useragent: navigator.userAgent,
      meta: {
        width: getWidth(),
        height: getHeight(),
        ram: getDeviceMemory(),
        gpu: getGPUName(),
        colorDepth: screen.colorDepth,
        gamut: getMediaColorGamut(),
        cores: navigator.hardwareConcurrency || null,
      },
      hints: hints,
    };
  };

}

// usage
//  let meta new DeviceMeta();
// console.log(meta.info());