Bug 188871 - Implement safe browsing in WebKit
Summary: Implement safe browsing in WebKit
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Alex Christensen
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-08-22 17:14 PDT by Alex Christensen
Modified: 2018-11-06 11:05 PST (History)
16 users (show)

See Also:


Attachments
Patch (59.80 KB, patch)
2018-08-22 17:17 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (59.86 KB, patch)
2018-08-22 18:02 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (60.02 KB, patch)
2018-08-22 23:25 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (110.92 KB, patch)
2018-09-10 14:13 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (111.35 KB, patch)
2018-09-10 15:16 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (111.24 KB, patch)
2018-09-11 14:53 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (102.29 KB, patch)
2018-09-14 13:17 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (90.82 KB, patch)
2018-09-18 14:39 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (90.77 KB, patch)
2018-09-18 15:55 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (93.38 KB, patch)
2018-09-24 22:40 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (97.02 KB, patch)
2018-09-25 16:29 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (90.31 KB, patch)
2018-09-25 16:56 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Archive of layout-test-results from ews106 for mac-sierra-wk2 (3.78 MB, application/zip)
2018-09-25 18:40 PDT, EWS Watchlist
no flags Details
Patch (90.31 KB, patch)
2018-09-26 10:52 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (22.06 KB, patch)
2018-10-19 20:15 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (56.09 KB, patch)
2018-11-01 15:51 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (68.01 KB, patch)
2018-11-02 10:38 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (68.06 KB, patch)
2018-11-02 11:13 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (72.24 KB, patch)
2018-11-02 15:44 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (67.97 KB, patch)
2018-11-03 09:48 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (67.93 KB, patch)
2018-11-03 12:21 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (68.40 KB, patch)
2018-11-03 19:55 PDT, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (78.11 KB, patch)
2018-11-05 09:26 PST, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (78.78 KB, patch)
2018-11-05 15:47 PST, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (78.78 KB, patch)
2018-11-05 16:13 PST, Alex Christensen
no flags Details | Formatted Diff | Diff
Patch (78.82 KB, patch)
2018-11-05 17:12 PST, Alex Christensen
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alex Christensen 2018-08-22 17:14:28 PDT
Implement safe browsing in WebKit
Comment 1 Alex Christensen 2018-08-22 17:17:29 PDT
Created attachment 347880 [details]
Patch
Comment 2 Alex Christensen 2018-08-22 18:02:41 PDT
Created attachment 347888 [details]
Patch
Comment 3 Alex Christensen 2018-08-22 23:25:23 PDT
Created attachment 347904 [details]
Patch
Comment 4 Sam Weinig 2018-08-23 14:45:42 PDT
Comment on attachment 347904 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=347904&action=review

> Source/WebKit/UIProcess/WebPageProxy.cpp:4045
> +            loadAlternateHTML({ reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size() }, "UTF-8"_s, navigation->currentRequest().url(), navigation->currentRequest().url(), nullptr, true);

It seems wrong that WebKit would show an error page here rather than leaving that up to the client to do (like we do with all other page load errors).  I would expect a safe browsing failure to just be another type of error returned to the client.
Comment 5 mitz 2018-08-23 14:53:00 PDT
Comment on attachment 347904 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=347904&action=review

>> Source/WebKit/UIProcess/WebPageProxy.cpp:4045
>> +            loadAlternateHTML({ reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size() }, "UTF-8"_s, navigation->currentRequest().url(), navigation->currentRequest().url(), nullptr, true);
> 
> It seems wrong that WebKit would show an error page here rather than leaving that up to the client to do (like we do with all other page load errors).  I would expect a safe browsing failure to just be another type of error returned to the client.

Does this introduce a situation in which, unbeknownst to the client, the WKWebView’s URL property reports a certain URL, but the view is displaying content that wasn’t loaded from that URL?
Comment 6 Alex Christensen 2018-08-23 15:04:24 PDT
Comment on attachment 347904 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=347904&action=review

>>> Source/WebKit/UIProcess/WebPageProxy.cpp:4045
>>> +            loadAlternateHTML({ reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size() }, "UTF-8"_s, navigation->currentRequest().url(), navigation->currentRequest().url(), nullptr, true);
>> 
>> It seems wrong that WebKit would show an error page here rather than leaving that up to the client to do (like we do with all other page load errors).  I would expect a safe browsing failure to just be another type of error returned to the client.
> 
> Does this introduce a situation in which, unbeknownst to the client, the WKWebView’s URL property reports a certain URL, but the view is displaying content that wasn’t loaded from that URL?

