kaliiiiiiiiii / Selenium-Profiles

undetected Selenium using chromedriver and emulation / device profiles
Other
272 stars 29 forks source link

use regexp to check not a brand #72

Closed anysoft closed 1 year ago

anysoft commented 1 year ago

Not.A/Brand
Not:A/Brand
Not=A?Brand Not)A;Brand

anysoft commented 1 year ago

The latest regexp is as follows. you can update it by youself. Waiting for your release, I need this package. :)

brans_pattern = r'^Not[ (:\-./);=?_]A[ (:\-./);=?_]Brand$'

[" ", "(", ":", "-", ".", "/", ")", ";", "=", "?", "_"]

Reference source

https://wicg.github.io/ua-client-hints/#create-arbitrary-brands-section https://github.com/chromium/chromium/blob/02e65feb53029473f796c1bc2bbbf214ea627688/components/embedder_support/user_agent_utils.cc#L406 https://github.com/chromium/chromium/blob/02e65feb53029473f796c1bc2bbbf214ea627688/components/embedder_support/user_agent_utils_unittest.cc#L993

my implementation of it

class BrandVersion(object):
    def __init__(self, brand, version):
        self.brand = brand
        self.version = version

    def __str__(self):
        return f"BrandVersion(x={self.brand}, y={self.version})"
    def __repr__(self):
        return f"BrandVersion(x={self.brand}, y={self.version})"

    def toJson(self):
        return {'brand': self.brand, 'version': self.version}

def get_greased_user_agent_brand_version(permuted_order=[], major_version='114', enable_updated_grease_by_policy=True, is_full_version=False):
    if enable_updated_grease_by_policy:
        greasey_chars = [" ", "(", ":", "-", ".", "/", ")", ";", "=", "?", "_"]
        greased_versions = ["8", "99", "24"]
        # https://wicg.github.io/ua-client-hints/#create-arbitrary-brands-section
        greasey_brand = f"Not{greasey_chars[int(major_version) % len(greasey_chars)]}A{greasey_chars[(int(major_version) + 1) % len(greasey_chars)]}Brand"
        greasey_version = greased_versions[int(major_version) % len(greased_versions)]
        # https://github.com/chromium/chromium/blob/02e65feb53029473f796c1bc2bbbf214ea627688/components/embedder_support/user_agent_utils.cc#L406
        # https://github.com/chromium/chromium/blob/02e65feb53029473f796c1bc2bbbf214ea627688/components/embedder_support/user_agent_utils_unittest.cc#L993
    else:
        greasey_version = "99"
        greasey_chars = [" ", " ", ";"]
        greasey_brand = f'{greasey_chars[permuted_order[0]]}Not{greasey_chars[permuted_order[1]]}A{greasey_chars[permuted_order[2]]}Brand'
    if is_full_version:
        greasey_version = f'{greasey_version}.0.0.0'
    return BrandVersion(greasey_brand, greasey_version)

def generate_brand_version_list(major_version='114', brand='Microsoft Edge', full_version='114.0.5735.199', enable_updated_grease_by_policy=True, is_full_version=False):
    if not is_full_version:
        full_version = full_version.split('.')[0]
    # seed = major_version
    npermutations = 6
    permutation = int(major_version) % npermutations
    orders = [
        [0, 1, 2], [0, 2, 1], [1, 0, 2],
        [1, 2, 0], [2, 0, 1], [2, 1, 0]
    ]
    order = orders[permutation]
    greasey_bv = get_greased_user_agent_brand_version(permuted_order=order, major_version=major_version,
                                                      enable_updated_grease_by_policy=enable_updated_grease_by_policy, is_full_version=is_full_version)
    chromium_bv = BrandVersion("Chromium", full_version)
    greased_brand_version_list = [1, 2, 3]
    if brand:
        brand_bv = BrandVersion(brand, full_version)
        greased_brand_version_list[order[0]] = greasey_bv.toJson()
        greased_brand_version_list[order[1]] = chromium_bv.toJson()
        greased_brand_version_list[order[2]] = brand_bv.toJson()
    else:
        greased_brand_version_list[int(major_version) % 2] = greasey_bv
        greased_brand_version_list[(int(major_version) + 1) % 2] = chromium_bv

    return greased_brand_version_list

