Skip to content

Commit

Permalink
Display warning page for malicious sites
Browse files Browse the repository at this point in the history
  • Loading branch information
CrisBarreiro committed Dec 19, 2024
1 parent ef6e36e commit 7232199
Show file tree
Hide file tree
Showing 15 changed files with 486 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,9 @@ class BrowserTabFragment :
private val errorView
get() = binding.includeErrorView

private val warningView
get() = binding.maliciousSiteWarningLayout

private val sslErrorView
get() = binding.sslErrorWarningLayout

Expand Down Expand Up @@ -1371,6 +1374,26 @@ class BrowserTabFragment :
errorView.errorLayout.show()
}

private fun showWarning(url: Uri) {
webViewContainer.gone()
newBrowserTab.newTabLayout.gone()
newBrowserTab.newTabContainerLayout.gone()
sslErrorView.gone()
// TODO (cbarreiro) we should probably define a new view mode
omnibar.setViewMode(Omnibar.ViewMode.Error)
webView?.onPause()
webView?.hide()
warningView.bind(/*handler, errorResponse*/) /*{ action ->
viewModel.onSSLCertificateWarningAction(action, errorResponse.url)
}*/
warningView.show()
// warningView.leaveSiteButton.setOnClickListener {
// viewModel.closeCurrentTab()
// // TODO (cbarreiro) Fix, not working
// renderer.showNewTab()
// }
}

private fun showSSLWarning(
handler: SslErrorHandler,
errorResponse: SslErrorResponse,
Expand Down Expand Up @@ -1711,6 +1734,7 @@ class BrowserTabFragment :
)

is Command.WebViewError -> showError(it.errorType, it.url)
is Command.WebViewWarningMaliciousSite -> showWarning(it.url)
is Command.SendResponseToJs -> contentScopeScripts.onResponse(it.data)
is Command.SendResponseToDuckPlayer -> duckPlayerScripts.onResponse(it.data)
is Command.WebShareRequest -> webShareRequest.launch(it.data)
Expand Down Expand Up @@ -4006,7 +4030,7 @@ class BrowserTabFragment :
viewModel.onCtaShown()
}

