Chromium Code Reviews| Index: content/public/android/java/src/org/chromium/content/browser/installedapp/InstalledAppProviderImpl.java |
| diff --git a/content/public/android/java/src/org/chromium/content/browser/installedapp/InstalledAppProviderImpl.java b/content/public/android/java/src/org/chromium/content/browser/installedapp/InstalledAppProviderImpl.java |
| index d07abed0a3f938dd176d1d87d8d89a9ea214e5ea..f31e0804a705dd24558cfa57f10294b8d38621bc 100644 |
| --- a/content/public/android/java/src/org/chromium/content/browser/installedapp/InstalledAppProviderImpl.java |
| +++ b/content/public/android/java/src/org/chromium/content/browser/installedapp/InstalledAppProviderImpl.java |
| @@ -109,10 +109,22 @@ public class InstalledAppProviderImpl implements InstalledAppProvider { |
| * @param frameUrl Returns false if the Android package does not declare association with the |
| * origin of this URL. Can be null. |
| */ |
| - private static boolean isAppInstalledAndAssociatedWithOrigin( |
| + private boolean isAppInstalledAndAssociatedWithOrigin( |
| String packageName, URI frameUrl, PackageManager pm) { |
| if (frameUrl == null) return false; |
| + // Important timing-attack prevention measure: delay by a pseudo-random amount of time, to |
| + // add significant noise to the time taken to check whether this app is installed and |
| + // related. Otherwise, it would be possible to tell whether a non-related app is installed, |
| + // based on the time this operation takes. |
| + // |
| + // Generate a 16-bit hash based on a unique device ID + the package name. |
| + short hash = PackageHash.hashForPackage(packageName); |
| + |
| + // The time delay is the low 13 bits of the hash in usec (between 0 and 8.192ms). |
|
palmer
2017/04/07 18:56:33
Pico-nit: Use "ms" consistently (not "usec").
Matt Giuca
2017/04/10 08:33:40
Not sure what you mean by this. Are you asking me
|
| + int sleepUsec = hash & 0x1fff; |
| + sleep(sleepUsec / 1000, (sleepUsec % 1000) * 1000); |
| + |
| // Early-exit if the Android app is not installed. |
| JSONArray statements; |
| try { |
| @@ -247,4 +259,20 @@ public class InstalledAppProviderImpl implements InstalledAppProvider { |
| return assetUrl.getScheme().equals(frameUrl.getScheme()) |
| && assetUrl.getAuthority().equals(frameUrl.getAuthority()); |
| } |
| + |
| + /** |
| + * Puts the current thread to sleep for a given amount of time. |
| + * |
| + * This is approximate but should at least be accurate to the millisecond. |
| + * |
| + * Protected and non-static for testing. |
| + */ |
| + protected void sleep(long millis, int nanos) { |
| + try { |
| + Thread.sleep(millis, nanos); |
| + } catch (InterruptedException e) { |
| + // Continue to interrupt the thread after this completes. |
| + Thread.currentThread().interrupt(); |
| + } |
| + } |
| } |