diff options
Diffstat (limited to 'core/java/android/service/autofill/AutofillService.java')
-rw-r--r-- | core/java/android/service/autofill/AutofillService.java | 130 |
1 files changed, 4 insertions, 126 deletions
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java index b062dc3c18f7..a80ef032e68f 100644 --- a/core/java/android/service/autofill/AutofillService.java +++ b/core/java/android/service/autofill/AutofillService.java @@ -51,7 +51,6 @@ import com.android.internal.os.SomeArgs; * Settings screen). * </ol> * - * <a name="BasicUsage"></a> * <h3>Basic usage</h3> * * <p>The basic autofill process is defined by the workflow below: @@ -123,14 +122,12 @@ import com.android.internal.os.SomeArgs; * each {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} received - if it * doesn't, the request will eventually time out and be discarded by the Android System. * - * <a name="SavingUserData"></a> * <h3>Saving user data</h3> * * <p>If the service is also interested on saving the data filled by the user, it must set a * {@link SaveInfo} object in the {@link FillResponse}. See {@link SaveInfo} for more details and * examples. * - * <a name="UserAuthentication"></a> * <h3>User authentication</h3> * * <p>The service can provide an extra degree of security by requiring the user to authenticate @@ -167,7 +164,6 @@ import com.android.internal.os.SomeArgs; * credentials in "vaults": the first response would contain fake datasets with the vault names, * and the subsequent response would contain the app credentials stored in that vault. * - * <a name="DataPartioning"></a> * <h3>Data partitioning</h3> * * <p>The autofillable views in a screen should be grouped in logical groups called "partitions". @@ -183,18 +179,11 @@ import com.android.internal.os.SomeArgs; * should not contain fields for username, password, and credit card information. The reason for * this rule is that a malicious app could draft a view structure where the credit card fields * are not visible, so when the user selects a dataset from the username UI, the credit card info is - * released to the application without the user knowledge. Similarly, it's recommended to always + * released to the application without the user knowledge. Similar, it's recommended to always * protect a dataset that contains sensitive information by requiring dataset authentication - * (see {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}), and to include - * info about the "primary" field of the partition in the custom presentation for "secondary" - * fields — that would prevent a malicious app from getting the "primary" fields without the - * user realizing they're being released (for example, a malicious app could have fields for a - * credit card number, verification code, and expiration date crafted in a way that just the latter - * is visible; by explicitly indicating the expiration date is related to a given credit card - * number, the service would be providing a visual clue for the users to check what would be - * released upon selecting that field). + * (see {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}). * - * <p>When the service detects that a screen has multiple partitions, it should return a + * <p>When the service detects that a screen have multiple partitions, it should return a * {@link FillResponse} with just the datasets for the partition that originated the request (i.e., * the partition that has the {@link android.app.assist.AssistStructure.ViewNode} whose * {@link android.app.assist.AssistStructure.ViewNode#isFocused()} returns {@code true}); then if @@ -247,44 +236,6 @@ import com.android.internal.os.SomeArgs; * <p>When the service returns multiple {@link FillResponse}, the last one overrides the previous; * that's why the {@link SaveInfo} in the 2nd request above has the info for both partitions. * - * <a name="PackageVerification"></a> - * <h3>Package verification</h3> - * - * <p>When autofilling app-specific data (like username and password), the service must verify - * the authenticity of the request by obtaining all signing certificates of the app being - * autofilled, and only fulfilling the request when they match the values that were - * obtained when the data was first saved — such verification is necessary to avoid phishing - * attempts by apps that were sideloaded in the device with the same package name of another app. - * Here's an example on how to achieve that by hashing the signing certificates: - * - * <pre class="prettyprint"> - * private String getCertificatesHash(String packageName) throws Exception { - * PackageManager pm = mContext.getPackageManager(); - * PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); - * ArrayList<String> hashes = new ArrayList<>(info.signatures.length); - * for (Signature sig : info.signatures) { - * byte[] cert = sig.toByteArray(); - * MessageDigest md = MessageDigest.getInstance("SHA-256"); - * md.update(cert); - * hashes.add(toHexString(md.digest())); - * } - * Collections.sort(hashes); - * StringBuilder hash = new StringBuilder(); - * for (int i = 0; i < hashes.size(); i++) { - * hash.append(hashes.get(i)); - * } - * return hash.toString(); - * } - * </pre> - * - * <p>If the service did not store the signing certificates data the first time the data was saved - * — for example, because the data was created by a previous version of the app that did not - * use the Autofill Framework — the service should warn the user that the authenticity of the - * app cannot be confirmed (see an example on how to show such warning in the - * <a href="#WebSecurityDisclaimer">Web security</a> section below), and if the user agrees, - * then the service could save the data from the signing ceriticates for future use. - * - * <a name="IgnoringViews"></a> * <h3>Ignoring views</h3> * * <p>If the service find views that cannot be autofilled (for example, a text field representing @@ -292,79 +243,6 @@ import com.android.internal.os.SomeArgs; * calling {@link FillResponse.Builder#setIgnoredIds(AutofillId...)} so the system does not trigger * a new {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} when these views are * focused. - * - * <a name="WebSecurity"></a> - * <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 != null && !idn.isTopPrivateDomain()) { - * idn = idn.parent(); - * } - * return idn == null ? null : idn.toString(); - * } - * </pre> - * - * <a name="WebSecurityDisclaimer"></a> - * <p>If the association between the web domain and app package cannot be verified through the steps - * above, but the service thinks that it is appropriate to fill persisted credentials that are - * stored for the web domain, the service should warn the user about the potential data - * leakage first, and ask for 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 selects 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, with 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 { private static final String TAG = "AutofillService"; @@ -509,7 +387,7 @@ public abstract class AutofillService extends Service { * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)}) * 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#getText()} or other methods, there is no * guarantee such method will return the most recent value of the field. |