fix: validate TLS certificates on the native browser network path - #34791
Open
cacieprins wants to merge 5 commits into
Open
fix: validate TLS certificates on the native browser network path#34791cacieprins wants to merge 5 commits into
cacieprins wants to merge 5 commits into
Conversation
On the CDP netstack (Chrome, Chromium, Edge), Cypress no longer passes the blanket --ignore-certificate-errors flag, which silently accepted invalid certificates and, as a side effect, prevented the browser from caching static assets across navigations. The browser now validates certificates as it does in production. Adds a `trustedCertificates` config option so users can declare a self-signed or private-CA certificate their app under test presents; each entry's SubjectPublicKeyInfo fingerprint is passed to Chrome via --ignore-certificate-errors-spki-list. Firefox, WebKit, Electron, and forceHttp1 runs are unaffected and keep the legacy behavior. Addresses #34760. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…wser network path Exercises the end-to-end plumbing on Chrome: a self-signed HTTPS origin whose leaf certificate is declared in `trustedCertificates` loads because its SPKI fingerprint reaches Chrome via --ignore-certificate-errors-spki-list, with the blanket --ignore-certificate-errors no longer passed. Deliberately does not assert the disk-cache behavior the feature restores, which is unobservable from a system test: Cypress's security-reducing launch flags load invalid certs regardless of trust, the same-renderer memory cache masks the disk cache within a spec, and the browser cache is reset between specs. That behavior is covered by lower-level verification. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replaces the .js fixture config and spec with cypress.config.ts (a plain export default, since lightweight fixtures have no node_modules to resolve `cypress` from) and a .cy.ts spec, and adds the tsconfig.json a .cy.ts fixture requires — the batteries-included preprocessor throws TsConfigNotFoundError without one (house precedent: projects/ts-proj). Records the "TypeScript for all new code" convention in AGENTS.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
cacieprins
requested review from
brian-mann and
jennifer-shehane
as code owners
September 4, 2026 18:38
…stedCertificates is additive Dropping the blanket flag on the native browser network path broke real self-signed HTTPS setups beyond caching: Chrome refuses service-worker registration on a page with a genuine certificate error, and cross-origin navigation to a hosts-mapped self-signed origin timed out (system-tests-chrome: service_worker_spec, web_security_spec). Those are user-visible breaks for a common local-dev configuration. The blanket flag now stays. `trustedCertificates` layers an --ignore-certificate-errors-spki-list on top; Chrome honors that list over the blanket flag, so a declared cert's origin is genuinely trusted and its assets cache, while undeclared origins behave exactly as before. Tightening the blanket flag can be a deliberate change in a major version. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 552a243. Configure here.
Running `yarn test web_security --browser chrome` locally let snap-shot-it prune the Firefox-gated snapshot key from __snapshots__/web_security_spec.js, and it was swept into the previous commit. CI then failed the Firefox test with "Cannot store new snapshot value". Restores the file from develop and records the gotcha in system-tests/AGENTS.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
cypress
|
||||||||||||||||||||||||||||||||||||||||
| Project |
cypress
|
| Branch Review |
claude/cypress-34760-remediation-0e5e75
|
| Run status |
|
| Run duration | 15m 42s |
| Commit |
|
| Committer | Cacie Prins |
| View all properties for this run ↗︎ | |
| Test results | |
|---|---|
|
|
0
|
|
|
13
|
|
|
1118
|
|
|
0
|
|
|
29197
|
| View all changes introduced in this branch ↗︎ | |
UI Coverage
68.06%
|
|
|---|---|
|
|
23
|
|
|
49
|
Accessibility
98.96%
|
|
|---|---|
|
|
0 critical
3 serious
2 moderate
0 minor
|
|
|
18
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Additional details
Root cause. Cypress launches every Chromium browser with
--ignore-certificate-errors. When the certificate an origin presents actually errors — a self-signed development certificate, an internal CA, or Cypress's own MITM CA on the legacy path — Chrome treats the connection like a clicked-through certificate warning and, by design, never writes anything from it to the HTTP disk cache. On the Cypress 16 default (native browser network) path this made the cache inert for any HTTPS app with an untrusted certificate: every navigation re-downloaded every static asset. This is independent of CDP interception, which the issue originally blamed; that was refuted empirically across Chrome 148–152 and the issue has been rewritten with the corrected root cause.The fix, scoped to the native browser network path (Chrome, Chromium, Edge — not
forceHttp1, Electron, Firefox, or WebKit, which are unchanged):trustedCertificatesconfiguration option lets users declare a certificate their app presents, as{ filePath },{ pem }, or a precomputed{ spki }fingerprint. Each entry's SubjectPublicKeyInfo fingerprint is passed to Chrome via--ignore-certificate-errors-spki-list. Chrome honors that list over the blanket flag, so the connection becomes genuinely trusted — and therefore cacheable — rather than merely tolerated. Chrome matches the fingerprint against any certificate in the chain the server presents, so one leaf or CA fingerprint suffices.--ignore-certificate-errorsis kept. The change is purely additive: origins you don't declare load exactly as they do today (just uncached, as before); origins you do declare gain a working browser cache.Why the blanket flag stays (for now). A stricter variant that dropped
--ignore-certificate-errorson this path was evaluated in CI. It broke real self-signed HTTPS setups on the netstack beyond caching: Chrome refuses service-worker registration on a page with a genuine certificate error, and cross-origin navigation to ahosts-mapped self-signed origin timed out (service_worker_spec,web_security_spec). Those are user-visible breaks for a common local-dev configuration and don't belong in a patch release. With the allow-mechanism now in place, tightening the blanket flag can be a deliberate, documented change in a major version.Why there is no disk-cache system test. The cache benefit is unobservable from a Cypress system test: Cypress's other launch flags load invalid certificates regardless of trust, so navigation success is not a signal; a repeat visit within a spec is served by the renderer's in-memory cache even when the disk cache is broken; and the browser cache is reset between specs. The included system test therefore guards the config → SPKI → launch plumbing end to end on real Chrome and says so explicitly. The cache behavior itself is covered by direct disk inspection and by the lower-level verification recorded on the issue.
Also in this PR: the system-test fixtures are TypeScript (a
.cy.tsfixture spec requires atsconfig.json, added), andAGENTS.mdrecords the "TypeScript for all new code" convention.Note
Medium Risk
Touches browser launch flags and TLS trust on the default Chromium network path; misconfiguration could affect which origins are trusted, though behavior is additive and scoped to declared certificates.
Overview
Adds
trustedCertificatesso Chromium browsers on the native (CDP) network path can treat selected dev/self-signed certs as genuinely trusted, restoring HTTP disk caching for those HTTPS origins instead of only tolerating cert errors via--ignore-certificate-errors.Each entry is exactly one of
{ filePath },{ pem }, or{ spki }; config validation, TypeScript types, and defaults are wired through@packages/config. At launch, entries are resolved to deduped SPKI fingerprints (packages/server/lib/util/spki.ts) and passed on the browser path as--ignore-certificate-errors-spki-list=…alongside the existing blanket ignore flag; the MITM/forceHttp1path is unchanged.16.0.1 changelog documents the fix (#34760). A Chrome-only system-test fixture exercises config → SPKI → launch plumbing. AGENTS.md notes TypeScript for new fixtures and a system-test snapshot pruning gotcha.
Reviewed by Cursor Bugbot for commit 6e5a8f1. Bugbot is set up for automated code reviews on this repo. Configure here.
Steps to test
Unit coverage (validation, SPKI derivation, launch-flag gating):
End-to-end on real Chrome (a self-signed HTTPS origin whose leaf certificate is declared in
trustedCertificates):Manual, to see the cache effect: run an e2e project on Chrome against an HTTPS origin with a self-signed certificate. Without
trustedCertificatesthe page loads, but nothing from that origin appears in the browser's disk cache. AddtrustedCertificates: [{ filePath: 'certs/server.pem' }](relative to the project root) and the origin's assets are cached and served from disk on later navigations. Confirm the launch args:--ignore-certificate-errorsis still present, and--ignore-certificate-errors-spki-list=<fingerprint>is added alongside it.How has the user experience changed?
No visual change. Behavioral: purely additive. On Chrome, Chromium, and Edge without
forceHttp1, static assets from an origin whose certificate is declared in the newtrustedCertificatesoption are now cached across navigations, so asset-heavy specs against such origins stop re-downloading everything on eachcy.visit. Origins that are not declared behave exactly as before.PR Tasks
cypress-documentation? To follow — the newtrustedCertificatesoption needs documenting.type definitions?🤖 Generated with Claude Code