Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intercept requests and add skeleton for malicious site detection #5369

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from

Conversation

CrisBarreiro
Copy link
Contributor

@CrisBarreiro CrisBarreiro commented Dec 9, 2024

Task/Issue URL: https://app.asana.com/0/1205008441501016/1207151848931035/f

Description

Steps to test this PR

Feature 1

  • Load a site and check you get Timber.tag("MaliciousSiteProtection").d("isMalicious $url") for all mainframe and iframe requests (only for internal builds).
  • Check you should never get 2 instances of those logs for the exact same URL

UI changes

Before After
!(Upload before screenshot) (Upload after screenshot)

Copy link
Contributor Author

CrisBarreiro commented Dec 9, 2024

@CrisBarreiro CrisBarreiro marked this pull request as ready for review December 9, 2024 10:36
@CrisBarreiro CrisBarreiro mentioned this pull request Dec 10, 2024
21 tasks
@CrisBarreiro CrisBarreiro force-pushed the feature/cris/malicious-site-protection/intercept-requests branch 2 times, most recently from 13cfb3a to 8d0f3b0 Compare December 10, 2024 10:49
@CrisBarreiro CrisBarreiro force-pushed the feature/cris/malicious-site-protection/intercept-requests branch from 8d0f3b0 to 0b7f33d Compare December 10, 2024 13:37
@CrisBarreiro CrisBarreiro force-pushed the feature/cris/malicious-site-protection/intercept-requests branch from 615f371 to 7fd8100 Compare December 11, 2024 14:03
@CrisBarreiro CrisBarreiro force-pushed the feature/cris/malicious-site-protection/intercept-requests branch from 7fd8100 to c24dff3 Compare December 11, 2024 14:12
Copy link
Contributor

@cmonfortep cmonfortep left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just testing the changes (haven't started the code review yet)

Sharing something I've found:

  • when clicking any link in this URL https://www.yahoo.com/?guccounter=1, the url changes but I don't see it in the logs.
  • After some normal browsing on a tab, testing back and forward navigation between sites, I don't see some URLs appearing, and that I can repro. (edit: actually I think this never works, and the urls I see is just some requests the site triggers)
  • I think this one is fine but just fyi, in the logs I see http://domain.com and https://domain.com (just changing schema http -> https)

Friendly reminder about updating the description of the PR to include what's included and giving some context 🙏

@@ -158,6 +164,20 @@ class BrowserWebViewClient @Inject constructor(
try {
Timber.v("shouldOverride webViewUrl: ${webView.url} URL: $url")
webViewClientListener?.onShouldOverride()

if (runBlocking {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

proposal: remove the suspend for shouldOverrideUrlLoading, and move the runBlocking inside the implementation of that method. That way we can control where exactly we need it and it's an implementation detail of that method.

@@ -63,4 +67,10 @@ class RealMaliciousSiteProtection @Inject constructor(
}
}
}

override suspend fun isMalicious(url: Uri, confirmationCallback: (isMalicious: Boolean) -> Unit): IsMaliciousResult {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proposal: implementing MaliciousSiteProtection on a different class, and leaving this one exclusively for the feature config state (since the feature state is more than just a boolean and has state). That way we can separate responsibilities, and improve cohesion, ensuring that each class has a well-defined purpose.

@@ -48,6 +49,7 @@ interface RequestInterceptor {
request: WebResourceRequest,
webView: WebView,
documentUri: Uri?,
maliciousSiteProtectionWebViewIntegration: MaliciousSiteBlockerWebViewIntegration,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific reason for passing this as a method argument rather than injecting it as a class attribute via the constructor? I would prefer the later since this is a dependency rather than a value.

webViewClientListener: WebViewClientListener?,
): WebResourceResponse? {
val url: Uri? = request.url

val confirmationCallback: (isMalicious: Boolean) -> Unit = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this will have the same implementation as in app/src/main/java/com/duckduckgo/app/browser/BrowserWebViewClient.kt L131.

Have you considered any options to don't have them duplicated?

return false
}

private fun isForIframe(request: WebResourceRequest) = request.requestHeaders["Sec-Fetch-Dest"] == "iframe" ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very familiar with detecting iframes, so just asking, how can we validate this is the right checks / we are not missing anything?

also, this is being called from a block which is

if(mainFrame ...)
else if (isForIframe(request) && documentUri?.host == request.requestHeaders["Referer"]?.toUri()?.host)

just checking, would it be possible to skip isForIframe and just do documentUri?.host == request.requestHeaders["Referer"]?.toUri()?.host?

seems we just want to run our logic for any mainframe OR request related to that documentUri.host, does it matter if iframe is true?

return true
}
processedUrls.add(decodedUrl)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be add a comment documenting why we don't check for iframes here since we do in other methods?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants