0
Files
src/content/browser/blob_storage
Dominic Farolino 16b5623e6e Blink: Fix CanChangeToUrlForHistoryApi() to be spec-compliant
The `blink::CanChangeToUrlForHistoryApi()` helper takes in a target URL
and a document's current URL, and evaluates whether we can set the
latter to the former for same-document navigations. The spec equivalent
is HTML's "can have its URL rewritten" [1] algorithm.

Before this CL, that function deviated from the spec in a number of
ways:
  1. It created a SecurityOrigin out of the target URL and used it for
     same-origin checks with the document's actual origin. This is
     fraught for `about:blank/srcdoc` KURLs which don't carry their
     actual origin with them. So they're always seen as opaque, and
     `history.pushState()/replaceState()` was rejected for them. Per
     spec however, those APIs should work in those documents. This was
     discovered in https://crrev.com/c/4690242 and is fixed here.
  2. It has non-standard code that allows opaque origins to change their
     fragment. This isn't actually much of an issue, and it's documented
     that the behavior exists for compatibility reasons, but the issue
     is that at the same time, we *disallow* path mutations for URLs
     in opaque origins, even though HTML allows these modifications for
     all HTTP(S) URLs, per step (2) of the spec algorithm [1].

     This CL implements this step correctly and changes the
     corresponding security web test expectations to expect a
     path-mutating `history.pushState()` to succeed on an HTTP(S) site
     running in an opaque origin.
  3. It deferred to `EqualIgnoringPathQueryAndFragment()` for all other
     URLs, while the HTML Standard explicitly disallows path mutations
     per step (4) in the spec algorithm [1].
       a. This had the positive side-effect of allowing path mutations
          for "standard" URLs — like `chrome://`, `chrome-extension://`,
          and `chrome-error://` — that are registered specially with
          `url::AddStandardScheme()`. Chrome WebUI and extensions seem
          to rely on this behavior, and that's fine since it's a
          non-standard allowance.
       b. The negative side-effect of (a) above is that we allowed path
          mutations for even non-specially-registered URLs, like `blob:`
          URLs. For example, before this CL, Blink allowed changing
          `blob:https://example.com/{UUID-HERE}` to
          `blob:https://spoof.com@example.com/abcd`, which is
          same-origin, so the code permitted it, but it was a path
          change, which is illegal per spec. What's more is that this is
          considered a UI URL spoof, and if you did this the browser
          would change the URL bar to `about:blank#blocked` but the
          document's URL would still be updated to the spoofed URL in
          Blink; this led to really weird test expectations [2]. This
          CL fixes the behavior and those test expectations

After this CL and the fixes mentioned above, there are still two
outstanding non-standard conditions that this algorithm maintains:
  1. Allowing non-HTTP(s) opaque documents to mutate their query and
     fragment, for historical compatibility concerns that are documented
     in the code.
  2. Allowing "standard"-scheme URLs — which includes `filesystem:` and
     ones registered specially by //content embedders, like
     `chrome:`, `chrome-extension`, etc. — to change their path, query,
     and fragment, which is a much looser policy than we apply to other
     URLs.

Additionally, before this CL, because we didn't even allow `pushState()`
to be called on `about:blank` documents at all, we never had to
implement step 4 of
https://html.spec.whatwg.org/C/#url-and-history-update-steps, which
ensures that `pushState()` on `about:blank` documents are done with the
"replace" navigation mode. Now that this CL enables this to be hit, we
must implement that step to be spec compliant. Without it, tests like
`iframe-src-204-pushState-replaceState.html` would fail.

[1]: https://html.spec.whatwg.org/#can-have-its-url-rewritten
[2]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/blob_storage/blob_url_browsertest.cc;l=173-177;drc=cb17f93f3a17a6831cf90d616e23840f2ca726a5

Bug: 1239052,1465972
Change-Id: Id23d894d33c955894757d970d39a68076f2a8d5d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4701743
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Dominic Farolino <dom@chromium.org>
Reviewed-by: Charlie Reis <creis@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1177746}
2023-08-01 12:26:10 +00:00
..