It does.  For the record, I have also argued that this ought to be a new error type, so I'm not the person to argue against your views which I see as correct.
Comment 7 mitz 2018-08-23 15:11:44 PDT
Comment on attachment 347904 [details]
Patch

The WebKit project works best when we only make changes that at least one author and one reviewer deem to be correct.
Comment 8 Alex Christensen 2018-08-24 21:23:49 PDT
Comment on attachment 347904 [details]
Patch

I'm going to take a different approach.
Comment 9 Alex Christensen 2018-09-10 14:13:53 PDT
Created attachment 349327 [details]
Patch
Comment 10 Alex Christensen 2018-09-10 15:16:00 PDT
Created attachment 349334 [details]
Patch
Comment 11 Alex Christensen 2018-09-11 14:53:12 PDT
Created attachment 349462 [details]
Patch
Comment 12 Sam Weinig 2018-09-11 17:30:41 PDT
Comment on attachment 349462 [details]
Patch

This new patch doesn't seem to address the concerns raised earlier in this bug.
Comment 13 Alex Christensen 2018-09-11 19:15:11 PDT
Comment on attachment 349462 [details]
Patch

This patch does address the concerns from earlier in this bug.
With the new delegate callback in WKUIDelegate, an app will have the ability to see and control whether a safe browsing warning is being shown.
Because loading an unsafe URL in an iframe is determined to indicate that the whole page should not be shown, we cannot use WKNavigationDelegate's existing error callbacks because they are not called for iframe navigation.
Because we want unmodified clients to get this safety coverage but still have the ability to not be broken, this is the design.  Re-requesting review.
Comment 14 mitz 2018-09-11 19:26:32 PDT
As noted before, the patch introduces new meaning to WKWebView’s URL property for clients that were built with an SDK in which it had a different meaning.
Comment 15 Sam Weinig 2018-09-11 20:26:28 PDT
(In reply to Alex Christensen from comment #13)
> Comment on attachment 349462 [details]
> Patch
> 
> This patch does address the concerns from earlier in this bug.
> With the new delegate callback in WKUIDelegate, an app will have the ability
> to see and control whether a safe browsing warning is being shown.
> Because loading an unsafe URL in an iframe is determined to indicate that
> the whole page should not be shown, we cannot use WKNavigationDelegate's
> existing error callbacks because they are not called for iframe navigation.
> Because we want unmodified clients to get this safety coverage but still
> have the ability to not be broken, this is the design.  Re-requesting review.

I think you may have misunderstood my concern. My specific stated concern was that the design up until this point has been to require clients to implement their own error pages, the idea being that only the client could design something that matches the UI of their application. This was a deliberate choice when designing the API. As such, it seems like a better approach would be to return an error to the client and allow them to construct an error page.
Comment 16 Geoffrey Garen 2018-09-11 21:03:47 PDT
> As such, it seems like a better
> approach would be to return an error to the client and allow them to
> construct an error page.

What default behavior are you proposing for clients that don't design and implement their own error pages?
Comment 17 mitz 2018-09-11 21:11:29 PDT
(In reply to Geoffrey Garen from comment #16)
> What default behavior are you proposing for clients that don't design and
> implement their own error pages?

I’m no Sam Weinig, but I would propose the same behavior that clients that don’t design and implement their own “untrustworthy TLS certificate” error pages have: the navigation fails (if it’s a main-frame navigation, the navigation delegate receives an error).
Comment 18 Alex Christensen 2018-09-12 09:23:10 PDT
I'm all for that, but I ran up against a problem: if it's an iframe navigating to an unsafe URL, there's no API on WKWebView to tell the application about the error.  didFailProvisionalNavigation and didFailNavigation are only called for top level navigations.  Do you think it would be better to just unexpectedly call didStartProvisionalNavigation and didFailProvisionalNavigation even when the WKFrameInfos of the decidePolicyForNavigationAction call said it was not for a main frame navigation?  I could, but that would also be changing the meaning of the API.
Comment 19 mitz 2018-09-12 10:01:06 PDT
(In reply to Alex Christensen from comment #18)
> I'm all for that, but I ran up against a problem: if it's an iframe
> navigating to an unsafe URL, there's no API on WKWebView to tell the
> application about the error.

Right, this mirrors what happens when an iframe navigates to a URL with an untrustworthy certificate.

> Do you think
> it would be better to just unexpectedly call didStartProvisionalNavigation
> and didFailProvisionalNavigation even when the WKFrameInfos of the
> decidePolicyForNavigationAction call said it was not for a main frame
> navigation?

This doesn’t strike me as a good design, and like you say, it’s not a binary-compatible change.

There is private API for notifying the delegate of errors in subframes, which is used by Safari in iOS for the “untrustworthy certificate in subframe navigation” case. Perhaps this private API is a good starting point for public API for communicating subframe navigation errors.
Comment 20 Geoffrey Garen 2018-09-12 12:32:22 PDT
(In reply to mitz from comment #17)
> (In reply to Geoffrey Garen from comment #16)
> > What default behavior are you proposing for clients that don't design and
> > implement their own error pages?
> 
> I’m no Sam Weinig, but I would propose the same behavior that clients that
> don’t design and implement their own “untrustworthy TLS certificate” error
> pages have: the navigation fails (if it’s a main-frame navigation, the
> navigation delegate receives an error).

OK, now that I understand this proposal, I see that it may be aesthetically pleasing and similar to existing behaviors -- maybe that's why Sam called it "better"? -- but it's also a security regression compared to the behavior in this patch (and the behavior Safari currently implements).

The Safe Browsing service can detect that a website is a phishing attempt at any time -- before, during, or after the load. When the Safe Browsing service flags a subframe or subresource, that doesn't mean "this resource is phishing, but everything else is OK". Instead it means "because of this resource, we believe the whole webpage is a phishing attempt". 

So, responding to a flagged subframe or subresource by just neglecting to load it would leave the user exposed to the phishing attack in the main frame.

Can you modify your proposal in some way to resolve this problem?
Comment 21 mitz 2018-09-13 12:46:26 PDT
(In reply to Geoffrey Garen from comment #20)
> (In reply to mitz from comment #17)
> > (In reply to Geoffrey Garen from comment #16)
> > > What default behavior are you proposing for clients that don't design and
> > > implement their own error pages?
> > 
> > I’m no Sam Weinig, but I would propose the same behavior that clients that
> > don’t design and implement their own “untrustworthy TLS certificate” error
> > pages have: the navigation fails (if it’s a main-frame navigation, the
> > navigation delegate receives an error).
> 
> OK, now that I understand this proposal, I see that it may be aesthetically
> pleasing and similar to existing behaviors -- maybe that's why Sam called it
> "better"? -- but it's also a security regression compared to the behavior in
> this patch (and the behavior Safari currently implements).
> 
> The Safe Browsing service can detect that a website is a phishing attempt at
> any time -- before, during, or after the load. When the Safe Browsing
> service flags a subframe or subresource, that doesn't mean "this resource is
> phishing, but everything else is OK". Instead it means "because of this
> resource, we believe the whole webpage is a phishing attempt". 
> 
> So, responding to a flagged subframe or subresource by just neglecting to
> load it would leave the user exposed to the phishing attack in the main
> frame.
> 
> Can you modify your proposal in some way to resolve this problem?

Since, as you explained, being unsafe-to-browse is not a characteristic of a navigation but rather a state that the web view enters, a good binary-compatible way to present this state to clients would be to mimic one of these existing error states: Web Content process hang and Web Content process termination.
Comment 22 Geoffrey Garen 2018-09-13 16:48:38 PDT
> Since, as you explained, being unsafe-to-browse is not a characteristic of a
> navigation but rather a state that the web view enters, a good
> binary-compatible way to present this state to clients would be to mimic one
> of these existing error states: Web Content process hang and Web Content
> process termination.

I think something like the process termination API could fit here. In that case, what user-facing behavior would you propose?
Comment 23 Alex Christensen 2018-09-14 13:17:02 PDT
Created attachment 349793 [details]
Patch
Comment 24 Alex Christensen 2018-09-18 14:39:23 PDT
Created attachment 350060 [details]
Patch
Comment 25 Alex Christensen 2018-09-18 15:55:07 PDT
Created attachment 350071 [details]
Patch
Comment 26 mitz 2018-09-20 21:25:32 PDT
(In reply to Geoffrey Garen from comment #22)
> > Since, as you explained, being unsafe-to-browse is not a characteristic of a
> > navigation but rather a state that the web view enters, a good
> > binary-compatible way to present this state to clients would be to mimic one
> > of these existing error states: Web Content process hang and Web Content
> > process termination.
> 
> I think something like the process termination API could fit here. In that
> case, what user-facing behavior would you propose?

The difference between initiating a main-frame navigation to an unsafe URL and learning that the current page has become unsafe is significant enough, that they should be presented differently to existing clients.

I would propose that a main-frame navigation to an unsafe URL will appear to have failed prior to being committed. The user-facing behavior depends on how the client handles navigation errors (or not) so it can range from nothing happening through the app presenting a modal alert to the app loading an HTML error page.

The current page becoming unsafe, while currently can only be triggered by a main frame navigation, is not really a navigational concept. It’s conceivable that in the future it might be triggered by any sub-resource load or even by analysis of something the page is doing with the DOM or with style. Once this condition is triggered, it’s unsafe for the user to interact with the webpage. The user-facing behavior, again, will depend on whether and how the client handles -webViewWebContentProcessDidTerminate: so it can range from the view just going blank through the app presenting a modal alert, or reloading the view with or without showing banner, or reloading the view repeatedly, or navigating to an HTML error page. Whatever it is, it’s something the app and its users are should be familiar with from experiencing Web Content process crashes.

I would propose that those behaviors for existing clients also apply to clients building against the future SDK, as long as they don’t bother to adopt any new WebKit API related to safe browsing.

The above behaviors also inform what such new API might look like, because it will remain important for clients to distinguish between “a bad navigation could happen, or we could stop it” and “the currently committed webpage is now known to be unsafe”. The former is best presented to clients as a new error from the existing navigation delegate method. The latter is better presented via a new API similar to -webViewWebContentProcessDidTerminate:, which requires them to take specific action prior to returning if they wish to avoid the default behavior of blanking-the-web-view-as-if-the-process-has-crashed.
Comment 27 Alex Christensen 2018-09-24 22:40:23 PDT
Created attachment 350738 [details]
Patch
Comment 28 Chris Dumez 2018-09-25 08:54:07 PDT
Comment on attachment 350738 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=350738&action=review

> Source/WebKit/UIProcess/WebPageProxy.cpp:4077
> +                    case UnsafeContentDecision::YepItsUnsafe:

YepItsUnsafe? really?

> Source/WebKit/UIProcess/WebPageProxy.cpp:4085
> +                    case UnsafeContentDecision::IThinkItsActuallySafe:

IThinkItsActuallySafe ?

> Source/WebKit/UIProcess/API/APINavigationClient.h:61
> +enum class UnsafeContentDecision : uint8_t { YepItsUnsafe, IThinkItsActuallySafe };

I do not think this naming style is good or common in the project.

> Source/WebKit/UIProcess/API/Cocoa/WKNavigationDelegatePrivate.h:65
> +    _WKUnsafeContentDecisionYepItsUnsafe,

Ditto.

> Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:477
> +        provisionalLoader = static_cast<WebDocumentLoader*>(m_frame->coreFrame()->loader().policyDocumentLoader());

We would not need this workaround if you moved the DocumentLoader from policy to provisional before calling didStartProvisionalLoad(), like we usually do, e.g.:
setProvisionalDocumentLoader(m_policyDocumentLoader.get());
setState(FrameStateProvisional);
setPolicyDocumentLoader(nullptr);
m_client.dispatchDidStartProvisionalLoad();

> Source/WebKit/WebProcess/WebPage/WebPage.cpp:4142
> +        documentLoader = frame->coreFrame()->loader().policyDocumentLoader();

Ditto
Comment 29 Alex Christensen 2018-09-25 11:19:33 PDT
> YepItsUnsafe? really?
No, not really.  This is still in the design exploration phase, but I think we're closing in on what we want, and I'd be up for some name suggestions.
Comment 30 Alex Christensen 2018-09-25 16:29:43 PDT
Created attachment 350808 [details]
Patch
Comment 31 Alex Christensen 2018-09-25 16:56:19 PDT
Created attachment 350813 [details]
Patch
Comment 32 EWS Watchlist 2018-09-25 18:40:54 PDT
Comment on attachment 350813 [details]
Patch

Attachment 350813 [details] did not pass mac-wk2-ews (mac-wk2):
Output: https://webkit-queues.webkit.org/results/9350684

New failing tests:
imported/w3c/web-platform-tests/dom/nodes/Document-characterSet-normalization.html
editing/selection/iframe.html
Comment 33 EWS Watchlist 2018-09-25 18:40:56 PDT
Created attachment 350826 [details]
Archive of layout-test-results from ews106 for mac-sierra-wk2

The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews.
Bot: ews106  Port: mac-sierra-wk2  Platform: Mac OS X 10.12.6
Comment 34 Alex Christensen 2018-09-26 10:52:41 PDT
Created attachment 350872 [details]
Patch
Comment 35 Geoffrey Garen 2018-10-08 22:10:12 PDT
Here's my understanding of where we stand on this feature, and why.

# Consensus items

1. WebKit should do safe browsing checks by default. There are lots of WebKit clients and it's not practical to expect each one to adopt a safe browsing API separately.

2. Clients should be able to disable WebKit's checks, or override their outcomes. Some clients may consider it more private not to perform checks. Others might want to consult the user on the outcome.

3. loadAlternateHTML is not the best way for WebKit to present the user with an interstitial choice about safe browsing. It doesn't work for POST and other one-time loads because it cancels the load, making it impossible to bypass the warning and continue. It also invites apps that modify the DOM to accidentally modify the presentation of the interstitial choice.

4. Safe browsing is a continuous evaluation. You can decide that a webpage is unsafe at any time -- even after a page finishes loading. A simple page load error would be an incomplete implementation (though it sure would be simpler!).

# Open Questions

1. Do we need to offer a default UI to bypass a safe browsing warning? Unlike a TLS error or a network disconnection, a safe browsing warning is a trusted guesstimate and not a fact. We might want or need to maintain some humility about WebKit's guesstimates.

# Geoff says

1. It's not so great to kill the web process. Might a client display something like a crash banner if we did? It would be surprising and confusing if a user complained about a crash, and the complaint turned out to be a successful but poorly communicated identification of a flagged webpage -- if and only if the webpage were flagged because of a subframe. One alternative is to "undo" the navigation -- by going back or forward or to about:blank, depending on whether the navigation had been a forward or a back or a new WebView. Another alternative is to fail the load in v1, and retain the option to add a default interstitial UI prior to the load failure in v2 if it proves necessary. Another option is to add a default interstitial UI in v1, using a mechanism other than loadAlternateHTML.
Comment 36 Alex Christensen 2018-10-09 10:57:39 PDT
(In reply to Geoffrey Garen from comment #35)

> 3. loadAlternateHTML is not the best way for WebKit to present the user with
> an interstitial choice about safe browsing. It doesn't work for POST and
> other one-time loads because it cancels the load, making it impossible to
> bypass the warning and continue. It also invites apps that modify the DOM to
> accidentally modify the presentation of the interstitial choice.

It's not about losing the POST data, but more about losing the state of the current page.  If we decide to go back to safety when doing a main frame navigation, we want to not have destroyed the state of the previous page.  Even more important, if the user or client sees that a subresource load is marked as unsafe but decides to load it anyway, we want to be able to load that subresource into a page that has not lost state or been reloaded.
Comment 37 Alex Christensen 2018-10-19 20:15:24 PDT
Created attachment 352850 [details]
Patch
Comment 38 Alex Christensen 2018-11-01 15:51:14 PDT
Created attachment 353655 [details]
Patch
Comment 39 Alex Christensen 2018-11-01 15:53:40 PDT
Known issues with this latest patch:
1. no tests yet :(
2. WKSafeBrowsingClickableTextView.intrinsicContentSize isn't quite right, but it's good enough for all sizes
3. Not implemented on iOS yet even though it builds
4. Navigating the WKWebView should clear the interstitial.
5. Minor UI tweaks are probably needed
Comment 40 Tim Horton 2018-11-01 16:20:52 PDT
Comment on attachment 353655 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=353655&action=review

> Source/WebKit/UIProcess/PageClient.h:120
> +enum class HeedSafeBrowsingWarning : bool { No, Yes };

I don't love "Heed"

> Source/WebKit/UIProcess/WebPageProxy.cpp:4139
> +            if (result->needsInterstitialWarning()) {

Reduce indentation a little with a `if (!..) continue`?

> Source/WebKit/UIProcess/API/C/mac/WKContextPrivateMac.mm:176
> +#if PLATFORM(MAC)

What was this even here for before! Does anyone use it?

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.h:61
> +- (void)frameChangedTo:(CGRect)frame;

Why? Why not just set the frame in the place where this is called?

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:60
> +static ColorType *redColor()

You should stick all of the colors in an asset catalog with specializations for dark mode and use them by name. We have one on iOS, but you should add one that we use on both platforms.

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:96
> +    return WebCore::URL({ }, "http://webkit.org/"_s);

What‽ Why webkit.org

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:146
> +    _dark = dark;

Why all this passing dark state around? Just use NSAppearance like it was made for.

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:178
> +    [[NSColor windowBackgroundColor] set];

Ditto the question from below; this could just be a layer with background color and corner radius. Also does it want continuous curvature corners? Probably.

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:304
> +}
> +- (void)dealloc

Lots of missing newlines

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:325
> +        NSAlert *alert = [[NSAlert alloc] init];

Leak?

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:361
> +- (void)drawRect:(CGRect)rect
> +{
> +    [redColor() set];
> +    [[BezierPathType bezierPathWithRect:rect] fill];
> +}

Why make backing store when it could just be a layer with background color!

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:365
> +- (void)frameChangedTo:(CGRect)frame
> +{
> +    [self setFrame:frame];
> +}

This is wrong. You're setting the frame of this view to the frame of the WKWebView. It's OK in Safari and MiniBrowser because Safari/MiniBrowser put the WKWebView at the origin, but in general you want to make this view (which is installed as a child of the WKWebView, right?) cover the *bounds* of the WKWebView, not its frame. But I also think as stated above that you should just set the frame of this view in the places where currently call this (frameChangedTo:) and get rid of this.
Comment 41 Alex Christensen 2018-11-01 20:03:47 PDT
Comment on attachment 353655 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=353655&action=review

Thanks for the great review, Tim!

>> Source/WebKit/UIProcess/API/C/mac/WKContextPrivateMac.mm:176
>> +#if PLATFORM(MAC)
> 
> What was this even here for before! Does anyone use it?

This was added and adopted in Safari so that one change in WebKit can enable safe browsing in WebKit and disable safe browsing in Safari at the same time so there aren't broken builds between landing two patches in two repositories.  It will be removed after this project is over.
Comment 42 Tim Horton 2018-11-01 21:41:39 PDT
Smart!
Comment 43 Alex Christensen 2018-11-02 07:56:22 PDT
Comment on attachment 353655 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=353655&action=review

>> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:178
>> +    [[NSColor windowBackgroundColor] set];
> 
> Ditto the question from below; this could just be a layer with background color and corner radius. Also does it want continuous curvature corners? Probably.

NSView doesn't have backgroundColor, just UIView.
Comment 44 Tim Horton 2018-11-02 08:36:24 PDT
Comment on attachment 353655 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=353655&action=review

>>> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:178
>>> +    [[NSColor windowBackgroundColor] set];
>> 
>> Ditto the question from below; this could just be a layer with background color and corner radius. Also does it want continuous curvature corners? Probably.
> 
> NSView doesn't have backgroundColor, just UIView.

I said layer! Which you can make a view have by setting wantsLayer, and ten grab it via ‘layer’ and set a background color
Comment 45 Alex Christensen 2018-11-02 10:38:10 PDT
Created attachment 353711 [details]
Patch
Comment 46 Wenson Hsieh 2018-11-02 11:02:58 PDT
Comment on attachment 353711 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=353711&action=review

> Source/WebKit/UIProcess/SafeBrowsingResult.h:56
> +    bool needsSafeBrowsingWarning() { return m_isPhishing || m_isMalware || m_isUnwantedSoftware; }

Nit - needsSafeBrowsingWarning() const?

> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:3282
> +    _impl->frameOrBoundsChanged();

Can we make this work using existing machinery (e.g. WebViewImpl::setFrameSize) instead?

> Source/WebKit/UIProcess/Cocoa/SafeBrowsingResultCocoa.mm:36
> +// FIXME: These ought to be API calls to the SafariSafeBrowsing framework when such SPI is available.

If there's a radar tracking this, I think it would be nice to reference it here.

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:340
> +        NSFontAttributeName:[FontType systemFontOfSize:13],
> +        NSForegroundColorAttributeName : foregroundColor

Nit - spaces around the : seem inconsistent here.

> Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm:1625
> +    [m_safeBrowsingWarning setFrame:[m_view frame]];
> +    [m_safeBrowsingWarning setBounds:[m_view bounds]];

🤔
Comment 47 Alex Christensen 2018-11-02 11:13:08 PDT
Created attachment 353715 [details]
Patch
Comment 48 Alex Christensen 2018-11-02 15:44:24 PDT
Created attachment 353740 [details]
Patch
Comment 49 Alex Christensen 2018-11-03 09:48:24 PDT
Created attachment 353776 [details]
Patch
Comment 50 Alex Christensen 2018-11-03 12:21:04 PDT
Created attachment 353780 [details]
Patch
Comment 51 Tim Horton 2018-11-03 15:15:58 PDT
Comment on attachment 353780 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=353780&action=review

> Source/WebKit/UIProcess/API/C/mac/WKContextPrivateMac.mm:177
> +    return true;

Should this follow the preference?

> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:3282
> +    _impl->frameOrBoundsChanged();

Prettttty likely you can get rid of this and just use WebViewImpl::setFrameSize. But this is also fine I guess? Though the name is a bit of a lie.

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:89
> +        NSUnderlineStyleAttributeName: [NSNumber numberWithInteger:1]

@(1)

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:90
> +    } range:NSMakeRange(0, [replaceWith length])];

More dots! 

replaceWith.length

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:102
> +    [colorNamed(@"WKSafeBrowsingWarningTitle") set];

Pretty good chance this function would look way less crazy if you just used CG, but w/e.

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:257
> +    if (_completionHandler)
> +        _completionHandler(WebKit::ContinueUnsafeLoad::Yes);

Really, continue if you're being deallocated?
Comment 52 Alex Christensen 2018-11-03 19:55:04 PDT
Created attachment 353792 [details]
Patch
Comment 53 Alex Christensen 2018-11-05 09:26:12 PST
Created attachment 353870 [details]
Patch
Comment 54 Tim Horton 2018-11-05 10:25:41 PST
Comment on attachment 353870 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=353870&action=review

> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:6657
> +- (NSView *)_safeBrowsingWarningForTesting

This obviously isn't going to fly on iOS

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:200
> ++ (instancetype)viewWithAttributedString:(NSMutableAttributedString *)attributedString linkTarget:(WKSafeBrowsingWarning *)target;

Why mutable! (Ideally there would be a mutableCopy hiding inside here, and the caller's string wouldn't get mutated)

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:295
> +    _completionHandler(makeUnexpected(link));

Alex says "I could use a variant instead of Expected"

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:302
> +    NSStackView *bottom =box.views.lastObject;

Missing a space after the =

> Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm:1609
> +            weakThis->m_ignoresNonWheelEvents = oldIgnoresNonWheelEvents;

?? do you want to allow scrolling (but not other events) ??
Comment 55 Joseph Pecoraro 2018-11-05 10:58:27 PST
Comment on attachment 353870 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=353870&action=review

> Source/WebKit/UIProcess/Cocoa/WKSafeBrowsingWarning.mm:89
> +        NSUnderlineStyleAttributeName: @(1)

Or just @1
Comment 56 Alex Christensen 2018-11-05 15:47:36 PST
Created attachment 353915 [details]
Patch
Comment 57 Alex Christensen 2018-11-05 16:13:45 PST
Created attachment 353918 [details]
Patch
Comment 58 Alex Christensen 2018-11-05 17:12:05 PST
Created attachment 353928 [details]
Patch
Comment 59 Alex Christensen 2018-11-06 07:26:30 PST
http://trac.webkit.org/r237863
Comment 60 Radar WebKit Bug Importer 2018-11-06 07:27:29 PST
<rdar://problem/45842451>
Comment 61 Ryan Haddad 2018-11-06 09:15:05 PST
This change introduced an API test failure on High Sierra and Mojave:

    TestWebKitAPI.ProcessSwap.LoadAfterPolicyDecision
        Received data during response processing, queuing it.
        Received data during response processing, queuing it.
        
        /Volumes/Data/slave/highsierra-release/build/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:485
        Expected equality of these values:
          @"pson://www.webkit.org/main2.html"
            Which is: "pson://www.webkit.org/main2.html"
          [[webView URL] absoluteString]
            Which is: "pson://www.apple.com/main.html"

https://build.webkit.org/builders/Apple%20High%20Sierra%20Release%20WK2%20(Tests)/builds/7662
Comment 62 Alex Christensen 2018-11-06 11:05:03 PST
Tests fixed in http://trac.webkit.org/r237876
Also, this is part of <rdar://problem/26892893>