专栏首页w候人兮猗的博客技术教程 || 浏览器知道你的哪些信息?

技术教程 || 浏览器知道你的哪些信息?

在不弹出权限询问的情况下,浏览器可以获得你的哪些信息?除了常见的 IP、地理位置、系统和浏览器版本,其实还能获取本地 IP、CPU 平台、显卡型号、登录过的社交网站等等信息。 What every Browser knows about you 展示了浏览器知道的所有关于你的信息。本文就来一一解释下所使用的技术。

地理位置(Location)

经纬坐标和位置信息

Webkay 使用了 Google Maps Geolocation API 来获取地理位置。

类似的地理位置服务都是通过服务器获取客户端 IP,然后在 IP 地址库中查找对应的真实坐标。

这种方法依赖于浏览器上报的 IP,精确度远不如 GPS。比如我挂了代理,Google 就把我定位到了日本。

以下是 PHP 获取客户端 IP 的代码(source):

function get_client_ip() {
    $ipaddress = '';
    if (getenv('HTTP_CLIENT_IP'))
        $ipaddress = getenv('HTTP_CLIENT_IP');
    else if(getenv('HTTP_X_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
    else if(getenv('HTTP_X_FORWARDED'))
        $ipaddress = getenv('HTTP_X_FORWARDED');
    else if(getenv('HTTP_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_FORWARDED_FOR');
    else if(getenv('HTTP_FORWARDED'))
       $ipaddress = getenv('HTTP_FORWARDED');
    else if(getenv('REMOTE_ADDR'))
        $ipaddress = getenv('REMOTE_ADDR');
    else
        $ipaddress = 'UNKNOWN';
    return $ipaddress;
}

如果想获取精准的地理坐标,可以使用 HTML5 中的 Geolocation API,不过使用该 API 会向用户弹出权限询问框。

语言

window.navigator 保存了不少客户端信息,接下来你还会看到很多次:

var languages = navigator.languages     // 非 IE 浏览器,语言列表
             || navigator.language      // 非 IE 浏览器,首选语言
             || navigator.userLanguage; // IE 浏览器,首选语言

本地时间

最容易获取的信息之一:

new Date();

软件(Software)

系统和浏览器

Webkay 使用了 UAParser.jsnavigator.userAgent 进行了解析。UserAgent 中文叫用户代理字符,这个字符串包含了浏览器和系统的表示信息。

比如这几个 UserAgent:

  • Chrome: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.75 Safari/537.36
  • iPad: Mozilla/5.0 (iPad; CPU OS 9_3 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13E237 Safari/601.1
  • MEIZU MX4: Mozilla/5.0 (Linux; Android 5.1; MZ-MX4 Build/LMY47I) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/45.0.2454.94 Mobile Safari/537.36

插件

浏览器插件则是通过遍历 navigator.plugins 获得。

for (var i = 0; i < navigator.plugins.length; i++) {
    var plugin = navigator.plugins[i];
    plugin.name        // 名称
    plugin.filename    // 文件名
    plugin.description // 描述
    plugin.version     // 版本号
}

硬件(Hardware)

CPU

Webkay 结合使用了 navigator.platform 和 UAParser.js 来获取 CPU 平台,核心数则通过 navigator.hardwareConcurrency 获取。

GPU

通过 WebGL API 中的 WEBGL_debug_renderer_info 来获取显卡信息。

分辨率和颜色深度则是通过 window.screen 获取。

var canvas = document.createElement("canvas");
var gl = canvas.getContext("experimental-webgl");
var debugInfo = gl.getExtension("WEBGL_debug_renderer_info");

gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);   // 显卡供应商
gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL); // 显卡渲染器

window.screen.width      // 屏幕宽度
window.screen.height     // 屏幕高度
window.screen.colorDepth // 颜色深度

电量

通过新的 Battery Status API 获取电量相关信息;

navigator.getBattery().then(function(battery) {
    battery.charging;               // 是否在充电
    battery.level;                  // 电量比例
    battery.chargingTime;           // 充电时长
    battery.dischargingTime;        // 放电时长

    /* 事件 */
    battery.onchargingchange        // 充电状态放生变化
    battery.onlevelchange           // 电量发生变化
    battery.onchargingtimechange    // 充电时长发生变化
    battery.ondischargingtimechange // 放电时长发生变化
});

连接(Connection)

本地 IP

使用 WebRTC 中的 RTCPeerConnection 接口建立 WebRTC 连接,给其他客户端发送请求时会带上本地 IP。我们只需要对信息中的 IP 进行提取即可。

var PeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var pc = new PeerConnection({
    iceServers: [{
        urls: "stun:stun.services.mozilla.com"
    }]
});

pc.onicecandidate = function(event) {
    if (event.candidate) {
        var candidate = event.candidate.candidate;
        // candidate:2795255774 1 udp 2122260223 192.168.1.7 64974 typ host generation 0 ufrag W1Ah3U1F3qZXQ8aM
        var ip = candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/)[1];
    }
};

pc.createDataChannel("c7sky.com");

pc.createOffer(function(offer) {
    pc.setLocalDescription(offer);
});

公网 IP 和服务器运营商

分别使用了在线服务 https://api.ipify.org?format=jsonhttp://ip-api.com/json。 原理和之前获取经纬坐标和位置信息一样,服务器根据 IP 查地址库。

来源页

document.referrer

下载速度

Webkay 通过 new Image() 下载一张图片,然后用文件大小除以用时得出,不过这个方法需要事先在 JS 里写明文件大小。如果用 XMLHttpRequest 会更加方便:

var startTime = Date.now();
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://upload.wikimedia.org/wikipedia/commons/2/2d/Snake_River_%285mb%29.jpg");

xhr.onload = function() {
    var duration = (Date.now() - startTime) / 1000;
    var size = xhr.getResponseHeader("Content-Length") / 1024;
    var speed = (size / duration).toFixed(2);
    console.log(speed);
};

xhr.send();

网络类型

使用了目前还没有任何浏览器支持的 Network Information API

var type = navigator.connection.type;
// bluetooth || cellular || ethernet || none || wifi || wimax || other || unknown

社交媒体(Social Media)

如果你已经登录了某个网站,这时你再访问该网站的登录页面,网站会自动跳转到其他页面。

Webkay 就是利用了这一点,通过一个地址为登录页面(可能会跳转到 Favicon)的图像元素,如果接收到的是图片,就说明用户已经登录了该网站,并触发 onload 事件,反之则不会触发。

以 Twitter 为例:在你已经登录的情况下访问 https://twitter.com/login?redirect_after_login=%2Ffavicon.ico,页面就会自动跳转到 https://twitter.com/favicon.ico

var img = new Image();

img.onload = function() {
    // 你登录过 Twitter 啦
};

img.src = "https://twitter.com/login?redirect_after_login=%2Ffavicon.ico";

点击劫持(Click Jacking)

这个我感觉和 What every Browser knows about you 的主题无关,具体介绍可以看 Clickjacking 简单介绍 | WooYun 知识库

陀螺仪(Gyroscope)

这个只有在带有陀螺仪的设备上才有效,通过注册 deviceorientation 事件实时获取设备的陀螺仪信息。

function handleOrientation(event) {
    event.alpha; // Z 轴旋转角度
    event.beta;  // X 轴旋转角度
    event.gamma; // Y 轴旋转角度
}
window.addEventListener("deviceorientation", handleOrientation);

网络扫描(Network Scan)

WebSocket API 遍历之前获得的本地 IP 所在的 IP 段。这个方法只有在对方搭建了 WebSocket 服务器的情况下才有效,对于普通用户来说,可能性基本为零。

var ws_scan = new WebSocket("ws://" + hostname);
var start_time_ws = Date.now();
var closetimeout = 1200;

setInterval(function() {
    var interval = Date.now() - start_time_ws;
    if (ws_scan.readyState === 3) {
        if (closetimeout < interval) {
            // 存在该 IP
        }
    }
    return;
}, 10);

图像(Image)

使用 Exif.js 读取图像 EXIF 信息。

总结

这些信息并不像 Cookie 存在关于个人隐私的安全隐患,如果能够善用这些信息,其实可以给用户带来更好的用户体验~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 实现一个简化版的Vue3数据侦测

    距离国庆假期尤大发布vue3前瞻版本发布已经有一个月的时间,大家都知道在vue2x版本中的响应式数据更新是用的defineProperty这个API。

    w候人兮猗
  • 使用useSelector useDispatch 替代connect

    随着react hooks越来越火,react-redux也紧随其后发布了7.1(https://react-redux.js.org/api/hooks#us...

    w候人兮猗
  • antd-design Form,Select联合使用 placeholder 不起作用问题

    w候人兮猗
  • 结合wasm与mse技术实现的支持H.265网页播放器,为安防可视化系统带来了新突破

    我们在《wasm(WebAssembly)技术的普及为安防信息可视化系统的发展带来了哪些突破口》一文中讲过了实现和普及wasm(WebAssembly)技术的重...

    EasyNVR
  • 图片验证码怎么写?

    如有一天,你需要写一个图片验证码,这篇文章就派上用场了,以下直接上代码,代码中会有详细的注释

    BigYoung小站
  • Python终极调试指南

    本文介绍了一些 Python 调试的高级技巧。如果你还在像新手一样无脑 print 调试,那么赶紧向大牛学习一下如何优雅地调试 Python 代码吧。

    深度学习与Python
  • 火爆全网的动态曲线图是怎么做的?

    之前大家遇到的最多的就是动态条形图,看来大家都对这种比较少见的动态曲线图非常感兴趣。

    朱小五
  • 源码分析Dubbo NettyServer与HeaderExchangeServer

    本文主要分析一下NettyServer,HeaderExchangeServer实现细节。

    丁威
  • 中英三校合作开发新电池结构,可用于改善可穿戴设备体验

    如果电池能够任意改变形状,这将大大提升可穿戴设备的柔软度,人们在使用时也会觉得更加舒适。

    镁客网
  • 像20200202这种完全对称的公历日期,真的是千年一遇吗

    但实际上,这传说中的千年对称日其实并非千年一遇,我运用简单的Python编程计算了未来千年内的所有对称日。

    老肥码码码

扫码关注云+社区

领取腾讯云代金券