Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 6 additions & 11 deletions bbot/modules/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,16 +285,10 @@ async def handle_batch(self, *events):
)
configs.append(config)

# Suppress redundant https probes when http already succeeded for the same
# (host, port). When probing an unknown port, we try both schemes; if http
# works, the port definitely speaks HTTP, and the https result is likely a
# proxy artifact (intercepting proxies like Burp terminate TLS themselves,
# making any https:// URL "succeed" regardless of whether the target really
# speaks TLS). Explicit URL/URL_UNVERIFIED events are never suppressed —
# only speculative OPEN_TCP_PORT probes.
#
# Streaming requires per-pair coordination: emit http immediately, defer
# https until http's outcome is known (or the stream ends).
# Suppress redundant https probes when http returned a real page (2xx) for
# the same (host, port). Only a 2xx counts as "http works" -- 3xx (often
# http-to-https redirects), 4xx (e.g. Cloudflare 400 on plain HTTP to TLS
# port), and 5xx do NOT suppress the https probe.
http_succeeded = {} # key -> bool, set when http result arrives
deferred_https = {} # key -> result, awaiting http verdict

Expand All @@ -318,7 +312,8 @@ async def resolve_https(key, result):
# Paired OPEN_TCP_PORT probe
is_http = result.url == port_probes[key]["http"]
if is_http:
http_succeeded[key] = result.success and result.response is not None and result.response.status != 0
status = result.response.status if result.response is not None else 0
http_succeeded[key] = result.success and 200 <= status < 300
await self._process_result(result, stdin[result.url])
# If https for this key arrived first and was buffered, resolve it now
pending = deferred_https.pop(key, None)
Expand Down
Loading