Problem
Remote images in rendered email are currently loaded directly by WKWebView. When an <img> fails, page JavaScript can observe only a generic load error—not whether the cause was an ordinary 404/DNS/authentication/invalid-image failure or App Transport Security rejecting a TLS 1.2 static-RSA connection for lack of forward secrecy.
Routine image failures are intentionally silent. That is the right product behavior, but it also means the specific ATS rejection is silent because the current WebKit subresource path does not expose an exact failure reason.
Goal
Fetch remote email images through an app-owned loader so TabMail can classify the exact transport result and give WebKit the same bytes that were inspected. This should make an ATS/PFS-specific notice possible without timers, duplicate probes, or weakening ATS.
Proposed direction
- Rewrite remote image candidates to an opaque TabMail custom-scheme URL.
- Serve that scheme with a
WKURLSchemeHandler backed by an ephemeral URLSession.
- Fetch each resource once, then pass the exact response bytes and appropriate response metadata to WebKit.
- Classify
URLError.appTransportSecurityRequiresSecureConnection separately from HTTP errors, DNS/offline failures, authentication failures, timeouts, and invalid image bytes.
- Enforce an explicit product resource timeout that is materially shorter than the current WebKit wait.
- Keep text rendering immediate; image loading remains asynchronous.
- Define redirect, cookie, referrer, user-agent, cancellation, cache, response-size, MIME, and decode policies explicitly.
Coverage must include:
src, srcset, and <picture>/<source>
- CSS
background-image
- relative URLs and redirects
- animated GIF/WebP/AVIF and SVG
- collapsed quotes/invites and hidden
.eml sections
- WebKit data-store/cookie behavior
- CSP support for the custom scheme
- cancellation and view reuse
- tracking guarantees: exactly one remote request per resource
Acceptance criteria
Non-goals
- HEAD/preflight followed by a second WebKit fetch
- timer or Resource Timing heuristics
- retrying failed resources
- adding ATS exceptions or weakening TLS
- using
shouldAllowDeprecatedTLS, which concerns TLS-version deprecation rather than the forward-secrecy failure measured here
References
Problem
Remote images in rendered email are currently loaded directly by
WKWebView. When an<img>fails, page JavaScript can observe only a generic load error—not whether the cause was an ordinary 404/DNS/authentication/invalid-image failure or App Transport Security rejecting a TLS 1.2 static-RSA connection for lack of forward secrecy.Routine image failures are intentionally silent. That is the right product behavior, but it also means the specific ATS rejection is silent because the current WebKit subresource path does not expose an exact failure reason.
Goal
Fetch remote email images through an app-owned loader so TabMail can classify the exact transport result and give WebKit the same bytes that were inspected. This should make an ATS/PFS-specific notice possible without timers, duplicate probes, or weakening ATS.
Proposed direction
WKURLSchemeHandlerbacked by an ephemeralURLSession.URLError.appTransportSecurityRequiresSecureConnectionseparately from HTTP errors, DNS/offline failures, authentication failures, timeouts, and invalid image bytes.Coverage must include:
src,srcset, and<picture>/<source>background-image.emlsectionsAcceptance criteria
Non-goals
shouldAllowDeprecatedTLS, which concerns TLS-version deprecation rather than the forward-secrecy failure measured hereReferences
TabMail/Views/Shared/AutoSizingHTMLView.swiftTabMail/Views/Shared/EmailHTMLWrapper.swiftCompanion/Memory/Current/037-html-email-render-pipeline-autosizinghtmlview-must-stay-idempotent-adr-i.mdCompanion/Process/Current/KnownIssues/Amendments/ios-ui-004.md