Skip to content

fix(deps): use native OS certificate store for TLS on non-Windows platforms#1134

Closed
Jkker wants to merge 1 commit intovoidzero-dev:mainfrom
Jkker:fix/rustls-native-roots
Closed

fix(deps): use native OS certificate store for TLS on non-Windows platforms#1134
Jkker wants to merge 1 commit intovoidzero-dev:mainfrom
Jkker:fix/rustls-native-roots

Conversation

@Jkker
Copy link

@Jkker Jkker commented Mar 24, 2026

description below is written by opus; i've reviewed, verified, and approved the fix myself. the key is migrating to rustls-tls-native-roots to make vp usable in corporate vpn / self-signed CA / complex network conditions beyond simple / personal / home-use scenarios.

Description

The vp binary fails all HTTPS requests (downloads, registry lookups, upgrade checks) when running behind a TLS-intercepting proxy or firewall that re-signs certificates with a private CA.

Root cause: On non-Windows platforms, reqwest is configured with the rustls-tls feature, which bundles Mozilla's root CA store (webpki-roots) at compile time. This hardcoded CA set ignores any additional certificates installed in the operating system's trust store. When a network appliance re-signs TLS certificates with a private CA (common in corporate and enterprise environments), vp cannot verify any HTTPS connection.

Fix: Switch from rustls-tls to rustls-tls-native-roots in the three crates that depend on reqwest (vite_error, vite_install, vite_js_runtime). This replaces webpki-roots with rustls-native-certs, which loads certificates from the platform's native trust store at runtime:

  • macOS: Security.framework (System Keychain)
  • Linux: OpenSSL-compatible certificate directories (/etc/ssl/certs, etc.)
  • Windows: No change — already uses native-tls-vendored (SChannel)

Switching from rustls-tls to rustls-tls-native-roots

rustls-tls rustls-tls-native-roots
CA source Bundled Mozilla root CAs (compile-time) OS native trust store (runtime)
Custom/private CAs Not supported Loaded from OS keychain/cert dirs
TLS-intercepting proxies Always fails Works if proxy CA is in OS trust store
TLS library rustls (unchanged) rustls (unchanged)
Crypto backend ring/aws-lc (unchanged) ring/aws-lc (unchanged)
OS cert store dependency None security-framework (macOS), openssl-probe (Linux)

The underlying TLS library (rustls) and cryptographic backend remain identical — only the source of trusted root certificates changes.

Reproduction

  1. Run vp on any machine where HTTPS traffic is intercepted by a TLS proxy that re-signs certificates with a non-Mozilla CA
  2. Any command that makes HTTPS requests fails:
    $ vp upgrade --check
    error: Upgrade error: Failed to fetch package metadata from
    https://registry.npmjs.org/vite-plus/latest: error sending request for url
    (https://registry.npmjs.org/vite-plus/latest)
    
    $ vp env install lts
    error: Failed to download Node.js runtime: Failed to download from
    https://nodejs.org/dist/index.json: error sending request for url
    (https://nodejs.org/dist/index.json)
    
  3. The same URLs work fine with curl, node, git, and other tools that use the OS certificate store or respect SSL_CERT_FILE

Verify the issue in the binary

# Current binary uses bundled webpki-roots:
strings $(which vp) | grep -c 'webpki_roots'  # > 0

# After this fix, uses OS-native certs:
strings $(which vp) | grep -c 'webpki_roots'     # 0
strings $(which vp) | grep -c 'security-framework' # > 0 (macOS)

Changes

  • crates/vite_error/Cargo.toml: rustls-tlsrustls-tls-native-roots
  • crates/vite_install/Cargo.toml: rustls-tlsrustls-tls-native-roots
  • crates/vite_js_runtime/Cargo.toml: rustls-tlsrustls-tls-native-roots
  • Cargo.lock: replaces webpki-roots with rustls-native-certs (+ transitive deps security-framework, openssl-probe)

No Rust source code changes required.

…tforms

Switch reqwest feature from `rustls-tls` to `rustls-tls-native-roots` in
vite_error, vite_install, and vite_js_runtime crates.

`rustls-tls` bundles Mozilla's root CA store (webpki-roots) at compile time.
This means the `vp` binary can only verify certificates signed by CAs in
Mozilla's root program, ignoring any additional CAs installed in the OS
certificate store.

`rustls-tls-native-roots` uses `rustls-native-certs` to load certificates from
the platform's native trust store at runtime:
- macOS: Security.framework (System Keychain)
- Linux: OpenSSL certificate directories
- Windows: unchanged (already uses native-tls-vendored / SChannel)

This fixes TLS verification failures for users behind corporate proxies,
firewalls, or TLS inspection appliances that re-sign certificates with a
private
Switch reqwest feature from `rustls-tls` to `rustls-tls-native-roots` in
vite_error, vite_install, and vite_js_runtime crates.

`rustls-tls` bundles Mozilla's root CA store (webpki-roots)  git reset HEAD 2>&1
 git --no-pager log --oneline -3
 git --no-pager log --oneline -3 2>&1 | head -5
 git --no-pager status --short 2>&1 | tail -10
 exit
 export PATH="/opt/homebrew/opt/rustup/bin:$PATH" && git status --short 2>&1 | head -10
@netlify
Copy link

netlify bot commented Mar 24, 2026

Deploy Preview for viteplus-preview canceled.

Name Link
🔨 Latest commit 28b7dbb
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/69c321f663614e0008b342dd

@fengmk2
Copy link
Member

fengmk2 commented Mar 25, 2026

This is a duplicate of #1068

@fengmk2 fengmk2 closed this Mar 25, 2026
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