private fun showNewTab() {
fun showNewTab() {
newTabPageProvider.provideNewTabPageVersion().onEach { newTabPage ->
if (newBrowserTab.newTabContainerLayout.childCount == 0) {
newBrowserTab.newTabContainerLayout.addView(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ import com.duckduckgo.app.browser.commands.Command.ShowWebPageTitle
import com.duckduckgo.app.browser.commands.Command.ToggleReportFeedback
import com.duckduckgo.app.browser.commands.Command.WebShareRequest
import com.duckduckgo.app.browser.commands.Command.WebViewError
import com.duckduckgo.app.browser.commands.Command.WebViewWarningMaliciousSite
import com.duckduckgo.app.browser.commands.NavigationCommand
import com.duckduckgo.app.browser.customtabs.CustomTabPixelNames
import com.duckduckgo.app.browser.duckplayer.DUCK_PLAYER_FEATURE_NAME
Expand Down Expand Up @@ -3187,6 +3188,11 @@ class BrowserTabViewModel @Inject constructor(
command.postValue(WebViewError(errorType, url))
}

override fun onReceivedMaliciousSiteWarning(url: Uri) {
// TODO (cbarreiro): Fire pixel
command.postValue(WebViewWarningMaliciousSite(url))
}

override fun recordErrorCode(
error: String,
url: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ import com.duckduckgo.history.api.NavigationHistory
import com.duckduckgo.privacy.config.api.AmpLinks
import com.duckduckgo.subscriptions.api.Subscriptions
import com.duckduckgo.user.agent.api.ClientBrandHintProvider
import com.google.android.material.snackbar.Snackbar
import java.net.URI
import javax.inject.Inject
import kotlinx.coroutines.*
Expand Down Expand Up @@ -159,7 +158,7 @@ class BrowserWebViewClient @Inject constructor(
try {
Timber.v("shouldOverride webViewUrl: ${webView.url} URL: $url")
webViewClientListener?.onShouldOverride()
if (requestInterceptor.shouldOverrideUrlLoading(webView, url, isForMainFrame)) {
if (requestInterceptor.shouldOverrideUrlLoading(webViewClientListener, url, isForMainFrame)) {
return true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ interface WebViewClientListener {
fun linkOpenedInNewTab(): Boolean
fun isActiveTab(): Boolean
fun onReceivedError(errorType: WebViewErrorResponse, url: String)
fun onReceivedMaliciousSiteWarning(url: Uri)
fun recordErrorCode(error: String, url: String)
fun recordHttpErrorCode(statusCode: Int, url: String)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import com.duckduckgo.httpsupgrade.api.HttpsUpgrader
import com.duckduckgo.privacy.config.api.Gpc
import com.duckduckgo.request.filterer.api.RequestFilterer
import com.duckduckgo.user.agent.api.UserAgentProvider
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.withContext
import timber.log.Timber

Expand All @@ -63,7 +62,7 @@ interface RequestInterceptor {

@WorkerThread
fun shouldOverrideUrlLoading(
webView: WebView,
webViewClientListener: WebViewClientListener?,
url: Uri,
isForMainFrame: Boolean,
): Boolean
Expand Down Expand Up @@ -108,9 +107,9 @@ class WebViewRequestInterceptor(
val url: Uri? = request.url

maliciousSiteBlockerWebViewIntegration.shouldIntercept(request, documentUri) {
handleSiteBlocked(webView)
handleSiteBlocked(webViewClientListener, url)
}?.let {
handleSiteBlocked(webView)
handleSiteBlocked(webViewClientListener, url)
return it
}

Expand Down Expand Up @@ -179,22 +178,22 @@ class WebViewRequestInterceptor(
return getWebResourceResponse(request, documentUrl, null)
}

override fun shouldOverrideUrlLoading(webView: WebView, url: Uri, isForMainFrame: Boolean): Boolean {
override fun shouldOverrideUrlLoading(webViewClientListener: WebViewClientListener?, url: Uri, isForMainFrame: Boolean): Boolean {
if (maliciousSiteBlockerWebViewIntegration.shouldOverrideUrlLoading(
url,
isForMainFrame,
) {
handleSiteBlocked(webView)
handleSiteBlocked(webViewClientListener, url)
}
) {
handleSiteBlocked(webView)
handleSiteBlocked(webViewClientListener, url)
return true
}
return false
}

private fun handleSiteBlocked(webView: WebView) {
Snackbar.make(webView, "Site blocked", Snackbar.LENGTH_SHORT).show()
private fun handleSiteBlocked(webViewClientListener: WebViewClientListener?, url: Uri?) {
url?.let { webViewClientListener?.onReceivedMaliciousSiteWarning(it) }
}

private fun getWebResourceResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ sealed class Command {
val url: String,
) : Command()

data class WebViewWarningMaliciousSite(
val url: Uri,
) : Command()

// TODO (cbarreiro) Rename to SendResponseToCSS
data class SendResponseToJs(val data: JsCallbackData) : Command()
data class SendResponseToDuckPlayer(val data: JsCallbackData) : Command()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2024 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.duckduckgo.app.browser.webview

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.FrameLayout
import com.duckduckgo.app.browser.databinding.ViewMaliciousSiteBlockedWarningBinding
import com.duckduckgo.common.ui.view.gone
import com.duckduckgo.common.ui.view.show
import com.duckduckgo.common.ui.viewbinding.viewBinding

class MaliciousSiteBlockedWarningLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0,
) : FrameLayout(context, attrs, defStyle) {

sealed class Action {
data object VisitSite : Action()
data object LeaveSite : Action()
}

private val binding: ViewMaliciousSiteBlockedWarningBinding by viewBinding()

fun bind() {
resetViewState()

with(binding) {
setListeners()
}
}

private fun resetViewState() {
with(binding) {
advancedCTA.show()
advancedGroup.gone()
}
}

private fun setListeners() {
with(binding) {
advancedCTA.setOnClickListener {
advancedCTA.gone()
advancedGroup.show()
errorLayout.post {
errorLayout.fullScroll(View.FOCUS_DOWN)
}
}
}
}
}
105 changes: 105 additions & 0 deletions app/src/main/res/drawable/malware_site_128.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<!--
~ Copyright (c) 2024 DuckDuckGo
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="128dp"
android:height="97dp"
android:viewportWidth="128"
android:viewportHeight="97">
<path
android:pathData="M16.91,31.55C16.33,30.96 16.33,30.02 16.91,29.43C17.5,28.85 18.44,28.85 19.03,29.43L20.96,31.37L22.89,29.43C23.47,28.85 24.42,28.85 25,29.43C25.59,30.02 25.59,30.96 25,31.55L23.07,33.48L25,35.41C25.59,36 25.59,36.94 25,37.53C24.42,38.11 23.47,38.11 22.89,37.53L20.96,35.59L19.03,37.53C18.44,38.11 17.5,38.11 16.91,37.53C16.33,36.94 16.33,36 16.91,35.41L18.84,33.48L16.91,31.55Z"
android:strokeAlpha="0.2"
android:fillColor="#888888"
android:fillAlpha="0.2"/>
<path
android:pathData="M0.58,53.41C-0,52.83 -0,51.88 0.58,51.3C1.17,50.71 2.11,50.71 2.7,51.3L3.99,52.59L5.28,51.3C5.86,50.71 6.81,50.71 7.39,51.3C7.98,51.88 7.98,52.83 7.39,53.41L6.1,54.7L7.39,55.99C7.98,56.58 7.98,57.52 7.39,58.11C6.81,58.69 5.86,58.69 5.28,58.11L3.99,56.81L2.69,58.11C2.11,58.69 1.16,58.69 0.58,58.11C-0,57.52 -0,56.58 0.58,55.99L1.87,54.7L0.58,53.41Z"
android:strokeAlpha="0.2"
android:fillColor="#888888"
android:fillAlpha="0.2"/>
<path
android:pathData="M105.55,37.96C104.97,37.37 104.97,36.43 105.55,35.84C106.14,35.26 107.08,35.26 107.67,35.84L108.96,37.14L110.25,35.84C110.83,35.26 111.78,35.26 112.36,35.84C112.95,36.43 112.95,37.37 112.36,37.96L111.07,39.25L112.36,40.54C112.95,41.12 112.95,42.07 112.36,42.65C111.78,43.24 110.83,43.24 110.25,42.65L108.96,41.36L107.67,42.65C107.08,43.24 106.14,43.24 105.55,42.65C104.97,42.07 104.97,41.12 105.55,40.54L106.85,39.25L105.55,37.96Z"
android:strokeAlpha="0.2"
android:fillColor="#888888"
android:fillAlpha="0.2"/>
<path
android:pathData="M124.5,54.5C123.68,54.5 123,53.83 123,53C123,52.17 123.68,51.5 124.5,51.5C125.32,51.5 126,52.17 126,53C126,53.83 125.32,54.5 124.5,54.5Z"
android:strokeAlpha="0.2"
android:fillColor="#888888"
android:fillAlpha="0.2"/>
<path
android:pathData="M24,67.5C22.9,67.5 22,66.6 22,65.5C22,64.4 22.9,63.5 24,63.5C25.1,63.5 26,64.4 26,65.5C26,66.6 25.1,67.5 24,67.5Z"
android:strokeAlpha="0.2"
android:fillColor="#888888"
android:fillAlpha="0.2"/>
<path
android:pathData="M92,51.5C94.21,51.5 96,49.71 96,47.5V26.5C96,23.19 93.31,20.5 90,20.5H86C89.31,20.5 92,23.19 92,26.5V51.5Z"
android:fillColor="#AAAAAA"/>
<path
android:pathData="M38,20.5C34.69,20.5 32,23.19 32,26.5L32,70.5C32,73.81 34.69,76.5 38,76.5H64C65.66,76.5 67,75.16 67,73.5V71.5C67,60.45 75.95,51.5 87,51.5H92V26.5C92,23.19 89.31,20.5 86,20.5L38,20.5Z"
android:fillColor="#F5F5F5"/>
<path
android:pathData="M32.03,25.89C32.01,26.09 32,26.29 32,26.5L32,70.5C32,73.81 34.69,76.5 38,76.5H64C65.66,76.5 67,75.16 67,73.5H38C36.34,73.5 35,72.16 35,70.5L35,28.5L89,28.5V51.5H92V26.5C92,23.19 89.31,20.5 86,20.5L38,20.5C34.89,20.5 32.34,22.86 32.03,25.89Z"
android:fillColor="#DDDDDD"/>
<path
android:pathData="M41,24.5C41,23.4 40.1,22.5 39,22.5C37.9,22.5 37,23.4 37,24.5C37,25.6 37.9,26.5 39,26.5C40.1,26.5 41,25.6 41,24.5Z"
android:fillColor="#000000"
android:fillAlpha="0.18"/>
<path
android:pathData="M47,24.5C47,23.4 46.1,22.5 45,22.5C43.9,22.5 43,23.4 43,24.5C43,25.6 43.9,26.5 45,26.5C46.1,26.5 47,25.6 47,24.5Z"
android:fillColor="#000000"
android:fillAlpha="0.18"/>
<path
android:pathData="M51,22.5C52.1,22.5 53,23.4 53,24.5C53,25.6 52.1,26.5 51,26.5C49.9,26.5 49,25.6 49,24.5C49,23.4 49.9,22.5 51,22.5Z"
android:fillColor="#000000"
android:fillAlpha="0.18"/>
<path
android:pathData="M81.91,39.89C82.63,39.92 83.3,40.32 83.68,40.96C84.3,42.01 83.99,43.39 82.97,44.04L82.62,44.26C81.54,44.95 80.22,45.17 78.97,44.87C77.58,44.52 76.1,44.77 74.88,45.55L65.17,51.73L72.59,56.45C72.84,56.61 73.1,56.75 73.37,56.86C72.51,57.67 71.72,58.55 71.01,59.49C70.95,59.45 70.9,59.42 70.84,59.38L62,53.75L53.15,59.38C51.93,60.16 51.05,61.41 50.72,62.85C50.43,64.14 49.66,65.25 48.56,65.95L48.22,66.17C47.19,66.81 45.86,66.49 45.23,65.43C44.84,64.8 44.8,64 45.1,63.32C45.35,62.76 44.97,62.13 44.38,62.11C43.66,62.08 42.99,61.68 42.61,61.04C41.99,59.99 42.3,58.61 43.32,57.96L43.67,57.74C44.75,57.05 46.07,56.83 47.32,57.13C48.71,57.48 50.19,57.23 51.41,56.45L52.62,55.68L58.83,51.73L49.12,45.55C47.9,44.77 46.43,44.53 45.03,44.87C43.79,45.17 42.48,44.96 41.38,44.26L41.04,44.04C40.01,43.39 39.69,42.01 40.32,40.96C40.71,40.32 41.37,39.92 42.09,39.89C42.68,39.88 43.06,39.23 42.82,38.68C42.51,38 42.56,37.21 42.94,36.57C43.57,35.51 44.91,35.18 45.93,35.83L46.28,36.05C47.36,36.75 48.14,37.86 48.44,39.15C48.77,40.59 49.65,41.84 50.87,42.62L62.01,49.71L73.14,42.62C74.36,41.84 75.24,40.59 75.57,39.15C75.86,37.86 76.63,36.75 77.73,36.05L78.07,35.83C79.1,35.19 80.43,35.51 81.06,36.57C81.45,37.2 81.49,38 81.19,38.68C80.94,39.24 81.32,39.88 81.91,39.89Z"
android:fillColor="#CCCCCC"/>
<path
android:pathData="M74.07,41.87C74.3,41.64 74.51,41.39 74.7,41.12C75.32,42.32 75.79,43.62 76.06,44.99C75.65,45.12 75.25,45.31 74.88,45.55L65.17,51.73L65.18,51.74L65.17,51.75L67.08,52.94L70.45,55.09L71.37,55.7L72.58,56.47C72.75,56.58 72.92,56.68 73.1,56.76L73.14,56.76C73.22,56.8 73.29,56.83 73.37,56.86C72.51,57.67 71.72,58.55 71.01,59.49C70.95,59.45 70.9,59.42 70.84,59.38L62,53.75L53.45,59.19C52.49,58.49 51.63,57.68 50.88,56.76C51.06,56.67 51.23,56.58 51.4,56.47L52.61,55.7L58.82,51.75L58.81,51.74L58.83,51.73L49.12,45.55C48.75,45.31 48.35,45.12 47.93,44.98C48.2,43.61 48.67,42.31 49.29,41.12C49.7,41.71 50.24,42.24 50.86,42.63L62,49.72L73.13,42.63C73.47,42.41 73.79,42.16 74.07,41.87Z"
android:fillColor="#BCBCBC"/>
<path
android:pathData="M63.69,35.5H60.34C53.68,35.5 48.49,42.05 50.4,49.3C50.8,50.83 51.64,52.21 52.72,53.33L54.97,55.68C55.48,56.21 55.77,56.92 55.77,57.67V59.03C55.77,59.84 56.4,60.5 57.18,60.5C57.49,60.5 57.78,60.31 57.91,60.03C58.21,59.39 59.08,59.39 59.37,60.03C59.52,60.31 59.79,60.5 60.11,60.5H60.54C60.85,60.5 61.13,60.31 61.27,60.03C61.57,59.39 62.44,59.39 62.73,60.03C62.88,60.31 63.15,60.5 63.46,60.5H63.89C64.21,60.5 64.49,60.31 64.63,60.03C64.93,59.39 65.79,59.39 66.09,60.03C66.23,60.31 66.51,60.5 66.82,60.5C67.6,60.5 68.23,59.84 68.23,59.03V57.67C68.23,56.92 68.52,56.21 69.03,55.68L71.28,53.33C72.36,52.21 73.19,50.83 73.6,49.3C75.51,42.05 70.32,35.5 63.66,35.5H63.69Z"
android:fillColor="#CCCCCC"/>
<path
android:pathData="M63.82,60.5H63.89C63.97,60.5 64.04,60.49 64.12,60.47C64.02,60.49 63.92,60.5 63.82,60.5Z"
android:fillColor="#AAAAAA"/>
<path
android:pathData="M65.13,59.59C65.49,59.48 65.9,59.62 66.09,60.03C66.23,60.31 66.51,60.5 66.82,60.5C67.6,60.5 68.23,59.84 68.23,59.03V57.67C68.23,56.92 68.52,56.21 69.03,55.68L71.28,53.33C72.36,52.21 73.19,50.83 73.6,49.3C75.51,42.05 70.32,35.5 63.66,35.5H60.66C67.32,35.5 72.51,42.05 70.6,49.3C70.19,50.83 69.36,52.21 68.28,53.33L66.03,55.68C65.52,56.21 65.23,56.92 65.23,57.67V59.03C65.23,59.23 65.2,59.42 65.13,59.59Z"
android:fillColor="#AAAAAA"/>
<path
android:pathData="M66.28,52.15C67.34,52.15 68.2,51.27 68.2,50.18C68.2,49.09 67.34,48.2 66.28,48.2C65.23,48.2 64.37,49.09 64.37,50.18C64.37,51.27 65.23,52.15 66.28,52.15ZM57.67,52.15C58.73,52.15 59.59,51.27 59.59,50.18C59.59,49.09 58.73,48.2 57.67,48.2C56.62,48.2 55.76,49.09 55.76,50.18C55.76,51.27 56.62,52.15 57.67,52.15ZM63.67,54.15L62.46,52.4H62.44C62.21,52.06 61.72,52.06 61.49,52.4L60.28,54.15C60,54.55 60.28,55.11 60.76,55.11H63.19C63.67,55.11 63.95,54.56 63.67,54.15Z"
android:fillColor="#999999"
android:fillType="evenOdd"/>
<path
android:pathData="M87,71.5m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0"
android:fillColor="#EB102D"/>
<path
android:pathData="M89,78.3C89,79.4 88.1,80.3 87,80.3C85.9,80.3 85,79.4 85,78.3C85,77.2 85.9,76.3 87,76.3C88.1,76.3 89,77.2 89,78.3Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M86.96,73.9C86.25,73.9 85.63,73.41 85.55,72.78L84.61,64.03C84.53,63.33 85.16,62.7 86.02,62.7H87.98C88.77,62.7 89.47,63.33 89.39,64.03L88.45,72.78C88.3,73.41 87.67,73.9 86.96,73.9Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M108.5,59.5C108.8,59.5 109.1,59.62 109.32,59.85C109.78,60.32 109.78,61.08 109.32,61.55L106.99,63.95C106.54,64.42 105.8,64.42 105.34,63.95C104.89,63.48 104.89,62.72 105.34,62.25L107.67,59.85C107.9,59.62 108.2,59.5 108.5,59.5H108.5Z"
android:fillColor="#CCCCCC"/>
<path
android:pathData="M107.33,70.3H110.83C111.47,70.3 112,70.84 112,71.5C112,72.16 111.47,72.7 110.83,72.7H107.33C106.69,72.7 106.17,72.16 106.17,71.5C106.17,70.84 106.69,70.3 107.33,70.3Z"
android:fillColor="#CCCCCC"/>
<path
android:pathData="M105.35,79.05C105.58,78.82 105.88,78.7 106.18,78.7H106.18C106.48,78.7 106.78,78.82 107,79.05L109.34,81.45C109.79,81.92 109.79,82.68 109.34,83.15C108.88,83.62 108.14,83.62 107.68,83.15L105.35,80.75C104.9,80.28 104.9,79.52 105.35,79.05Z"
android:fillColor="#CCCCCC"/>
</vector>
6 changes: 6 additions & 0 deletions app/src/main/res/layout/fragment_browser_tab.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@
android:layout_height="match_parent"
android:visibility="gone" />

<com.duckduckgo.app.browser.webview.MaliciousSiteBlockedWarningLayout
android:id="@+id/maliciousSiteWarningLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />

<RelativeLayout
android:id="@+id/browserLayout"
android:layout_width="match_parent"
Expand Down
Loading

0 comments on commit 7232199

Please sign in to comment.