LEFT | RIGHT |
1 /* | 1 /* |
2 * Copyright (C) 2018 Google LLC. All rights reserved. | 2 * Copyright (C) 2018 Google LLC. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 | 53 |
54 void SafeBrowsingController::checkURL(Ref<API::NavigationAction>&& navigationAct
ion, NavigationPolicyDecider&& policyDecider, Ref<WebFramePolicyListenerProxy>&&
listener) | 54 void SafeBrowsingController::checkURL(Ref<API::NavigationAction>&& navigationAct
ion, NavigationPolicyDecider&& policyDecider, Ref<WebFramePolicyListenerProxy>&&
listener) |
55 { | 55 { |
56 bool shouldSkipSafeBrowsingLookUp = !m_webView.configuration.preferences.saf
eBrowsingEnabled; | 56 bool shouldSkipSafeBrowsingLookUp = !m_webView.configuration.preferences.saf
eBrowsingEnabled; |
57 if (!shouldSkipSafeBrowsingLookUp) { | 57 if (!shouldSkipSafeBrowsingLookUp) { |
58 bool warningBypassed = navigationAction->navigationType() == WebCore::Na
vigationType::LinkClicked | 58 bool warningBypassed = navigationAction->navigationType() == WebCore::Na
vigationType::LinkClicked |
59 && navigationAction->sourceFrame() | 59 && navigationAction->sourceFrame() |
60 && navigationAction->sourceFrame()->page()->pageLoadState().url() ==
s_warningPageUrl | 60 && navigationAction->sourceFrame()->page()->pageLoadState().url() ==
s_warningPageUrl |
61 && navigationAction->sourceFrame()->page()->currentURL() == navigati
onAction->originalURL().string(); | 61 && navigationAction->sourceFrame()->page()->currentURL() == navigati
onAction->originalURL().string(); |
62 | 62 |
63 // FIXME: Figure out the right persistence model. Right now, this persis
ts ignoring warnings for the currently | |
64 // displayed URL (i.e., the main-frame URL), but not for the specific su
bframe that triggered the | |
65 // warning. So the next attempt at loading that subframe will still trig
ger the warning. | |
66 // For subframes, the user might have no idea what URL is 'dangerous', s
o persisting that URL seems | |
67 // questionable. | |
68 // Another approach would be to exempt all loads triggered by the main-f
rame URL once the user | |
69 // bypasses a warning with that main-frame URL. But then we also need to
track what warning types | |
70 // the user has decided to bypass (e.g., maybe the user bypassed a phish
ing warning, but that | |
71 // shouldn't automatically imply they also want to bypass malware warnin
gs). | |
72 if (warningBypassed) | 63 if (warningBypassed) |
73 m_warningIgnoredUrls.add(navigationAction->originalURL()); | 64 m_warningIgnoredUrls.add(navigationAction->originalURL()); |
74 | 65 |
75 shouldSkipSafeBrowsingLookUp = warningBypassed || m_warningIgnoredUrls.c
ontains(navigationAction->originalURL()); | 66 shouldSkipSafeBrowsingLookUp = warningBypassed || m_warningIgnoredUrls.c
ontains(navigationAction->originalURL()); |
76 } | 67 } |
77 | 68 |
78 auto safeBrowsingCheck = std::make_unique<SafeBrowsingCheck>(WTFMove(listene
r), WTFMove(navigationAction)); | 69 auto safeBrowsingCheck = std::make_unique<SafeBrowsingCheck>(WTFMove(listene
r), WTFMove(navigationAction)); |
79 auto checkRaw = safeBrowsingCheck.get(); | 70 auto checkRaw = safeBrowsingCheck.get(); |
80 m_checks.add(WTFMove(safeBrowsingCheck)); | 71 m_checks.add(WTFMove(safeBrowsingCheck)); |
81 | 72 |
| 73 if (shouldSkipSafeBrowsingLookUp) |
| 74 receivedSafeBrowsingResult(checkRaw, SafeBrowsingResult::Safe); |
| 75 else { |
| 76 #if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || (PLATFORM(IO
S) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000) |
| 77 auto weakThis = m_weakPtrFactory.createWeakPtr(*this); |
| 78 [SafeBrowsingContextProvider::sharedLookupContext() lookUpURL:checkRaw->
navigationAction->request().url() completionHandler:^(SSBLookupResult* result, N
SError* error) { |
| 79 if (!weakThis) |
| 80 return; |
| 81 |
| 82 SafeBrowsingResult safeBrowsingResult = SafeBrowsingResult::Safe; |
| 83 if (result.serviceLookupResults) { |
| 84 for (SSBServiceLookupResult* details in result.serviceLookupResu
lts) { |
| 85 // FIXME: Keep track of the different types in order to give
different warnings. |
| 86 if (details.isPhishing || details.isMalware || details.isUnw
antedSoftware || details.isKnownToBeUnsafe) |
| 87 safeBrowsingResult = SafeBrowsingResult::Unsafe; |
| 88 } |
| 89 } |
| 90 weakThis->receivedSafeBrowsingResult(checkRaw, safeBrowsingResult); |
| 91 }]; |
| 92 #else |
| 93 receivedSafeBrowsingResult(checkRaw, SafeBrowsingResult::Safe); |
| 94 #endif |
| 95 } |
| 96 |
82 auto policyCompletionHandler = [checkRaw, weakThis = m_weakPtrFactory.create
WeakPtr(*this)] (WKNavigationActionPolicy policy, std::optional<WebsitePoliciesD
ata>&& data) mutable { | 97 auto policyCompletionHandler = [checkRaw, weakThis = m_weakPtrFactory.create
WeakPtr(*this)] (WKNavigationActionPolicy policy, std::optional<WebsitePoliciesD
ata>&& data) mutable { |
83 if (weakThis) | 98 if (weakThis) |
84 weakThis->receivedNavigationPolicyDecision(*checkRaw, policy, WTFMov
e(data)); | 99 weakThis->receivedNavigationPolicyDecision(*checkRaw, policy, WTFMov
e(data)); |
85 }; | 100 }; |
86 | 101 |
87 policyDecider(WTFMove(policyCompletionHandler)); | 102 policyDecider(WTFMove(policyCompletionHandler)); |
88 | |
89 if (shouldSkipSafeBrowsingLookUp) { | |
90 receivedSafeBrowsingResult(checkRaw, SafeBrowsingResult::Safe); | |
91 return; | |
92 } | |
93 | |
94 #if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || (PLATFORM(IO
S) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000) | |
95 auto weakThis = m_weakPtrFactory.createWeakPtr(*this); | |
96 [SafeBrowsingContextProvider::sharedLookupContext() lookUpURL:checkRaw->navi
gationAction->request().url() completionHandler:^(SSBLookupResult* result, NSErr
or* error) { | |
97 // FIXME: Remove logging. | |
98 if (error) | |
99 WTFLogAlways("Error doing SafeBrowsing check"); | |
100 if (!weakThis) | |
101 return; | |
102 SafeBrowsingResult safeBrowsingResult = SafeBrowsingResult::Safe; | |
103 if (result.serviceLookupResults) { | |
104 for (SSBServiceLookupResult* details in result.serviceLookupResults)
{ | |
105 // FIXME: Do we want to keep track of the different types in ord
er to give | |
106 // different warnings? | |
107 if (details.isPhishing || details.isMalware || details.isUnwante
dSoftware || details.isKnownToBeUnsafe) | |
108 safeBrowsingResult = SafeBrowsingResult::Unsafe; | |
109 } | |
110 } | |
111 weakThis->receivedSafeBrowsingResult(checkRaw, safeBrowsingResult); | |
112 }]; | |
113 #else | |
114 receivedSafeBrowsingDecision(checkRaw, false); | |
115 #endif | |
116 } | 103 } |
117 | 104 |
118 void SafeBrowsingController::receivedNavigationPolicyDecision(SafeBrowsingContro
ller::SafeBrowsingCheck& check, WKNavigationActionPolicy policy, std::optional<W
ebsitePoliciesData>&& data) | 105 void SafeBrowsingController::receivedNavigationPolicyDecision(SafeBrowsingContro
ller::SafeBrowsingCheck& check, WKNavigationActionPolicy policy, std::optional<W
ebsitePoliciesData>&& data) |
119 { | 106 { |
120 check.navigationPolicyDecision = policy; | 107 check.navigationPolicyDecision = policy; |
121 check.websitePoliciesData = WTFMove(data); | 108 check.websitePoliciesData = WTFMove(data); |
122 maybeFinishedCheck(check); | 109 maybeFinishedCheck(check); |
123 } | 110 } |
124 | 111 |
125 void SafeBrowsingController::receivedSafeBrowsingResult(SafeBrowsingCheck* check
, SafeBrowsingResult safeBrowsingResult) | 112 void SafeBrowsingController::receivedSafeBrowsingResult(SafeBrowsingCheck* check
, SafeBrowsingResult safeBrowsingResult) |
(...skipping 10 matching lines...) Expand all Loading... |
136 if (!check.navigationPolicyDecision) | 123 if (!check.navigationPolicyDecision) |
137 return; | 124 return; |
138 | 125 |
139 if (check.navigationPolicyDecision.value() == WKNavigationActionPolicyAllow
&& !check.safeBrowsingResult) | 126 if (check.navigationPolicyDecision.value() == WKNavigationActionPolicyAllow
&& !check.safeBrowsingResult) |
140 return; | 127 return; |
141 | 128 |
142 switch (check.navigationPolicyDecision.value()) { | 129 switch (check.navigationPolicyDecision.value()) { |
143 case WKNavigationActionPolicyAllow: { | 130 case WKNavigationActionPolicyAllow: { |
144 if (check.safeBrowsingResult == SafeBrowsingResult::Safe) { | 131 if (check.safeBrowsingResult == SafeBrowsingResult::Safe) { |
145 check.listener->use(WTFMove(check.websitePoliciesData)); | 132 check.listener->use(WTFMove(check.websitePoliciesData)); |
146 return; | 133 break; |
147 } | 134 } |
148 | 135 |
149 auto weakThis = m_weakPtrFactory.createWeakPtr(*this); | 136 check.listener->ignore(); |
150 void (^safeBrowsingPolicyHandler)(WKSafeBrowsingResultPolicy) = ^(WKSafe
BrowsingResultPolicy policy) { | 137 // FIXME: This really needs to be loaded in a way that permits localizat
ion. |
151 if (!weakThis) | 138 // FIXME: Make the warning message more similar to Safari, which means d
ifferent |
152 return; | 139 // wording depending on the type of warning (phishing, malware, etc.). |
153 switch (policy) { | 140 auto targetMainFrameUrl = check.navigationAction->targetFrame()->isMainF
rame() ? check.navigationAction->request().url() : WebCore::URL(WebCore::ParsedU
RLString, check.navigationAction->targetFrame()->page()->currentURL()); |
154 case WKSafeBrowsingResultPolicyCancel: | 141 NSString* warningString = [NSString stringWithFormat:@"<style>body { bac
kground-color: red; }</style><body><h1>This is a simple SafeBrowsing warning.</h
1><h2>You've been warned!!!</h2><h2><a id='visitAnyway' href='%s'>Visit the site
anyway</a></h2>", targetMainFrameUrl.string().utf8().data()]; |
155 check.listener->ignore(); | 142 [m_webView _loadAlternateHTMLString:warningString baseURL:WebCore::URL(W
ebCore::ParsedURLString, s_warningPageUrl) forUnreachableURL:targetMainFrameUrl]
; |
156 break; | 143 break; |
157 case WKSafeBrowsingResultPolicyCancelAndShowWarning: { | |
158 check.listener->ignore(); | |
159 // FIXME: This really needs to be loaded in a way that permits l
ocalization. | |
160 // Possibly put strings in LocalizedStrings.cpp or LocalizedStri
ngCocoa.mm. | |
161 // Make the warning message similar/identical to Safari, which m
eans different | |
162 // wording depending on the type of warning (phishing, malware,
etc.). | |
163 bool targetFrameIsMainFrame = check.navigationAction->targetFram
e()->isMainFrame(); | |
164 auto targetMainFrameUrl = targetFrameIsMainFrame ? check.navigat
ionAction->request().url() : WebCore::URL(WebCore::ParsedURLString, check.naviga
tionAction->targetFrame()->page()->currentURL()); | |
165 NSString* warningString = [NSString stringWithFormat:@"<style>bo
dy { background-color: red; }</style><body><h1>This is a simple SafeBrowsing war
ning.</h1><h2>You've been warned!!!</h2><h2><a id='visitAnyway' href='%s'>Live d
angerously and visit the site anyway</a></h2>", targetMainFrameUrl.string().utf8
().data()]; | |
166 if (targetFrameIsMainFrame) | |
167 [m_webView _page]->loadAlternateHTMLString(warningString, We
bCore::URL(WebCore::ParsedURLString, s_warningPageUrl), targetMainFrameUrl, null
ptr, check.navigationAction->redirectedByClient(), check.navigationAction->navig
ationType(), check.navigationAction->targetBackForwardItemIdentifier()); | |
168 else | |
169 [m_webView _page]->loadAlternateHTMLString(warningString, We
bCore::URL(WebCore::ParsedURLString, s_warningPageUrl), targetMainFrameUrl, null
ptr, WebCore::RedirectedByClient::No, WebCore::NavigationType::Reload); | |
170 break; | |
171 } | |
172 case WKSafeBrowsingResultPolicyAllow: | |
173 check.listener->use(WTFMove(check.websitePoliciesData)); | |
174 break; | |
175 } | |
176 m_checks.remove(&check); | |
177 }; | |
178 auto navigationDelegate = [m_webView navigationDelegate]; | |
179 if (navigationDelegate && [navigationDelegate respondsToSelector:@select
or(webView:decidePolicyForSafeBrowsingResultForNavigationAction:decisionHandler:
)]) | |
180 [navigationDelegate webView:m_webView decidePolicyForSafeBrowsingRes
ultForNavigationAction:wrapper(check.navigationAction) decisionHandler:safeBrows
ingPolicyHandler]; | |
181 else | |
182 safeBrowsingPolicyHandler(WKSafeBrowsingResultPolicyCancelAndShowWar
ning); | |
183 return; | |
184 } | 144 } |
185 case WKNavigationActionPolicyCancel: | 145 case WKNavigationActionPolicyCancel: |
186 check.listener->ignore(); | 146 check.listener->ignore(); |
187 break; | 147 break; |
188 case _WKNavigationActionPolicyDownload: | 148 case _WKNavigationActionPolicyDownload: |
189 check.listener->download(); | 149 check.listener->download(); |
190 break; | 150 break; |
191 default: | 151 default: |
192 ASSERT_NOT_REACHED(); | 152 ASSERT_NOT_REACHED(); |
193 } | 153 } |
194 m_checks.remove(&check); | 154 m_checks.remove(&check); |
195 } | 155 } |
196 | 156 |
197 } // namespace WebKit | 157 } // namespace WebKit |
198 | 158 |
199 #endif // WK_API_ENABLED | 159 #endif // WK_API_ENABLED |
LEFT | RIGHT |