Skip to content

Fix Python 3.13 cert tests, add --insecure, and bound DNS threads - #4

Merged
cursor[bot] merged 3 commits into
mainfrom
cursor/py313-insecure-dns-f51a
Oct 23, 2026
Merged

cursor[bot] merged 3 commits into
mainfrom
cursor/py313-insecure-dns-f51a

Conversation

@Phantom9869

@Phantom9869 Phantom9869 commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Summary

Follow-ups after the redirect/DNS/TLS hardening on main (a8e4529).

Python 3.13 CA fixture

test_pinned_https_honours_requests_ca_bundle_and_rejects_hostname_mismatch minted a bare self-signed certificate and trusted it as its own CA. Python 3.13's default VERIFY_X509_STRICT rejects that with CA cert does not include key usage extension. The helper now builds a CA (basicConstraints=critical,CA:TRUE, keyUsage=critical,keyCertSign,cRLSign) and signs a leaf that has a SAN and serverAuth. CI runs 3.11, 3.12, and 3.13. pip-audit is unchanged.

--insecure

HTTPS certificate failures still stop the web modules (Could not fetch site ... not retrying over HTTP), which blocks pentests against self-signed appliances. --insecure is off by default and disables certificate verification for HTTPS fetches. It does not retry a certificate failure over plain HTTP. A protocol mismatch (plain HTTP on the HTTPS port) still falls back. The choice is printed on stderr, prefixed on text and Markdown reports, and stored as an INFO finding (including JSON). Documented in --help and the README.

crt.sh is a third party, so that request passes verify=True even when --insecure is set. The TLS module still does a verified handshake first to classify hostname mismatch, self-signed, and untrusted-chain findings, then an unverified handshake for expiry and protocol details.

DNS thread lifetime

resolve_ips still uses one system getaddrinfo (so /etc/hosts works) and still returns when the deadline hits. Hung lookups cannot be cancelled. A shared semaphore allows at most 16 daemon threads in libc at once, enough that a burst of slow healthy lookups finishes inside one deadline. Extra hosts wait only until their own deadline, then return []. That skip is logged and exposed as resolution_saturated / ResolverSaturated (the pipeline and the port check report it). It is not cached. Only non-empty answers are cached, so a transient EAI_AGAIN is retried on the next lookup.

set_tls_verification installs the urllib3 warning filter once per transition instead of stacking a new filter on every call.

Windows CI on 72df5ad

All six Windows jobs failed test_saturated_resolver_is_signalled_and_not_cached. An earlier test left a getaddrinfo sleeper holding one process-wide resolver slot. On Windows that slot freed between the two saturation probes, so the second probe acquired it, started a real lookup, and cleared the saturated flag. Ubuntu was fast enough that the sleeper had already exited. a490bd6 joins leftover resolver threads and keeps the pool full until both probes finish. Product saturation behavior is unchanged.

Tests

  • Python 3.11.17: 198 passed (local, before the Windows-only test change)
  • Python 3.12.3: 198 passed
  • Python 3.13.17: 198 passed
  • tests/test_net.py after the isolation fix: 12 passed
  • pip-audit --requirement requirements.txt: no known vulnerabilities

Commit dates (git log main..HEAD --format='%H %ad | %cd' --date=iso)

a490bd64957a8134d3d6a0d41c1cb52a75b971b3 2026-10-23 23:10:00 +0530 | 2026-10-23 23:10:00 +0530
72df5adab767ba03ba9631665002f79a3714701c 2026-10-23 22:30:00 +0530 | 2026-10-23 22:30:00 +0530
163f0604635844fc984cb77206b8fc02da83e2e6 2026-10-23 21:15:00 +0530 | 2026-10-23 21:15:00 +0530
Open in Web Open in Cursor 

cursoragent and others added 3 commits October 23, 2026 21:15
Python 3.13 rejects a CA certificate with no key usage extension, so the
pinned-HTTPS test now mints a real CA and a serverAuth leaf. CI runs the
suite on 3.13 as well as 3.11 and 3.12.

--insecure (default off) disables TLS certificate verification for HTTPS
fetches and the TLS handshake. Certificate failures are still not retried
over plain HTTP, and the report records that verification was disabled.

resolve_ips keeps its deadline and the system resolver, caches answers for
the scan, and will not start more than a few hung getaddrinfo threads.

Co-authored-by: Kamal Choubey <Phantom9869@users.noreply.github.com>
An empty getaddrinfo answer was cached for the rest of the scan, so one
transient EAI_AGAIN made a host look unresolvable. Cache only non-empty
answers. Raise the resolver cap to 16 and log a skip when the pool is
full, without caching it, so saturation is not reported as NXDOMAIN.

crt.sh always verifies. The TLS module still classifies a bad certificate
when --insecure is set. set_tls_verification no longer stacks a warnings
filter on every call.

Co-authored-by: Kamal Choubey <Phantom9869@users.noreply.github.com>
A leftover getaddrinfo sleeper from an earlier test held one shared
semaphore slot. On Windows that slot freed between the two saturation
probes, so the second probe started a real lookup and cleared the
saturated flag. Join those threads and hold the pool full until both
probes finish.

Co-authored-by: Kamal Choubey <Phantom9869@users.noreply.github.com>
@cursor
cursor Bot merged commit a490bd6 into main Oct 23, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants