Skip to content

Fix SSL certificate verification#47

Merged
liquidsec merged 6 commits into
devfrom
ssl-verify-fix
Jun 15, 2026
Merged

Fix SSL certificate verification#47
liquidsec merged 6 commits into
devfrom
ssl-verify-fix

Conversation

@liquidsec

@liquidsec liquidsec commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Hostname verification: verify_certs=True validated the certificate chain but did NOT verify the hostname. A cert valid for any domain was accepted when connecting to any other domain. Fixed by calling set_host()/set_ip() on the X509 verify params on both TLS paths (pooled and raw).
  • System CA loading: vendored OpenSSL's set_default_verify_paths() looks at a compiled-in OPENSSLDIR that doesn't exist on the host. Replaced with load_system_ca_certs() that checks SSL_CERT_FILE/SSL_CERT_DIR env vars, then probes well-known system paths. Also fixed dir-loading not being tracked, which caused an unnecessary fallback to set_default_verify_paths().
  • Timeout coverage: TLS handshakes and proxy handshakes (HTTP CONNECT, SOCKS5) were not bounded by the connect timeout. Now all phases (TCP + proxy + TLS) are wrapped in tokio::time::timeout on both pooled and raw paths. Also set HttpConnector::set_connect_timeout for the pooled path's TCP phase.
  • TLS cache key: ConnMode only keyed on proxy URL and verify_certs, so requests with different cipher strings, TLS versions, or ALPN protocols shared the same cached client. Extracted TlsKey struct (verify_certs + cipher_string + min/max TLS version + ALPN) and included it in all ConnMode variants.
  • raw_connect timeout: added timeout parameter to the raw_connect Python binding and wrapped TcpStream::connect in a timeout.
  • openssl 0.10.81: replaced deprecated as_utf8() with to_string() (4 call sites in cert info extraction).
  • Version bump: 0.8.0 -> 0.9.0 (Cargo.toml + pyproject.toml + Cargo.lock).
  • Tests: 18 Rust integration tests + 14 Python tests covering all connection types, self-signed rejection, hostname mismatch (with CA-signed cert isolation via SSL_CERT_FILE), cache isolation, and connect timeout.

- Load system CA certs explicitly instead of relying on
  set_default_verify_paths(), which fails when OpenSSL is vendored
  (compiled-in OPENSSLDIR points to nonexistent path)
- Include verify_certs in ConnMode cache key so connections with
  different verify settings don't share a cached hyper Client
- Add timeout parameter to raw_connect Python binding
- Wrap TCP connect in a timeout (was missing, causing hangs)
- Add Rust and Python tests for all connection types
F1: verify_certs=True now checks hostname (set_host/set_ip on both TLS paths)
F2: TLS and proxy handshakes bounded by connect timeout (pooled + raw paths)
F3: ConnMode cache key includes cipher_string, TLS versions, and ALPN
F4: load_system_ca_certs tracks dir loading to avoid unnecessary fallback
@ausmaster ausmaster assigned ausmaster and liquidsec and unassigned ausmaster Jun 15, 2026
@liquidsec
liquidsec merged commit ca48fb6 into dev Jun 15, 2026
15 checks passed
@ausmaster
ausmaster self-requested a review June 15, 2026 21:19
@liquidsec
liquidsec deleted the ssl-verify-fix branch June 15, 2026 21:19
@ausmaster

ausmaster commented Jun 15, 2026

Copy link
Copy Markdown

Approved btw.

liquidsec added a commit that referenced this pull request Jun 15, 2026
* chore(deps): bump http from 1.4.1 to 1.4.2

Bumps [http](https://github.com/hyperium/http) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/hyperium/http/releases)
- [Changelog](https://github.com/hyperium/http/blob/master/CHANGELOG.md)
- [Commits](hyperium/http@v1.4.1...v1.4.2)

---
updated-dependencies:
- dependency-name: http
  dependency-version: 1.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps-dev): bump ruff from 0.15.15 to 0.15.17

Bumps [ruff](https://github.com/astral-sh/ruff) from 0.15.15 to 0.15.17.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](astral-sh/ruff@0.15.15...0.15.17)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.15.17
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump version to 0.9.0

* chore(deps): bump openssl from 0.10.80 to 0.10.81 (#45)

Bumps [openssl](https://github.com/rust-openssl/rust-openssl) from 0.10.80 to 0.10.81.
- [Release notes](https://github.com/rust-openssl/rust-openssl/releases)
- [Commits](rust-openssl/rust-openssl@openssl-v0.10.80...openssl-v0.10.81)

---
updated-dependencies:
- dependency-name: openssl
  dependency-version: 0.10.81
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Fix SSL certificate verification (#47)

* Fix SSL certificate verification (verify_certs=True)

- Load system CA certs explicitly instead of relying on
  set_default_verify_paths(), which fails when OpenSSL is vendored
  (compiled-in OPENSSLDIR points to nonexistent path)
- Include verify_certs in ConnMode cache key so connections with
  different verify settings don't share a cached hyper Client
- Add timeout parameter to raw_connect Python binding
- Wrap TCP connect in a timeout (was missing, causing hangs)
- Add Rust and Python tests for all connection types

* Replace deprecated as_utf8() with to_string()

* Update Cargo.lock for 0.9.0

* Add hostname verification, timeout coverage, and TLS cache key fixes

F1: verify_certs=True now checks hostname (set_host/set_ip on both TLS paths)
F2: TLS and proxy handshakes bounded by connect timeout (pooled + raw paths)
F3: ConnMode cache key includes cipher_string, TLS versions, and ALPN
F4: load_system_ca_certs tracks dir loading to avoid unnecessary fallback

* Fix rustfmt in tls_server.rs

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
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