chromium/android_webview/docs/cors-and-webview-api.md

# CORS and WebView API

## What is CORS?

[Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
is a well-established security feature to protect data from unexpected
cross-origin accesses.

## Purpose of this document
WebView provides some APIs that change the CORS behaviors, but details are not
explained in the API documents. This document aims to clarify such detailed
behaviors and implementation details to give WebView and chromium developers
hints to keep consistent behaviors among making code changes.

## TL;DR for new developers
If you are working on new WebView applications and finding a way to load local
resources, we recommend that you use [WebViewAssetLoader](https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader)
as using other Android specific schemes is not covered by the open web platform
standards, and behavior details for new web features might be undefined or
changed. Using the WebViewAssetLoader API to load local resource on virtual
http/https URLs avoids these compatibility issues and allows the standard web
security model to apply.

## Android or WebView specific features

### intent:// URLs
`intent://` URLs are used to send an [Android Intent](https://developer.android.com/guide/components/intents-filters.html)
via a web link. A site can provide an `intent://` link for users so that users
can launch an Android application through the link.
See [Android Intents with Chrome](https://developer.chrome.com/multidevice/android/intents)
for details.

This is allowed only for the top-level navigation. If the site has a link to
an `intent://` URL for an iframe, such frame navigation will be just blocked.

Also, the page can not use such `intent://` URLs for sub-resources. For
instance, image loading for `intent://` URLs and making requests via
XMLHttpRequest or Fetch API just fail. JavaScript APIs will fail with an error
(ex. error callback, rejected promise, etc).

### content:// URLs
`content://` URLs are used to access resources provided via [Android Content Providers](https://developer.android.com/guide/topics/providers/content-providers).
The access should be permitted via [setAllowContentAccess](https://developer.android.com/reference/android/webkit/WebSettings#setAllowContentAccess(boolean))
API beforehand.

`content://` pages can contain iframes that load `content://` pages, but the
parent frame can not access into the iframe contents. Also only `content://`
pages can specify `content://` URLs for sub-resources.

However, even pages loaded from `content://` can not make any CORS-enabled
requests such as XMLHttpRequest to other `content://` URLs as each one is
assumed to belong to an [opaque origin](https://html.spec.whatwg.org/multipage/origin.html#concept-origin-opaque).
See also `setAllowFileAccessFromFileURLs` and
`setAllowUniversalAccessFromFileURLs` sections as they can relax this default
rule.

Pages loaded with any scheme other than `content://` can't load `content://`
page in iframes and they can not specify `content://` URLs for sub-resources.

### file:///android\_{asset,res}/ URLs
Android assets and resources are accessible using `file:///android_asset/` and
`file:///android_res/` URLs. WebView handles these special `file://` URLs as it
does other `file://` URLs. Only difference is these special paths are accessible
even if `setAllowFileAccess` is called with `false`. Even so, still CORS-enabled
requests are not permitted until these are explicitly permitted by
`setAllowFileAccessFromFileURLs`.

*** note
**Note:** `file:///android_asset,res}/` URLs are discouraged. Apps are
encouraged to use [WebViewAssetLoader](https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader)
instead, for better compatibility with the Same-Origin policy.
***

## WebView APIs

### setAllowFileAccessFromFileURLs
When this API is called with `true`, URLs starting with `content://` and
`file://` will have a scheme based origin, such as `content://` or `file://`
rather than `null`. But they don't have `host`:`port` parts in the origin as
these two are undefined concepts for these schemes. Thus, this origin is not
fully compatible with the [spec](https://fetch.spec.whatwg.org/#origin-header).

With this relaxed origin rule, URLs starting with `content://` and `file://`
can access resources that have the same relaxed origin over XMLHttpRequest.
For instance, `file://foo` can make an XMLHttpRequest to `file://bar`.
Developers need to be careful so that a user provided data do not run in
`content://` as it will allow the user's code to access arbitrary `content://`
URLs those are provided by other applications. It will cause a serious security
issue.

Regardless of this API call, [Fetch API](https://fetch.spec.whatwg.org/#fetch-api)
does not allow to access `content://` and `file://` URLs.

The requests from service workers also don't care for this setting.

*** note
**Note:** `setAllowFileAccessFromFileURLs` is deprecated in API level 30.
***

### setAllowUniversalAccessFromFileURLs
When this API is called with `true`, URLs starting with file:// will have a
scheme based origin, and can access other scheme based URLs over XMLHttpRequest.
For instance, `file://foo` can make an XMLHttpRequest to `content://bar`,
`http://example.com/`, and `https://www.google.com/`. So developers need to
manage data running under the `file://` scheme as it allows powerful permissions
beyond the public web's CORS policy.

Regardless of this API call, [Fetch API](https://fetch.spec.whatwg.org/#fetch-api)
does not allow to access `content://` and `file://` URLs.

The requests from service workers also don't care for this setting.

*** note
**Note:** `setAllowUniversalAccessFromFileURLs` is deprecated in API level 30.
***

### shouldInterceptRequest
Custom scheme should not be permitted for CORS-enabled requests usually.
However, when `shouldInterceptRequest` is used, the API allows developers to
handle CORS-enabled requests over custom schemes.

When a custom scheme is used, `*` or `null` should appear in the
`Access-Control-Allow-Origin` response header as such custom scheme is
processed as an [opaque origin](https://html.spec.whatwg.org/multipage/origin.html#concept-origin-opaque).