Adds SafetyNet safebrowsing API for Android

This commit is contained in:
Serg
2022-11-29 09:15:24 -05:00
parent 107d80eced
commit 1e987ac14b
8 changed files with 188 additions and 3 deletions
@@ -80,6 +80,7 @@ import org.chromium.chrome.R;
import org.chromium.chrome.browser.ApplicationLifetime;
import org.chromium.chrome.browser.BraveAdFreeCalloutDialogFragment;
import org.chromium.chrome.browser.BraveAdaptiveCaptchaUtils;
import org.chromium.chrome.browser.BraveConfig;
import org.chromium.chrome.browser.BraveFeatureUtil;
import org.chromium.chrome.browser.BraveHelper;
import org.chromium.chrome.browser.BraveRelaunchUtils;
@@ -146,6 +147,8 @@ import org.chromium.chrome.browser.privacy.settings.BravePrivacySettings;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.rate.RateDialogFragment;
import org.chromium.chrome.browser.rate.RateUtils;
import org.chromium.chrome.browser.safe_browsing.SafeBrowsingBridge;
import org.chromium.chrome.browser.safe_browsing.SafeBrowsingState;
import org.chromium.chrome.browser.set_default_browser.BraveSetDefaultBrowserUtils;
import org.chromium.chrome.browser.set_default_browser.OnBraveSetDefaultBrowserListener;
import org.chromium.chrome.browser.settings.BraveNewsPreferences;
@@ -182,6 +185,8 @@ import org.chromium.chrome.browser.vpn.wireguard.WireguardConfigUtils;
import org.chromium.components.browser_ui.settings.SettingsLauncher;
import org.chromium.components.embedder_support.util.UrlConstants;
import org.chromium.components.embedder_support.util.UrlUtilities;
import org.chromium.components.safe_browsing.BraveSafeBrowsingApiHandler;
import org.chromium.components.safe_browsing.SafeBrowsingApiBridge;
import org.chromium.components.search_engines.TemplateUrl;
import org.chromium.components.user_prefs.UserPrefs;
import org.chromium.content_public.browser.WebContents;
@@ -235,6 +240,8 @@ public abstract class BraveActivity<C extends ChromeActivityComponent> extends C
private static final List<String> yandexRegions =
Arrays.asList("AM", "AZ", "BY", "KG", "KZ", "MD", "RU", "TJ", "TM", "UZ");
private BraveSafeBrowsingApiHandler mBraveSafeBrowsingApiHandler;
private String mPurchaseToken = "";
private String mProductId = "";
private boolean mIsVerification;
@@ -293,6 +300,9 @@ public abstract class BraveActivity<C extends ChromeActivityComponent> extends C
}
updateWalletBadgeVisibility();
}
if (SafeBrowsingBridge.getSafeBrowsingState() != SafeBrowsingState.NO_SAFE_BROWSING) {
mBraveSafeBrowsingApiHandler.initSafeBrowsing();
}
}
@Override
@@ -765,6 +775,18 @@ public abstract class BraveActivity<C extends ChromeActivityComponent> extends C
PostTask.postTask(
TaskTraits.BEST_EFFORT_MAY_BLOCK, () -> { BraveStatsUtil.removeShareStatsFile(); });
if (mBraveSafeBrowsingApiHandler == null) {
mBraveSafeBrowsingApiHandler =
new BraveSafeBrowsingApiHandler(this, BraveConfig.SAFEBROWSING_API_KEY);
SafeBrowsingApiBridge.setHandler(mBraveSafeBrowsingApiHandler);
SafeBrowsingApiBridge.ensureInitialized();
}
}
@Override
public void onPause() {
super.onPause();
mBraveSafeBrowsingApiHandler.shutdownSafeBrowsing();
}
@Override
@@ -276,7 +276,7 @@ public class BravePrivacySettings extends PrivacySettings implements ConnectionE
removePreferenceIfPresent(PREF_SYNC_AND_SERVICES_LINK);
removePreferenceIfPresent(PREF_NETWORK_PREDICTIONS);
removePreferenceIfPresent(PREF_PRIVACY_SANDBOX);
removePreferenceIfPresent(PREF_SAFE_BROWSING);
// removePreferenceIfPresent(PREF_SAFE_BROWSING);
if (mCookieListOptInPageAndroidHandler != null) {
mCookieListOptInPageAndroidHandler.shouldShowDialog(shouldShowDialog -> {
@@ -0,0 +1,129 @@
/* Copyright (c) 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.chromium.components.safe_browsing;
import android.app.Activity;
import android.content.pm.ApplicationInfo;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.safetynet.SafeBrowsingThreat;
import com.google.android.gms.safetynet.SafetyNet;
import com.google.android.gms.safetynet.SafetyNetApi;
import com.google.android.gms.tasks.OnSuccessListener;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.chromium.base.ContextUtils;
public class BraveSafeBrowsingApiHandler implements SafeBrowsingApiHandler {
private static final long DEFAULT_CHECK_DELTA = 10;
private static final String SAFE_METADATA = "{}";
private static final String TAG = "BraveSafeBrowsingApiHandler";
private Observer mObserver;
private Activity mActivity;
private String mApiKey;
private boolean mInitialized;
public BraveSafeBrowsingApiHandler(Activity activity, String apiKey) {
mActivity = activity;
mApiKey = apiKey;
}
@Override
public boolean init(Observer observer) {
mObserver = observer;
return true;
}
@Override
public void startUriLookup(final long callbackId, String uri, int[] threatsOfInterest) {
if (mActivity == null || !mInitialized) {
return;
}
SafetyNet.getClient(ContextUtils.getApplicationContext())
.lookupUri(uri, mApiKey, threatsOfInterest)
.addOnSuccessListener(mActivity,
sbResponse -> {
try {
String metadata = SAFE_METADATA;
if (!sbResponse.getDetectedThreats().isEmpty()) {
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < sbResponse.getDetectedThreats().size();
i++) {
JSONObject jsonObj = new JSONObject();
jsonObj.put("threat_type",
String.valueOf(sbResponse.getDetectedThreats()
.get(i)
.getThreatType()));
jsonArray.put(jsonObj);
}
JSONObject finalObj = new JSONObject();
finalObj.put("matches", jsonArray);
metadata = finalObj.toString();
}
if (mObserver != null) {
mObserver.onUrlCheckDone(callbackId, SafeBrowsingResult.SUCCESS,
metadata, DEFAULT_CHECK_DELTA);
}
} catch (JSONException e) {
}
})
.addOnFailureListener(mActivity, e -> {
if (!isDebuggable()) {
return;
}
// An error occurred while communicating with the service.
if (e instanceof ApiException) {
// An error with the Google Play Services API contains some
// additional details.
ApiException apiException = (ApiException) e;
org.chromium.base.Log.d(TAG,
"Error: "
+ CommonStatusCodes.getStatusCodeString(
apiException.getStatusCode()));
// Note: If the status code, apiException.getStatusCode(),
// is SafetyNetStatusCode.SAFE_BROWSING_API_NOT_INITIALIZED,
// you need to call initSafeBrowsing(). It means either you
// haven't called initSafeBrowsing() before or that it needs
// to be called again due to an internal error.
} else {
// A different, unknown type of error occurred.
org.chromium.base.Log.d(TAG, "Error: " + e.getMessage());
}
});
}
@Override
public boolean startAllowlistLookup(final String uri, int threatType) {
return false;
}
public void initSafeBrowsing() {
SafetyNet.getClient(mActivity).initSafeBrowsing();
mInitialized = true;
}
public void shutdownSafeBrowsing() {
if (!mInitialized) {
return;
}
SafetyNet.getClient(ContextUtils.getApplicationContext()).shutdownSafeBrowsing();
}
private boolean isDebuggable() {
if (mActivity == null) {
return false;
}
return 0 != (mActivity.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE);
}
}