The following sample explicitly enables SafeBrowsing for WebViews in the AndroidManifest.xml by setting the android.webkit.WebView.EnableSafeBrowsing meta-data to true. However, in the WebView code, SafeBrowsing is disabled via WebSettings.setSafeBrowsingEnabled(false), which takes precedence over the manifest setting. This demonstrates that the manifest setting alone is not sufficient to determine whether SafeBrowsing is enabled.
<?xml version="1.0" encoding="utf-8"?><!-- SUMMARY: This AndroidManifest.xml sample enables SafeBrowsing for WebViews, but the setting is overridden and disabled in the Kotlin code. --><manifestxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><uses-permissionandroid:name="android.permission.INTERNET"/><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.MASTestApp"tools:targetApi="31"><!-- PASS: [MASTG-TEST-0399] SafeBrowsing is enabled, providing protection against known malicious URLs --><!-- But you should still check the Kotlin code since it takes precedence. --><meta-dataandroid:name="android.webkit.WebView.EnableSafeBrowsing"android:value="true"/><activityandroid:name=".MainActivityWebView"android:exported="true"android:windowSoftInputMode="adjustResize"android:theme="@style/Theme.MASTestApp"><intent-filter><actionandroid:name="android.intent.action.MAIN"/><categoryandroid:name="android.intent.category.LAUNCHER"/></intent-filter></activity></application></manifest>
packageorg.owasp.mastestappimportandroid.content.Contextimportandroid.os.Buildimportandroid.util.Logimportandroid.webkit.SafeBrowsingResponseimportandroid.webkit.WebResourceRequestimportandroid.webkit.WebViewimportandroid.webkit.WebViewClient// SUMMARY: This sample demonstrates an app that disables WebView SafeBrowsing at runtime, which takes precedence over the AndroidManifest setting.classMastgTestWebView(privatevalcontext:Context){funmastgTest(webView:WebView){webView.apply{// FAIL: [MASTG-TEST-0399] SafeBrowsing is disabled in code, overriding the manifest and removing protection against known malicious URLs.settings.safeBrowsingEnabled=falsewebViewClient=object:WebViewClient(){overridefunonSafeBrowsingHit(view:WebView,request:WebResourceRequest,threatType:Int,callback:SafeBrowsingResponse){Log.d("SafeBrowsing","Blocked URL, ${request.url}, threatType, $threatType")if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O_MR1){callback.backToSafety(true)}else{super.onSafeBrowsingHit(view,request,threatType,callback)}}}loadUrl("chrome://safe-browsing/match?type=phishing")}}}
Let's run our semgrep rule against the reverse-engineered manifest and code. The rule flags SafeBrowsing being disabled, either via the EnableSafeBrowsing meta-data set to false in the AndroidManifest.xml or via a WebSettings.setSafeBrowsingEnabled(false) call in the WebView code.
rules:-id:mastg-android-webview-safebrowsing-disabled-manifestseverity:WARNINGlanguages:-xmlmetadata:summary:ThisruledetectswhenSafeBrowsingisexplicitlydisabledforWebViewsintheAndroidManifest.xml.message:"[MASVS-CODE-4] SafeBrowsing is disabled for WebViews in the AndroidManifest (EnableSafeBrowsing set to false). This removes an important security protection against known malicious URLs."patterns:-pattern:|<meta-dataandroid:name="android.webkit.WebView.EnableSafeBrowsing"android:value="false".../>-id:mastg-android-webview-safebrowsing-disabled-codeseverity:WARNINGlanguages:-javametadata:summary:ThisruledetectswhenSafeBrowsingisexplicitlydisabledforWebViewsatruntimeviaWebSettings.setSafeBrowsingEnabled(false).message:"[MASVS-CODE-4] SafeBrowsing is disabled for WebViews in code via setSafeBrowsingEnabled(false). This takes precedence over the AndroidManifest and removes an important security protection against known malicious URLs."pattern:$WEBSETTINGS.setSafeBrowsingEnabled(false)
The test case fails because the WebView code disables SafeBrowsing via WebSettings.setSafeBrowsingEnabled(false) (reported on line 26 of the reverse-engineered code). Even though the android.webkit.WebView.EnableSafeBrowsing meta-data is set to android:value="true" in the manifest, the code setting takes precedence, so SafeBrowsing is disabled for all WebViews in the app, removing an important security layer that protects users from known malicious URLs. This is why the WebView code must be checked in addition to the manifest.
If you remove the call to WebSettings.setSafeBrowsingEnabled(false), SafeBrowsing is enabled by default and the runtime logcat shows it blocking known malicious URLs, as shown below: