Skip to content

fix(turbopack): Use rustls-tls-native-roots for system CA support #79060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: canary
Choose a base branch
from

Conversation

aberoham
Copy link

Bug Fix: Ensure rustls backend respects system-native certificate authorities

Fixes #79059

Issue:

When Next.js (specifically Turbopack's turbo-tasks-fetch module) uses reqwest with rustls as the TLS backend, it does not, by default, respect custom Certificate Authorities (CAs) that have been added to the operating system's native trust store. This is because the rustls-tls feature in reqwest typically defaults to using a bundled set of web CAs (e.g., via webpki-roots) and does not automatically load CAs from the OS.

This becomes problematic in environments where network traffic is routed through SSL-inspecting proxies (common in corporate settings) or when accessing internal HTTPS services that use certificates signed by an internal/custom CA. In such cases, turbo-tasks-fetch would fail with certificate validation errors, as it wouldn't trust the custom CA.

The native-tls backend for reqwest, on the other hand, generally does use the OS's native trust store and thus works correctly in these scenarios. The goal is to achieve consistent behavior with rustls when it's selected.

Fix:

This patch modifies the turbopack/crates/turbo-tasks-fetch/Cargo.toml to change the reqwest feature from rustls-tls to rustls-tls-native-roots for the relevant target configurations.

The rustls-tls-native-roots feature flag for reqwest enables the rustls-native-certs crate, which allows rustls to load root certificates from the platform's native certificate store. This ensures that if a custom CA is trusted by the OS, reqwest (when using rustls) will also trust it, mirroring the behavior of native-tls.

File Changed:

  • turbopack/crates/turbo-tasks-fetch/Cargo.toml

Diff:

--- a/turbopack/crates/turbo-tasks-fetch/Cargo.toml
+++ b/turbopack/crates/turbo-tasks-fetch/Cargo.toml
@@ -21,7 +21,7 @@ workspace = true
 reqwest = { workspace = true, features = ["native-tls"] }
 
 [target.'cfg(not(any(all(target_os = "windows", target_arch = "aarch64"), target_arch="wasm32")))'.dependencies]
-reqwest = { workspace = true, features = ["rustls-tls"] }
+reqwest = { workspace = true, features = ["rustls-tls-native-roots"] }
 
 [dependencies]
 anyhow = { workspace = true }

How to Reproduce/Verify (Conceptually):

While setting up a full environment with a custom CA and an HTTPS server using it can be involved, the following conceptual steps and sample code illustrate the issue:

  1. Environment Setup (Hypothetical):

    • Create a custom Certificate Authority (CA).
    • Generate a server certificate and key, signed by this custom CA.
    • Configure a simple HTTPS server to use this server certificate.
    • Add the custom CA certificate to your operating system's trust store (e.g., Keychain Access on macOS, update-ca-certificates on Linux).
  2. Sample Rust Code:
    A minimal Rust program is provided in the repro-custom-ca directory (see repro-custom-ca/src/main.rs and repro-custom-ca/Cargo.toml). This program attempts to fetch a URL using reqwest.

  3. Testing the Behavior:
    Modify repro-custom-ca/Cargo.toml to switch between reqwest features:

    • With features = ["rustls-tls"] (and default-features = false):

      reqwest = { version = "0.11", features = ["rustls-tls"], default-features = false }

      If you run cargo run in repro-custom-ca against your custom HTTPS server, reqwest (using rustls) would likely fail with a certificate validation error because it wouldn't find the custom CA in its bundled root list.

    • With features = ["rustls-tls-native-roots"] (and default-features = false) - THE FIX:

      reqwest = { version = "0.11", features = ["rustls-tls-native-roots"], default-features = false }

      Running cargo run now should succeed. reqwest (using rustls) will load the custom CA from the OS trust store, and the certificate validation will pass.

    • For comparison, with features = ["native-tls"] (and default-features = false):

      reqwest = { version = "0.11", features = ["native-tls"], default-features = false }

      This would also typically succeed, as native-tls usually respects OS-level CAs. The patch aims to make rustls behave similarly in this regard.

Conclusion:

This change ensures more consistent and robust behavior for turbo-tasks-fetch when dealing with HTTPS connections in diverse network environments, particularly those requiring custom CAs. It aligns the rustls backend's CA handling with that of native-tls and standard browser behavior.

@ijjk ijjk added the Turbopack Related to Turbopack with Next.js. label May 11, 2025
@ijjk
Copy link
Member

ijjk commented May 11, 2025

Allow CI Workflow Run

  • approve CI run for commit: a099d04

Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer

@vercel vercel deleted a comment from VoldeDoc May 12, 2025
@vercel vercel deleted a comment from VoldeDoc May 12, 2025
@lynfos
Copy link

lynfos commented May 14, 2025

Amazing. This should fix issues with font optimization failing when "netskope" is in use. Thanks!

There was an issue establishing a connection while requesting https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap

@aberoham aberoham force-pushed the fix/rustls-native-roots branch from 207cf47 to 59b5aa5 Compare May 15, 2025 17:11
Copy link

changeset-bot bot commented May 15, 2025

⚠️ No Changeset found

Latest commit: a099d04

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Turbopack Related to Turbopack with Next.js.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Turbopack rustls-tls fails to recognize system keychain certs
3 participants