Move URL from WebCore to WTF
[WebKit-https.git] / Source / WebKit / UIProcess / Cocoa / SafeBrowsingWarningCocoa.mm
1 /*
2  * Copyright (C) 2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "SafeBrowsingWarning.h"
28
29 #import "SafeBrowsingSPI.h"
30 #import <WebCore/LocalizedStrings.h>
31 #import <pal/spi/cocoa/NSAttributedStringSPI.h>
32 #import <wtf/Language.h>
33
34 namespace WebKit {
35
36 #if HAVE(SAFE_BROWSING)
37
38 // FIXME: These four functions ought to be API calls to the SafariSafeBrowsing framework when such SPI is available.
39 // That way WebKit does not need to know about the SafariSafeBrowsing framework's possible providers.
40 static const char* malwareDetailsBase(SSBServiceLookupResult *result)
41 {
42     if ([result.provider isEqualToString:SSBProviderTencent])
43         return "https://www.urlsec.qq.com/check.html?tpl=safari";
44     return "https://google.com/safebrowsing/diagnostic?tpl=safari";
45 }
46
47 static NSURL *learnMoreURL(SSBServiceLookupResult *result)
48 {
49     if ([result.provider isEqualToString:SSBProviderTencent])
50         return [NSURL URLWithString:@"https://www.urlsec.qq.com/standard/s1.html?tpl=safari"];
51     return [NSURL URLWithString:@"https://www.google.com/support/bin/answer.py?answer=106318"];
52 }
53
54 static const char* reportAnErrorBase(SSBServiceLookupResult *result)
55 {
56     if ([result.provider isEqualToString:SSBProviderTencent])
57         return "https://www.urlsec.qq.com/complain.html?tpl=safari";
58     return "https://www.google.com/safebrowsing/report_error/?tpl=safari";
59 }
60
61 static String localizedProvider(SSBServiceLookupResult *result)
62 {
63     if ([result.provider isEqualToString:SSBProviderTencent])
64         return WEB_UI_NSSTRING(@"Tencent Safe Browsing", "Tencent Safe Browsing");
65     return WEB_UI_NSSTRING(@"Google Safe Browsing", "Google Safe Browsing");
66 }
67
68
69 static void replace(NSMutableAttributedString *string, NSString *toReplace, NSString *replaceWith)
70 {
71     [string replaceCharactersInRange:[string.string rangeOfString:toReplace] withString:replaceWith];
72 }
73
74 static void addLinkAndReplace(NSMutableAttributedString *string, NSString *toReplace, NSString *replaceWith, NSURL *linkTarget)
75 {
76     NSMutableAttributedString *stringWithLink = [[[NSMutableAttributedString alloc] initWithString:replaceWith] autorelease];
77     [stringWithLink addAttributes:@{
78         NSLinkAttributeName: linkTarget,
79         NSUnderlineStyleAttributeName: @1
80     } range:NSMakeRange(0, replaceWith.length)];
81     [string replaceCharactersInRange:[string.string rangeOfString:toReplace] withAttributedString:stringWithLink];
82 }
83
84 static NSURL *reportAnErrorURL(const URL& url, SSBServiceLookupResult *result)
85 {
86     return URL({ }, makeString(reportAnErrorBase(result), "&url=", encodeWithURLEscapeSequences(url), "&hl=", defaultLanguage()));
87 }
88
89 static NSURL *malwareDetailsURL(const URL& url, SSBServiceLookupResult *result)
90 {
91     return URL({ }, makeString(malwareDetailsBase(result), "&site=", url.host(), "&hl=", defaultLanguage()));
92 }
93
94 static NSString *safeBrowsingTitleText(SSBServiceLookupResult *result)
95 {
96     if (result.isPhishing)
97         return WEB_UI_NSSTRING(@"Deceptive Website Warning", "Phishing warning title");
98     if (result.isMalware)
99         return WEB_UI_NSSTRING(@"Malware Website Warning", "Malware warning title");
100     ASSERT(result.isUnwantedSoftware);
101     return WEB_UI_NSSTRING(@"Website With Harmful Software Warning", "Unwanted software warning title");
102 }
103
104 static NSString *safeBrowsingWarningText(SSBServiceLookupResult *result)
105 {
106     if (result.isPhishing)
107         return WEB_UI_NSSTRING(@"This website may try to trick you into doing something dangerous, like installing software or disclosing personal or financial information, like passwords, phone numbers, or credit cards.", "Phishing warning");
108     if (result.isMalware)
109         return WEB_UI_NSSTRING(@"This website may attempt to install dangerous software, which could harm your computer or steal your personal or financial information, like passwords, photos, or credit cards.", "Malware warning");
110
111     ASSERT(result.isUnwantedSoftware);
112     return WEB_UI_NSSTRING(@"This website may try to trick you into installing software that harms your browsing experience, like changing your settings without your permission or showing you unwanted ads. Once installed, it may be difficult to remove.", "Unwanted software warning");
113 }
114
115 static NSMutableAttributedString *safeBrowsingDetailsText(const URL& url, SSBServiceLookupResult *result)
116 {
117     if (result.isPhishing) {
118         NSString *phishingDescription = WEB_UI_NSSTRING(@"Warnings are shown for websites that have been reported as deceptive. Deceptive websites try to trick you into believing they are legitimate websites you trust.", "Phishing warning description");
119         NSString *learnMore = WEB_UI_NSSTRING(@"Learn more…", "Action from safe browsing warning");
120         NSString *phishingActions = WEB_UI_NSSTRING(@"If you believe this website is safe, you can %report-an-error%. Or, if you understand the risks involved, you can %bypass-link%.", "Phishing warning description");
121         NSString *reportAnError = WEB_UI_NSSTRING(@"report an error", "Action from safe browsing warning");
122         NSString *visitUnsafeWebsite = WEB_UI_NSSTRING(@"visit this unsafe website", "Action from safe browsing warning");
123
124         NSMutableAttributedString *attributedString = [[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@\n\n%@", phishingDescription, learnMore, phishingActions]] autorelease];
125         addLinkAndReplace(attributedString, learnMore, learnMore, learnMoreURL(result));
126         addLinkAndReplace(attributedString, @"%report-an-error%", reportAnError, reportAnErrorURL(url, result));
127         addLinkAndReplace(attributedString, @"%bypass-link%", visitUnsafeWebsite, SafeBrowsingWarning::visitUnsafeWebsiteSentinel());
128         return attributedString;
129     }
130
131     auto malwareOrUnwantedSoftwareDetails = [&] (NSString *description, NSString *statusStringToReplace, bool confirmMalware) {
132         NSMutableAttributedString *malwareDescription = [[[NSMutableAttributedString alloc] initWithString:description] autorelease];
133         replace(malwareDescription, @"%safeBrowsingProvider%", localizedProvider(result));
134         NSMutableAttributedString *statusLink = [[[NSMutableAttributedString alloc] initWithString:WEB_UI_NSSTRING(@"the status of “%site%”", "Part of malware description")] autorelease];
135         replace(statusLink, @"%site%", url.host().toString());
136         addLinkAndReplace(malwareDescription, statusStringToReplace, statusLink.string, malwareDetailsURL(url, result));
137
138         NSMutableAttributedString *ifYouUnderstand = [[[NSMutableAttributedString alloc] initWithString:WEB_UI_NSSTRING(@"If you understand the risks involved, you can %visit-this-unsafe-site-link%.", "Action from safe browsing warning")] autorelease];
139         addLinkAndReplace(ifYouUnderstand, @"%visit-this-unsafe-site-link%", WEB_UI_NSSTRING(@"visit this unsafe website", "Action from safe browsing warning"), confirmMalware ? SafeBrowsingWarning::confirmMalwareSentinel() : SafeBrowsingWarning::visitUnsafeWebsiteSentinel());
140
141         [malwareDescription appendAttributedString:[[[NSMutableAttributedString alloc] initWithString:@"\n\n"] autorelease]];
142         [malwareDescription appendAttributedString:ifYouUnderstand];
143         return malwareDescription;
144     };
145
146     if (result.isMalware)
147         return malwareOrUnwantedSoftwareDetails(WEB_UI_NSSTRING(@"Warnings are shown for websites where malicious software has been detected. You can check the %status-link% on the %safeBrowsingProvider% diagnostic page.", "Malware warning description"), @"%status-link%", true);
148     ASSERT(result.isUnwantedSoftware);
149     return malwareOrUnwantedSoftwareDetails(WEB_UI_NSSTRING(@"Warnings are shown for websites where harmful software has been detected. You can check %the-status-of-site% on the %safeBrowsingProvider% diagnostic page.", "Unwanted software warning description"), @"%the-status-of-site%", false);
150 }
151
152 SafeBrowsingWarning::SafeBrowsingWarning(const URL& url, SSBServiceLookupResult *result)
153     : m_title(safeBrowsingTitleText(result))
154     , m_warning(safeBrowsingWarningText(result))
155     , m_details(safeBrowsingDetailsText(url, result))
156 {
157 }
158 #endif
159
160 SafeBrowsingWarning::SafeBrowsingWarning(String&& title, String&& warning, RetainPtr<NSAttributedString>&& details)
161     : m_title(WTFMove(title))
162     , m_warning(WTFMove(warning))
163     , m_details(WTFMove(details))
164 {
165 }
166
167 NSURL *SafeBrowsingWarning::visitUnsafeWebsiteSentinel()
168 {
169     return [NSURL URLWithString:@"WKVisitUnsafeWebsiteSentinel"];
170 }
171
172 NSURL *SafeBrowsingWarning::confirmMalwareSentinel()
173 {
174     return [NSURL URLWithString:@"WKConfirmMalwareSentinel"];
175 }
176
177 }