diff options
author | Markus Heiser <markus.heiser@darmarIT.de> | 2023-03-20 12:28:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-20 12:28:05 +0100 |
commit | b61b8459515ed58502e7af05037f52497a7b7d0a (patch) | |
tree | 6f32e590c856293b054c90cc00b8868f7c076cfe /searx | |
parent | 70e3fa94411ef3a8205fe61ce4679835bf365b51 (diff) | |
parent | 8fa54ffddfe9c121b5ffd499e376c77fdf90aca1 (diff) | |
download | searxng-b61b8459515ed58502e7af05037f52497a7b7d0a.tar.gz searxng-b61b8459515ed58502e7af05037f52497a7b7d0a.zip |
Merge pull request #2266 from return42/shuffle-cipher
[mod] Shuffle httpx's default ciphers of a SSL context randomly.
Diffstat (limited to 'searx')
-rw-r--r-- | searx/network/client.py | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/searx/network/client.py b/searx/network/client.py index f25aaf9ab..ffee3f096 100644 --- a/searx/network/client.py +++ b/searx/network/client.py @@ -4,6 +4,7 @@ import asyncio import logging +import random from ssl import SSLContext import threading from typing import Any, Dict @@ -28,10 +29,34 @@ LOOP = None SSLCONTEXTS: Dict[Any, SSLContext] = {} +def shuffle_ciphers(ssl_context): + """Shuffle httpx's default ciphers of a SSL context randomly. + + From `What Is TLS Fingerprint and How to Bypass It`_ + + > When implementing TLS fingerprinting, servers can't operate based on a + > locked-in whitelist database of fingerprints. New fingerprints appear + > when web clients or TLS libraries release new versions. So, they have to + > live off a blocklist database instead. + > ... + > It's safe to leave the first three as is but shuffle the remaining ciphers + > and you can bypass the TLS fingerprint check. + + .. _What Is TLS Fingerprint and How to Bypass It: + https://www.zenrows.com/blog/what-is-tls-fingerprint#how-to-bypass-tls-fingerprinting + + """ + c_list = httpx._config.DEFAULT_CIPHERS.split(':') # pylint: disable=protected-access + sc_list, c_list = c_list[:3], c_list[3:] + random.shuffle(c_list) + ssl_context.set_ciphers(":".join(sc_list + c_list)) + + def get_sslcontexts(proxy_url=None, cert=None, verify=True, trust_env=True, http2=False): key = (proxy_url, cert, verify, trust_env, http2) if key not in SSLCONTEXTS: SSLCONTEXTS[key] = httpx.create_ssl_context(cert, verify, trust_env, http2) + shuffle_ciphers(SSLCONTEXTS[key]) return SSLCONTEXTS[key] |