Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 11435f81 authored by Android Build Merger (Role)'s avatar Android Build Merger (Role) Committed by Android (Google) Code Review
Browse files

Merge "Merge "Additional documentation about Autofill / WebView security."...

Merge "Merge "Additional documentation about Autofill / WebView security." into oc-dev am: 36cbdef8 am: 7e9f379b am: 82e7dfca" into oc-mr1-dev-plus-aosp
parents 349f0297 262966aa
Loading
Loading
Loading
Loading
+71 −1
Original line number Original line Diff line number Diff line
@@ -280,6 +280,76 @@ import com.android.internal.os.SomeArgs;
 * calling {@link FillResponse.Builder#setIgnoredIds(AutofillId...)} so the system does not trigger
 * calling {@link FillResponse.Builder#setIgnoredIds(AutofillId...)} so the system does not trigger
 * a new {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} when these views are
 * a new {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} when these views are
 * focused.
 * focused.
 *
 * <h3>Web security</h3>
 *
 * <p>When handling autofill requests that represent web pages (typically
 * view structures whose root's {@link android.app.assist.AssistStructure.ViewNode#getClassName()}
 * is a {@link android.webkit.WebView}), the service should take the following steps to verify if
 * the structure can be autofilled with the data associated with the app requesting it:
 *
 * <ol>
 *   <li>Use the {@link android.app.assist.AssistStructure.ViewNode#getWebDomain()} to get the
 *       source of the document.
 *   <li>Get the canonical domain using the
 *       <a href="https://publicsuffix.org/>Public Suffix List</a> (see example below).
 *   <li>Use <a href="https://developers.google.com/digital-asset-links/">Digital Asset Links</a>
 *       to obtain the package name and certificate fingerprint of the package corresponding to
 *       the canonical domain.
 *   <li>Make sure the certificate fingerprint matches the value returned by Package Manager
 *       (see "Package verification" section above).
 * </ol>
 *
 * <p>Here's an example on how to get the canonical domain using
 * <a href="https://github.com/google/guava">Guava</a>:
 *
 * <pre class="prettyprint">
 * private static String getCanonicalDomain(String domain) {
 *   InternetDomainName idn = InternetDomainName.from(domain);
 *   while (!idn.isTopPrivateDomain() && idn != null) {
 *     idn = idn.parent();
 *   }
 *   return idn == null ? null : idn.toString();
 * }
 * </pre>
 *
 * <p>If the association between the web domain and app package cannot be verified through the steps
 * above, the service can still autofill the app, but it should warn the user about the potential
 * data leakage first, and askfor the user to confirm. For example, the service could:
 *
 * <ol>
 *   <li>Create a dataset that requires
 *       {@link Dataset.Builder#setAuthentication(android.content.IntentSender) authentication} to
 *       unlock.
 *   <li>Include the web domain in the custom presentation for the
 *       {@link Dataset.Builder#setValue(AutofillId, AutofillValue, android.widget.RemoteViews)
 *       dataset value}.
 *   <li>When the user select that dataset, show a disclaimer dialog explaining that the app is
 *       requesting credentials for a web domain, but the service could not verify if the app owns
 *       that domain. If the user agrees, then the service can unlock the dataset.
 *   <li>Similarly, when adding a {@link SaveInfo} object for the request, the service should
 *       include the above disclaimer in the {@link SaveInfo.Builder#setDescription(CharSequence)}.
 * </ol>
 *
 * <p>This same procedure could also be used when the autofillable data is contained inside an
 * {@code IFRAME}, in which case the WebView generates a new autofill context when a node inside
 * the {@code IFRAME} is focused, which the root node containing the {@code IFRAME}'s {@code src}
 * attribute on {@link android.app.assist.AssistStructure.ViewNode#getWebDomain()}. A typical and
 * legitimate use case for this scenario is a financial app that allows the user
 * to login on different bank accounts. For example, a financial app {@code my_financial_app} could
 * use a WebView that loads contents from {@code banklogin.my_financial_app.com}, which contains an
 * {@code IFRAME} node whose {@code src} attribute is {@code login.some_bank.com}. When fulfilling
 * that request, the service could add an
 * {@link Dataset.Builder#setAuthentication(android.content.IntentSender) authenticated dataset}
 * whose presentation displays "Username for some_bank.com" and
 * "Password for some_bank.com". Then when the user taps one of these options, the service
 * shows the disclaimer dialog explaining that selecting that option would release the
 * {@code login.some_bank.com} credentials to the {@code my_financial_app}; if the user agrees,
 * then the service returns an unlocked dataset with the {@code some_bank.com} credentials.
 *
 * <p><b>Note:</b> The autofill service could also whitelist well-known browser apps and skip the
 * verifications above, as long as the service can verify the authenticity of the browser app by
 * checking its signing certificate.
 */
 */
public abstract class AutofillService extends Service {
public abstract class AutofillService extends Service {
    private static final String TAG = "AutofillService";
    private static final String TAG = "AutofillService";
@@ -424,7 +494,7 @@ public abstract class AutofillService extends Service {
     * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)})
     * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)})
     * to notify the result of the request.
     * to notify the result of the request.
     *
     *
     * <p><b>NOTE: </b>to retrieve the actual value of the field, the service should call
     * <p><b>Note:</b> To retrieve the actual value of the field, the service should call
     * {@link android.app.assist.AssistStructure.ViewNode#getAutofillValue()}; if it calls
     * {@link android.app.assist.AssistStructure.ViewNode#getAutofillValue()}; if it calls
     * {@link android.app.assist.AssistStructure.ViewNode#getText()} or other methods, there is no
     * {@link android.app.assist.AssistStructure.ViewNode#getText()} or other methods, there is no
     * guarantee such method will return the most recent value of the field.
     * guarantee such method will return the most recent value of the field.
+12 −0
Original line number Original line Diff line number Diff line
@@ -2725,6 +2725,18 @@ public class WebView extends AbsoluteLayout
     * understood by the {@link android.service.autofill.AutofillService} implementations:
     * understood by the {@link android.service.autofill.AutofillService} implementations:
     *
     *
     * <ol>
     * <ol>
     *   <li>Only the HTML nodes inside a {@code FORM} are generated.
     *   <li>The source of the HTML is set using {@link ViewStructure#setWebDomain(String)} in the
     *   node representing the WebView.
     *   <li>If a web page has multiple {@code FORM}s, only the data for the current form is
     *   represented&mdash;if the user taps a field from another form, then the current autofill
     *   context is canceled (by calling {@link android.view.autofill.AutofillManager#cancel()} and
     *   a new context is created for that {@code FORM}.
     *   <li>Similarly, if the page has {@code IFRAME} nodes, they are not initially represented in
     *   the view structure until the user taps a field from a {@code FORM} inside the
     *   {@code IFRAME}, in which case it would be treated the same way as multiple forms described
     *   above, except that the {@link ViewStructure#setWebDomain(String) web domain} of the
     *   {@code FORM} contains the {@code src} attribute from the {@code IFRAME} node.
     *   <li>If the Android SDK provides a similar View, then should be set with the
     *   <li>If the Android SDK provides a similar View, then should be set with the
     *   fully-qualified class name of such view.
     *   fully-qualified class name of such view.
     *   <li>The W3C autofill field ({@code autocomplete} tag attribute) maps to
     *   <li>The W3C autofill field ({@code autocomplete} tag attribute) maps to