def get_user_agent_brand_full_version_list(major_version='114',
                                           full_version='114.0.5735.199', brand='Edge', enable_updated_grease_by_policy=True):
    return generate_brand_version_list(major_version=major_version, brand=brand, full_version=full_version, enable_updated_grease_by_policy=enable_updated_grease_by_policy, is_full_version=True)

if __name__ == '__main__':
    full_version = '109.0.5735.199'
    major_version = full_version.split('.')[0]
    brand = 'Microsoft Edge'
    print(get_user_agent_brand_full_version_list(major_version=major_version, full_version=full_version, brand=brand))
    print(generate_brand_version_list(major_version=major_version, full_version=full_version, brand=brand, is_full_version=False))
anysoft commented 1 year ago

I'm very sorry, the regex I wrote was not tested and there was an escape character error @kaliiiiiiiiii

brandspattern = r'^Not[ (:-./);=?]A[ (:-./);=?_]Brand$'

Should be changed to branspattern = r'^Not[ (:\-./);=?]A[ (:\-./);=?_]Brand$'

kaliiiiiiiiii commented 1 year ago

r'^Not[ (:-./);=?]A[ (:-./);=?]Brand$'

@anysoft mhh still get re.error: bad character range :-. at position 7

import re

brands_pattern =  r'^Not[ (:-./);=?]A[ (:-./);=?]Brand$'
brand = 'Google Chrome'
re.match(brands_pattern, brand)
anysoft commented 1 year ago

` branspattern = r'^Not[ (:\-./);=?]A[ (:\-./);=?_]Brand$'

`

is my fault

char - Escape character required

anysoft commented 1 year ago

r'^Not[ (:-./);=?]A[ (:-./);=?]Brand$'

@anysoft mhh still get re.error: bad character range :-. at position 7

import re

brands_pattern =  r'^Not[ (:-./);=?]A[ (:-./);=?]Brand$'
brand = 'Google Chrome'
re.match(brands_pattern, brand)

@kaliiiiiiiiii

Invalid escape character in github comment

brans_pattern = r'^Not[ (:\-./);=?]A[ (:\-./);=?]Brand$'

anysoft commented 1 year ago
    import re

    brands_pattern = r'^Not[ (:\-./);=?]A[ (:\-./);=?]Brand$'
    brand = 'Google Chrome'
    print(re.match(brands_pattern, brand))
    brand = 'Not.A/Brand'
    print(re.match(brands_pattern, brand))

in github comment we need enter double \ 😂

kaliiiiiiiiii commented 1 year ago
    import re

    brands_pattern = r'^Not[ (:\-./);=?]A[ (:\-./);=?]Brand$'
    brand = 'Google Chrome'
    print(re.match(brands_pattern, brand))
    brand = 'Not.A/Brand'
    print(re.match(brands_pattern, brand))

in github comment we need enter double \ 😂

@anysoft ohh forgot.. whatever, implemented now with with selenium-profiles>=2.2.7.4

anysoft commented 1 year ago
    import re

    brands_pattern = r'^Not[ (:\-./);=?]A[ (:\-./);=?]Brand$'
    brand = 'Google Chrome'
    print(re.match(brands_pattern, brand))
    brand = 'Not.A/Brand'
    print(re.match(brands_pattern, brand))

in github comment we need enter double \ 😂

@anysoft ohh forgot.. whatever, implemented now with with selenium-profiles>=2.2.7.4

Thank you very much ❤️

anysoft commented 1 year ago

The latest regexp is as follows. you can update it by youself. Waiting for your release, I need this package. :)

brans_pattern = r'^Not[ (:\-./);=?_]A[ (:\-./);=?_]Brand$'

[" ", "(", ":", "-", ".", "/", ")", ";", "=", "?", "_"]

Reference source

https://wicg.github.io/ua-client-hints/#create-arbitrary-brands-section https://github.com/chromium/chromium/blob/02e65feb53029473f796c1bc2bbbf214ea627688/components/embedder_support/user_agent_utils.cc#L406 https://github.com/chromium/chromium/blob/02e65feb53029473f796c1bc2bbbf214ea627688/components/embedder_support/user_agent_utils_unittest.cc#L993

