目录
Client Hints
是一组 HTTP 请求标头字段,服务器可以主动向客户端请求,以获取有关设备、网络、用户和代理特定首选项的信息。它是作为 HTTP 用户代理的替代品引入的:«用户代理客户端提示的主要目标是减少服务器可用于被动指纹识别的默认熵。但是,第一方或委托第三方仍可能请求并使用部分或全部提示进行主动指纹识别。»
每次访问此页面时,服务器都会使用以下 HTTP 标头进行响应:
服务器发送的 HTTP 标头
sec-ch-ua,ua,sec-ch-ua-platform,ua-platform,sec-ch-ua-mobile,ua-mobile,sec-ch-ua-full-version,ua-full-version,sec-ch-ua-full-version-list,sec-ch-ua-platform-version,ua-platform-version,sec-ch-ua-arch,ua-arch,sec-ch-ua-bitness,ua-bitness,sec-ch-ua-wow64,sec-ch-ua-model,ua-model,sec-ch-lang,lang,sec-ch-save-data,save-data,sec-ch-width,width,sec-ch-viewport-width,viewport-width,sec-ch-viewport-height,viewport-height,sec-ch-dpr,dpr,sec-ch-device-memory,device-memory,sec-ch-rtt,rtt,sec-ch-downlink,downlink,sec-ch-ect,ect,sec-ch-prefers-color-scheme,sec-ch-prefers-reduced-motion,sec-ch-prefers-reduced-transparency,sec-ch-prefers-contrast,sec-ch-forced-colors,sec-ch-prefers-reduced-data
可用性
Accept-CH 可用性
- 至 2022年3月23日
getHighEntropyValues 可用性
- 至 2022年3月23日
User Agent Client Hints JavaScript API
核心代码
"function" == typeof navigator.userAgentData.getHighEntropyValues
&& navigator.userAgentData.getHighEntropyValues([
"brands",
"mobile",
"platform",
"platformVersion",
"architecture",
"bitness",
"wow64",
"model",
"uaFullVersion",
"fullVersionList"
]).then(function(t) {
for (var n in t)
console.log(n,t[n])
})
puppeteer
请求头过滤
let filter_key = ["sec-ch-ua", "ua", "sec-ch-ua-platform", "ua-platform", "sec-ch-ua-mobile", "ua-mobile", "sec-ch-ua-full-version", "ua-full-version", "sec-ch-ua-full-version-list", "sec-ch-ua-platform-version", "ua-platform-version", "sec-ch-ua-arch", "ua-arch", "sec-ch-ua-bitness", "ua-bitness", "sec-ch-ua-wow64", "sec-ch-ua-model", "ua-model", "sec-ch-lang", "lang", "sec-ch-save-data", "save-data", "sec-ch-width", "width", "sec-ch-viewport-width", "viewport-width", "sec-ch-viewport-height", "viewport-height", "sec-ch-dpr", "dpr", "sec-ch-device-memory", "device-memory", "sec-ch-rtt", "rtt", "sec-ch-downlink", "downlink", "sec-ch-ect", "ect", "sec-ch-prefers-color-scheme", "sec-ch-prefers-reduced-motion", "sec-ch-prefers-reduced-transparency", "sec-ch-prefers-contrast", "sec-ch-forced-colors", "sec-ch-prefers-reduced-data"]
page.on('request',async request => {
let header = request.headers(),new_header ={}
Object.keys(header).filter((key) => {
return filter_key.indexOf(key)==-1
}).forEach((key) => {
new_header[key] = header[key]
})
console.log(new_header)
request.continue({ headers:new_header })
});
userAgentData.getHighEntropyValues
Object.defineProperty(navigator, 'userAgentData', Object.assign({},{}))
Object.defineProperty(navigator, 'userAgentData', Object.assign({},navigator.userAgentData,{
get: () => {
return {
brands: [{"brand": " Not A;Brand", "version": "91"},
{"brand": "Chromium", "version": "91"},
{"brand": "Google Chrome", "version": "91"}],
mobile: false,
platform: "Windows",
getHighEntropyValues(keys){
console.log(keys)
return new Promise(function (resolve,j) {
let fake_HV = {
brands: [{"brand": " Not A;Brand", "version": "91"},
{"brand": "Chromium", "version": "91"},
{"brand": "Google Chrome", "version": "91"}],
mobile: false,
platform: "Windows",
platformVersion: "10.0.0",
architecture: "x86",
bitness: "64",
model: '',
uaFullVersion: '91.0.4844.51',
fullVersionList: [{"brand": " Not A;Brand", "version": "91.0.0.0"},
{"brand": "Chromium", "version": "91.0.4844.51"},
{"brand": "Google Chrome", "version": "91.0.4844.51"}],
},ret_data = {}
Object.keys(fake_HV).filter((key) => {
return keys.indexOf(key)!=-1
}).forEach((key) => {
ret_data[key] = fake_HV[key]
})
console.log(ret_data)
resolve(ret_data)
})
},
toString(){
return
},
toJSON(){
}
}
},
}))
Object.defineProperty(navigator, 'userAgentData', Object.assign({}, navigator.userAgentData, {
get: () => {
function getFather () {
function NavigatorUAData () {
this.getHighEntropyValues = function (keys) {
return new Promise(function (resolve, j) {
let fake_HV = {
brands: [
{ 'brand': ' Not A;Brand', 'version': '91' },
{ 'brand': 'Chromium', 'version': '91' },
{ 'brand': 'Google Chrome', 'version': '91' }],
mobile: false,
platform: 'Windows',
platformVersion: '10.0.0',
architecture: 'x86',
bitness: '64',
model: '',
uaFullVersion: '91.0.4844.51',
fullVersionList: [
{ 'brand': ' Not A;Brand', 'version': '91.0.0.0' },
{ 'brand': 'Chromium', 'version': '91.0.4844.51' },
{ 'brand': 'Google Chrome', 'version': '91.0.4844.51' }],
}, ret_data = {}
Object.keys(fake_HV)
.filter((key) => { return keys.indexOf(key) != -1 })
.forEach((key) => { ret_data[key] = fake_HV[key] })
console.log(ret_data)
resolve(ret_data)
})
}
}
NavigatorUAData.prototype = {
get [Symbol.toStringTag] () {
return 'NavigatorUAData'
},
}
NavigatorUAData.prototype.constructor = NavigatorUAData
return NavigatorUAData
}
function NavigatorUAData () {
this.brands = [
{ 'brand': ' Not A;Brand', 'version': '91' },
{ 'brand': 'Chromium', 'version': '91' },
{ 'brand': 'Google Chrome', 'version': '91' },
]
this.mobile = false
this.platform = 'Windows'
}
var Father = getFather()
NavigatorUAData.prototype = new Father()
return new NavigatorUAData()
},
}))
参考
getHighEntropyValues
https://browserleaks.com/client-hints