Chrome的隐藏X-Browser-validation标头逆向工程
Chrome's hidden X-Browser-Validation header reverse engineered

原始链接: https://github.com/dsekz/chrome-x-browser-validation-header

Chrome推出了新的“ X-Browser-*”标题,其中最有趣的是“ X-Browser-validation”。该标头可能是完整性检查,对基础平台验证用户代理并检测欺骗尝试。 标题的值是通过特定过程生成的:首先,Chrome将特定于平台的API键连接(Windows使用“ Aizasya2klwbx3MKFO30OM9LUFYQHPQULOA_BNHE”)与完整的用户代理字符串。然后使用SHA-1散列此组合数据。最后,由此产生的20字节SHA-1摘要是基本64编码,产生了“ X-Browser-validation”标头的值。 Chrome的二进制文件的分析证实了这一过程,揭示了硬编码的API键,SHA-1哈希算法和基本64编码涉及生成标头的步骤。这种机制有助于镀铬确保其客户的真实性和完整性。

黑客新闻线程讨论了Chrome新发现的“ X-Browser-validation”标头及其含义。反向工程揭示了它是如何使用固定常数生成的。辩论以其目的为中心:机器人检测,反散布或扼杀浏览器竞争。 担心Google可能会使用此标头来降低非铬浏览器的体验,从而有可能迫使用户切换。一些人怀疑这是一种法律策略,使用了对标题阻止竞争的版权主张。其他人则认为它是为了检测精致的机器人和保护服务器API,尽管它的简单性引起了疑问。 讨论了标题欺骗的脆弱性,并有可能进行更复杂的实施。尽管目前对指纹的影响似乎很少,但担心它仍然可以使其能够歧视非浓汤用户,尤其是随着未来对Chrome的更新。有些人讨论复制Google版权字符串是否会侵犯版权。
相关文章

原文

Chrome recently added a few new headers:

"x-browser-channel": "stable",
"x-browser-copyright": "Copyright 2025 Google LLC. All rights reserved.",
"x-browser-validation": "6h3XF8YcD8syi2FF2BbuE2KllQo=",
"x-browser-year": "2025"

Apart from one of them, there isn’t much that’s interesting. They’re just bits of client specific information. However, base64 decoding x-browser-validation yields what appears to be a hash whose purpose remains undocumented.

Chrome almost certainly uses this header as an integrity signal. Verifying that the declared user agent matches the underlying platform, spotting user agent string spoofing attempts etc.


from xbv import generate_validation_header


ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"

# You may supply an explicit api_key alongside the ua
# if omitted, the function automatically selects the appropriate key based on the user agent
api_key = "AIzaSyA2KlwBX3mkFo30om9LUFYQhpqLoa_BNhE"

header_value = generate_validation_header(ua)

print(header_value)

  1. Grab two strings

    • A hard-coded, platform specific API key
    • The browser’s full user agent string
  2. Concatenate

    DATA = API_KEY + USER_AGENT
    
  3. Hash DATA with SHA-1 and base64 encode it.


Platform Default Key (found in Chrome binaries)
Windows AIzaSyA2KlwBX3mkFo30om9LUFYQhpqLoa_BNhE
Linux AIzaSyBqJZh-7pA44blAaAkH6490hUFOwX0KCYM
macOS AIzaSyDr2UxVnv_U85AbhhY8XSHSIavUW0DC-sY

Opened chrome.dll in IDA. The master routine sub_1806C95B0 builds every X-Browser-* header (you can find this function by searching browser-validation etc):

  • Data prep - grabs the first hard-coded API key for the OS and appends the full user agent.

    __int64 __fastcall sub_1806C95B0(__int64 a1, __int64 a2)
    {
        // ... setup ...
    
        // Data Preparation
        // Retrieves credentials and combines the API key and user agent into a buffer.
        v7 = sub_1806C9B30();
        v9 = sub_183EBC7D0(v41, 0LL, v7, v8);
    
        // ... more setup ...
    
        // Hashing
        // The call to the SHA-1 hashing function.
        sub_183B509D0(v46, v38);
    
        // ... more setup ...
        
        // Encoding
        // The call to the Base64 encoding function.
        sub_1806C9A80((__int64 *)v40, v39);
    
        // ... more setup ...
    
        // Header Setting
        // Adds the final encoded string to the request headers.
        v30 = "X-Browser-Validation";
        sub_183C6B920(v27);
        
        // ...
    }
  • Hash - passes that buffer into sub_183B509D0, which is SHA-1 algo. Open this guy and the first assignment jumps out:

    v12[0] = xmmword_7FFE2C9A7D50;
    LODWORD(v12[1]) = -1009589776;   // 0xC3D2E1F0

    The second you see that "-1009589776" number, you can literally smell SHA-1.

  • Base64 - the 20-byte digest is encoded.

Dynamic confirmation: pause one instruction before the hash call, dump RDX, and the ~150-byte buffer is nothing but

Base64(SHA-1(buffer)) = header. Mystery solved.

联系我们 contact @ memedata.com