Skip to content

App-owned remote image loader for exact ATS failure classification #1

Description

@tabmail-kmyi

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

  • The bytes inspected by TabMail are the same bytes rendered by WebKit.
  • Each remote resource produces at most one network request.
  • ATS/PFS rejection is distinguishable from 404, DNS/offline, auth, timeout, and invalid-image failures.
  • Routine failures remain silent.
  • The remote-image timeout is explicitly bounded and materially shorter than the current WebKit behavior; timeout remains routine/silent and cannot trigger the ATS notice.
  • An ATS-specific notice, if retained as the product decision, uses the exact classified failure rather than timing or Resource Timing heuristics.
  • No remote image blocks first text paint.
  • Existing render security canaries and the full iOS suite pass, with simulator/device coverage for the new loader.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    deferredOpen work intentionally deferred by owner decisionenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions