{"id":21187302,"url":"https://github.com/daijro/hazetunnel","last_synced_at":"2025-09-24T10:31:15.777Z","repository":{"id":231825815,"uuid":"782800389","full_name":"daijro/hazetunnel","owner":"daijro","description":"🔮 Vindicate non-organic web traffic via MITM proxy","archived":false,"fork":false,"pushed_at":"2024-07-15T06:46:02.000Z","size":61,"stargazers_count":45,"open_issues_count":4,"forks_count":7,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-08T15:17:21.345Z","etag":null,"topics":["golang","injector","mitm","networking","playwright","proxy","tls"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/hazetunnel","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/daijro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-06T04:26:03.000Z","updated_at":"2025-01-08T02:48:59.000Z","dependencies_parsed_at":"2024-06-09T07:37:50.786Z","dependency_job_id":"6cb954bf-9663-4838-9bf2-3f51f00cd81c","html_url":"https://github.com/daijro/hazetunnel","commit_stats":null,"previous_names":["daijro/hazetunnel"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daijro%2Fhazetunnel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daijro%2Fhazetunnel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daijro%2Fhazetunnel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daijro%2Fhazetunnel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/daijro","download_url":"https://codeload.github.com/daijro/hazetunnel/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234070405,"owners_count":18774676,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","injector","mitm","networking","playwright","proxy","tls"],"created_at":"2024-11-20T18:33:35.704Z","updated_at":"2025-09-24T10:31:10.495Z","avatar_url":"https://github.com/daijro.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n    Hazetunnel\n\u003c/h1\u003e\n\n\u003ch3 align=\"center\"\u003e\n    🔮 Vindicate non-organic web traffic\n\u003c/h3\u003e\n\n---\n\nHazetunnel is an MITM proxy that attempts to legitimize [BrowserForge](https://github.com/daijro/browserforge/)'s injected-browser web traffic by hijacking the TLS fingerprint to mirror the passed User-Agent.\n\nAdditionally, it can inject a Javascript payload into the web page to defend against [worker fingerprinting](https://github.com/apify/fingerprint-suite/issues/64).\n\n\u003chr width=50\u003e\n\n### Features ✨\n\n- Anti TLS fingerprinting 🪪\n\n  - Emulate the ClientHello of browsers based on the passed User-Agent (e.g. Chrome/120)\n  - Bypasses TLS fingerprinting checks\n\n- Javascript payload injection 💉\n\n  - Prepends payload to all Javascript responses, including the web page Service/Shared worker scope.\n  - Injects payload into embedded base64 encoded JavaScript within HTML responses ([see here](https://github.com/apify/fingerprint-suite/issues/64#issuecomment-1282877696))\n\nThis project was built on [tlsproxy](https://github.com/rosahaj/tlsproxy), please leave them a star!\n\n---\n\n# Usage\n\nThis package can be installed and used through Python. It is avaliable on PyPi:\n\n```bash\npip install hazetunnel\n```\n\nYou can also use it as a standalone Go executable by building the tool with the [guide](https://github.com/daijro/hazetunnel?tab=readme-ov-file#building) below.\n\n## CLI Usage\n\nAfter installing Hazetunnel through PyPi, it can be used as a standalone CLI application.\n\nThis example will inject `alert('Hello world');` before all Javascript responses:\n\n```bash\nhazetunnel run --payload \"alert('Hello world');\" --port 8080\n```\n\n\u003cdetails\u003e\n\n  \u003csummary\u003e\n    CLI parameters\n  \u003c/summary\u003e\n\n```\n$ hazetunnel run --help\nUsage: hazetunnel run [OPTIONS]\n\n  Run the MITM proxy\n\nOptions:\n  -p, --port TEXT        Port to use. Default: 8080.\n  --user_agent TEXT      Override User-Agent headers.\n  --payload TEXT         Payload to inject into responses.\n  --upstream_proxy TEXT  Forward requests to an upstream proxy.\n  --cert TEXT            Path to the certificate file.\n  --key TEXT             Path to the key file.\n  -v, --verbose          Enable verbose output.\n  --help                 Show this message and exit.\n```\n\n\u003c/details\u003e\n\nMore info on other CLI commands are avaliable [here](https://github.com/daijro/hazetunnel/tree/main/python-bindings#python-usage).\n\n### Payload Injection\n\n#### Javascript responses\n\nThis [example server](https://github.com/daijro/hazetunnel/blob/main/example/server.py) will return `console.log('Original JavaScript executed.')` when called:\n\n**Original response:**\n\n```bash\n$ curl http://localhost:5000/js\nconsole.log('Original JavaScript executed.');\n```\n\n**With Hazetunnel:**\n\n```bash\n$ curl http://localhost:5000/js --proxy http://localhost:8080 --cacert cert.pem\nalert('Hello world');console.log('Original JavaScript executed.');\n```\n\n#### HTML responses\n\nAdditionally, Hazetunnel can inject payloads into HTML responses:\n\n```bash\n$ curl http://localhost:5000/html --proxy http://localhost:8080 --cacert cert.pem\n\u003c!DOCTYPE html\u003e\n\u003cbody\u003e\n    \u003ch1\u003eBase64 JavaScript Testing Page\u003c/h1\u003e\n    \u003cp\u003eThis page includes an embedded base64 encoded JavaScript for testing.\u003c/p\u003e\n    \u003cscript src=\"data:application/javascript;base64,YWxlcnQoJ0hlbGxvIHdvcmxkJyk7Y29uc29sZS5sb2coJ09yaWdpbmFsIEphdmFTY3JpcHQgZXhlY3V0ZWQuJyk7\"\u003e\u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nThe embedded base64-encoded script will now decode to this:\n\n```\nalert('Hello world');console.log('Original JavaScript executed.');\n```\n\n### TLS Spoofing\n\nHazetunnel will spoof the TLS fingerprint to match the User-Agent passed in the request.\n\nHere is an example of a request to [tls.peet.ws](https://tls.peet.ws/api/clean) through Hazetunnel with a Chrome/121 User-Agent:\n\n```bash\n$ curl https://tls.peet.ws/api/clean -H \"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36\" --proxy http://localhost:8080 --cacert cert.pem\n{\n  \"ja3\": \"771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,16-45-65281-35-5-10-23-0-27-13-65037-11-18-43-17513-51,29-23-24,0\",\n  \"ja3_hash\": \"1a5edeab8308886ca9716ef14eecd4f3\",\n  \"akamai\": \"2:0,4:4194304,6:10485760|1073741824|0|a,m,p,s\",\n  \"akamai_hash\": \"55541b174e8a8adc32544ca36c6fd053\",\n  \"peetprint\": \"GREASE-772-771|2-1.1|GREASE-29-23-24|1027-2052-1025-1283-2053-1281-2054-1537|1|2|GREASE-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53|0-10-11-13-16-17513-18-23-27-35-43-45-5-51-65037-65281-GREASE-GREASE\",\n  \"peetprint_hash\": \"8ad9325e12f531d2983b78860de7b0ec\"\n}\n```\n\nHazetunnel interprets from the User-Agent that the response is meant to mimic Chrome 121, and sends a ClientHello that mimics Chrome 121 browsers' cipher suites, GREASE functionality, elliptic curves, etc.\n\nIt also generates an Akamai HTTP/2 fingerprint.\n\nThis supports User-Agents from **Firefox, Chrome, iOS, Android, Edge (legacy), Safari, 360Browser, QQBrowser, etc.**\n\n\u003chr width=50\u003e\n\n## Python API\n\nHazetunnel can also be used as a Python library.\n\n#### Simple usage\n\n```py\nfrom hazetunnel import HazeTunnel\nfrom browserforge.headers import HeaderGenerator\n...\n# Initialize the proxy\nproxy = HazeTunnel(port='8080', payload='alert(\"Hello World!\");')\nproxy.launch()\n# Send the request\nrequests.get(\n    url='https://example.com',\n    headers=HeaderGenerator().generate(browser='chrome'),\n    proxies={'https': proxy.url},\n    verify=proxy.cert\n).text\n# Stop the proxy\nproxy.stop()\n```\n\n\u003cdetails\u003e\n\n  \u003csummary\u003e\n    HazeTunnel parameters\n  \u003c/summary\u003e\n\n```\nParameters:\n    port (Optional[str]): Specify a port to listen on. Default is random.\n    payload (Optional[str]): Payload to inject into responses\n    user_agent (Optional[str]): Optionally override all User-Agent headers\n    upstream_proxy (Optional[str]): Optionally forward requests to an upstream proxy\n```\n\n\u003c/details\u003e\n\n#### Using a context manager\n\nA context manager will automatically close the server when not needed anymore.\n\n```py\nwith HazeTunnel(port='8080', payload='alert(\"Hello World!\");') as proxy:\n  # Send the request\n  requests.get(\n      url='https://example.com',\n      headers=HeaderGenerator().generate(browser='chrome'),\n      proxies={'https': proxy.url},\n      verify=proxy.cert\n  ).text\n```\n\n\u003chr width=50\u003e\n\n## Building\n\n### CFFI\n\nPre-built C shared library binaries provided in [Releases](https://github.com/daijro/hazetunnel/releases).\n\nOtherwise, you can build these yourself using the `build.bat` file provided.\n\n### CLI\n\n#### Building from source\n\n```bash\ngit clone https://github.com/daijro/hazetunnel\ncd hazetunnel\ngo build\n```\n\n#### Usage\n\n```\nUsage of hazetunnel:\n  -addr string\n        Proxy listen address\n  -cert string\n        TLS CA certificate (generated automatically if not present) (default \"cert.pem\")\n  -key string\n        TLS CA key (generated automatically if not present) (default \"key.pem\")\n  -port string\n        Proxy listen port (default \"8080\")\n  -user_agent string\n        Override the User-Agent header for incoming requests. Optional.\n  -verbose\n        Enable verbose logging\n```\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaijro%2Fhazetunnel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaijro%2Fhazetunnel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaijro%2Fhazetunnel/lists"}