my implementation of it

class BrandVersion(object):
    def __init__(self, brand, version):
        self.brand = brand
        self.version = version

    def __str__(self):
        return f"BrandVersion(x={self.brand}, y={self.version})"
    def __repr__(self):
        return f"BrandVersion(x={self.brand}, y={self.version})"

    def toJson(self):
        return {'brand': self.brand, 'version': self.version}

def get_greased_user_agent_brand_version(permuted_order=[], major_version='114', enable_updated_grease_by_policy=True, is_full_version=False):
    if enable_updated_grease_by_policy:
        greasey_chars = [" ", "(", ":", "-", ".", "/", ")", ";", "=", "?", "_"]
        greased_versions = ["8", "99", "24"]
        # https://wicg.github.io/ua-client-hints/#create-arbitrary-brands-section
        greasey_brand = f"Not{greasey_chars[int(major_version) % len(greasey_chars)]}A{greasey_chars[(int(major_version) + 1) % len(greasey_chars)]}Brand"
        greasey_version = greased_versions[int(major_version) % len(greased_versions)]
        # https://github.com/chromium/chromium/blob/02e65feb53029473f796c1bc2bbbf214ea627688/components/embedder_support/user_agent_utils.cc#L406
        # https://github.com/chromium/chromium/blob/02e65feb53029473f796c1bc2bbbf214ea627688/components/embedder_support/user_agent_utils_unittest.cc#L993
    else:
        greasey_version = "99"
        greasey_chars = [" ", " ", ";"]
        greasey_brand = f'{greasey_chars[permuted_order[0]]}Not{greasey_chars[permuted_order[1]]}A{greasey_chars[permuted_order[2]]}Brand'
    if is_full_version:
        greasey_version = f'{greasey_version}.0.0.0'
    return BrandVersion(greasey_brand, greasey_version)

def generate_brand_version_list(major_version='114', brand='Microsoft Edge', full_version='114.0.5735.199', enable_updated_grease_by_policy=True, is_full_version=False):
    if not is_full_version:
        full_version = full_version.split('.')[0]
    # seed = major_version
    npermutations = 6
    permutation = int(major_version) % npermutations
    orders = [
        [0, 1, 2], [0, 2, 1], [1, 0, 2],
        [1, 2, 0], [2, 0, 1], [2, 1, 0]
    ]
    order = orders[permutation]
    greasey_bv = get_greased_user_agent_brand_version(permuted_order=order, major_version=major_version,
                                                      enable_updated_grease_by_policy=enable_updated_grease_by_policy, is_full_version=is_full_version)
    chromium_bv = BrandVersion("Chromium", full_version)
    greased_brand_version_list = [1, 2, 3]
    if brand:
        brand_bv = BrandVersion(brand, full_version)
        greased_brand_version_list[order[0]] = greasey_bv.toJson()
        greased_brand_version_list[order[1]] = chromium_bv.toJson()
        greased_brand_version_list[order[2]] = brand_bv.toJson()
    else:
        greased_brand_version_list[int(major_version) % 2] = greasey_bv
        greased_brand_version_list[(int(major_version) + 1) % 2] = chromium_bv

    return greased_brand_version_list

def get_user_agent_brand_full_version_list(major_version='114',
                                           full_version='114.0.5735.199', brand='Edge', enable_updated_grease_by_policy=True):
    return generate_brand_version_list(major_version=major_version, brand=brand, full_version=full_version, enable_updated_grease_by_policy=enable_updated_grease_by_policy, is_full_version=True)

if __name__ == '__main__':
    full_version = '109.0.5735.199'
    major_version = full_version.split('.')[0]
    brand = 'Microsoft Edge'
    print(get_user_agent_brand_full_version_list(major_version=major_version, full_version=full_version, brand=brand))
    print(generate_brand_version_list(major_version=major_version, full_version=full_version, brand=brand, is_full_version=False))

If you have time to refer to this, just the useragent can automatically complete the brand data in the metadata

@kaliiiiiiiiii

Some security policies verify ua ch information in server