mirror of
https://github.com/yogeshojha/rengine.git
synced 2026-10-20 23:31:31 +02:00
A pass over every tool the resolved config reaches, driving a real run end to end and reading the argv each client builds. vhost swept http:// whatever the run asked for. FfufClient took a scheme argument nothing passed, so https_only did not hold for virtual-host discovery — a hole in the setting shipped earlier today. tlsx never went through the proxy. It was handed HTTP_PROXY env vars, which a raw TLS dial does not read, and tlsx does define -proxy: -proxy socks5://u:p@10.0.0.1:1080 accepted -proxy 10.0.0.1:1080 first path segment cannot contain colon -proxy http://10.0.0.1:8080 proxy: unknown scheme: http so it takes the URL when the scan's proxy is socks5, and refuses through availability() otherwise rather than dialling direct. is_socks5() now holds that decision for both tlsx and naabu. Screenshots had no rate limit at any level: no field on the config and no -rate-limit in the capture arguments, so a ceiling did not bind the render pass. The context's follow-redirects override reached only nuclei. The control offers "Engine default", which promises an override, and http_probe and endpoint_probe used their own setting regardless. origin_probe and session_check keep theirs, which are requirements rather than preferences. basic auth with both fields blank sent Authorization: Basic Og== to every target. Every other auth type already guarded on truthiness. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X5roHYDYzSPRNaTkn8hSkJ
51 lines
1.5 KiB
Python
51 lines
1.5 KiB
Python
import json
|
|
from urllib.parse import urlsplit
|
|
|
|
from shared.models.proxy import Proxy, ProxyEndpoint
|
|
from shared.utils.crypto import decrypt_stored
|
|
|
|
|
|
def load_proxy_endpoints(proxy: Proxy) -> list[ProxyEndpoint]:
|
|
raw = decrypt_stored(proxy.endpoints_encrypted or "", label=f"Proxy {proxy.name!r}")
|
|
if not raw:
|
|
return []
|
|
return [ProxyEndpoint(**e) for e in json.loads(raw)]
|
|
|
|
|
|
SOCKS_SCHEMES = frozenset({"socks5", "socks5h"})
|
|
|
|
|
|
def is_socks5(proxy_url: str | None) -> bool:
|
|
"""Whether a tool that speaks only socks5 can carry this proxy."""
|
|
if not proxy_url:
|
|
return False
|
|
raw = proxy_url if "://" in proxy_url else f"socks5://{proxy_url}"
|
|
return urlsplit(raw).scheme.lower() in SOCKS_SCHEMES
|
|
|
|
|
|
def proxy_env(proxy_url: str | None) -> dict[str, str] | None:
|
|
"""Proxy env vars honoured by Go HTTP clients that take no proxy flag."""
|
|
if not proxy_url:
|
|
return None
|
|
return {
|
|
"HTTP_PROXY": proxy_url,
|
|
"HTTPS_PROXY": proxy_url,
|
|
"ALL_PROXY": proxy_url,
|
|
}
|
|
|
|
|
|
def build_proxy_url(ep: ProxyEndpoint) -> str:
|
|
if ep.username:
|
|
cred = f"{ep.username}:{ep.password}@" if ep.password else f"{ep.username}@"
|
|
return f"{ep.scheme}://{cred}{ep.host}:{ep.port}"
|
|
return f"{ep.scheme}://{ep.host}:{ep.port}"
|
|
|
|
|
|
def resolve_proxy_url(proxy: Proxy | None) -> str | None:
|
|
if proxy is None or not proxy.is_active:
|
|
return None
|
|
endpoints = load_proxy_endpoints(proxy)
|
|
if not endpoints:
|
|
return None
|
|
return build_proxy_url(endpoints[0])
|