From 88505531780e8d7352832c5fd75415bc81363750 Mon Sep 17 00:00:00 2001 From: "reed@reedloden.com" Date: Mon, 29 Oct 2007 11:29:14 -0700 Subject: [PATCH] Bug 399233 - "Phishing UI hidden by content, inconsistent with malware" [p=johnath r=tony r=biesi ui-r=beltzner a=blocking-firefox3+ for M9] --- browser/app/profile/firefox.js | 4 + .../safebrowsing/content/application.js | 31 ++- .../safebrowsing/content/blockedSite.xhtml | 210 ++++++++++++++++++ .../safebrowsing/content/malware-warden.js | 7 + .../content/phishing-afterload-displayer.js | 50 +---- browser/components/safebrowsing/jar.mn | 1 + .../src/nsSafebrowsingApplication.js | 7 + .../safebrowsing/blockedSite.properties | 11 + .../chrome/overrides/appstrings.properties | 1 + .../en-US/chrome/overrides/netError.dtd | 6 + browser/locales/jar.mn | 1 + docshell/base/nsDocShell.cpp | 40 +++- docshell/base/nsDocShell.h | 3 +- docshell/base/nsWebShell.cpp | 1 + .../en-US/chrome/appstrings.properties | 1 + dom/locales/en-US/chrome/netError.dtd | 6 + .../src/nsUrlClassifierDBService.cpp | 7 + uriloader/base/nsURILoader.h | 3 +- 18 files changed, 326 insertions(+), 64 deletions(-) create mode 100644 browser/components/safebrowsing/content/blockedSite.xhtml create mode 100644 browser/locales/en-US/chrome/browser/safebrowsing/blockedSite.properties diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index f1bbc962019..3130f64527b 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -539,6 +539,10 @@ pref("browser.safebrowsing.provider.0.reportPhishURL", "http://{moz:locale}.phis // FAQ URL pref("browser.safebrowsing.warning.infoURL", "http://%LOCALE%.www.mozilla.com/%LOCALE%/firefox/phishing-protection/"); + +// Name of the about: page contributed by safebrowsing to handle display of error +// pages on phishing/malware hits. (bug 399233) +pref("urlclassifier.alternate_error_page", "blocked"); #endif // defaults to true diff --git a/browser/components/safebrowsing/content/application.js b/browser/components/safebrowsing/content/application.js index bce52af2ba4..31c8460c17a 100644 --- a/browser/components/safebrowsing/content/application.js +++ b/browser/components/safebrowsing/content/application.js @@ -38,8 +38,8 @@ var gDataProvider = null; // An instance of our application is a PROT_Application object. It -// basically just populates a few globals and instantiates wardens and -// the listmanager. +// basically just populates a few globals and instantiates wardens, +// the listmanager, and the about:blocked error page. /** * An instance of our application. There should be exactly one of these. @@ -100,3 +100,30 @@ function PROT_Application() { PROT_Application.prototype.getReportURL = function(name) { return gDataProvider["getReport" + name + "URL"](); } + +/** + * about:blocked implementation + */ +PROT_Application.prototype.newChannel = function(uri) { + var ioService = Cc["@mozilla.org/network/io-service;1"] + .getService(Ci.nsIIOService); + var childURI = ioService.newURI("chrome://browser/content/safebrowsing/blockedSite.xhtml", + null, null); + var channel = ioService.newChannelFromURI(childURI); + channel.originalURI = uri; + + return channel; +} + +PROT_Application.prototype.getURIFlags = function(uri) { + return Ci.nsIAboutModule.ALLOW_SCRIPT; +} + +PROT_Application.prototype.QueryInterface = function(iid) { + if (iid.equals(Ci.nsISupports) || + iid.equals(Ci.nsIAboutModule)) + return this; + + Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE; + return null; +} diff --git a/browser/components/safebrowsing/content/blockedSite.xhtml b/browser/components/safebrowsing/content/blockedSite.xhtml new file mode 100644 index 00000000000..63a145e14c8 --- /dev/null +++ b/browser/components/safebrowsing/content/blockedSite.xhtml @@ -0,0 +1,210 @@ + + + + %htmlDTD; + + %globalDTD; + + %brandDTD; + + %blockedSiteDTD; +]> + + + + + + + + + + + + +
+ + +
+

+

+ +
+ + +
+

+

+ + +
+

+

+ + +
+ +
+
+
+ + + + diff --git a/browser/components/safebrowsing/content/malware-warden.js b/browser/components/safebrowsing/content/malware-warden.js index a201816fb08..9363e8020ab 100644 --- a/browser/components/safebrowsing/content/malware-warden.js +++ b/browser/components/safebrowsing/content/malware-warden.js @@ -64,6 +64,13 @@ function PROT_MalwareWarden() { "a:1:" + testData.length + "\n" + testData + "\n"; + + testData = "mozilla.com/firefox/its-a-trap.html"; + testUpdate += + "n:1000\ni:test-phish-simple\nad:1\n" + + "a:1:" + testData.length + "\n" + + testData + + "\n"; var dbService_ = Cc["@mozilla.org/url-classifier/dbservice;1"] .getService(Ci.nsIUrlClassifierDBService); diff --git a/browser/components/safebrowsing/content/phishing-afterload-displayer.js b/browser/components/safebrowsing/content/phishing-afterload-displayer.js index 09aa7d803f2..0fbb7e7abca 100644 --- a/browser/components/safebrowsing/content/phishing-afterload-displayer.js +++ b/browser/components/safebrowsing/content/phishing-afterload-displayer.js @@ -532,26 +532,7 @@ PROT_PhishMsgDisplayerCanvas.inherits(PROT_PhishMsgDisplayerBase); * Displays the warning message. First we make sure the overlay is loaded * then call showMessageAfterOverlay_. */ -PROT_PhishMsgDisplayerCanvas.prototype.showMessage_ = function() { - G_Debug(this, "Showing message."); - - // Load the overlay if we haven't already. - var dimmer = this.doc_.getElementById('safebrowsing-dim-area-canvas'); - if (!dimmer) { - var onOverlayMerged = BindToObject(this.showMessageAfterOverlay_, - this); - var observer = new G_ObserverWrapper("xul-overlay-merged", - onOverlayMerged); - - this.doc_.loadOverlay( - "chrome://browser/content/safebrowsing/warning-overlay.xul", - observer); - } else { - // The overlay is already loaded so we go ahead and call - // showMessageAfterOverlay_. - this.showMessageAfterOverlay_(); - } -} +PROT_PhishMsgDisplayerCanvas.prototype.showMessage_ = function() { } /** * This does the actual work of showing the warning message. @@ -678,34 +659,7 @@ PROT_PhishMsgDisplayerCanvas.prototype.isVisibleElement_ = function(elt) { /** * Hide the warning message from the user. */ -PROT_PhishMsgDisplayerCanvas.prototype.hideMessage_ = function() { - G_Debug(this, "Hiding phishing warning."); - G_Assert(this, this.messageShowing_, "Hide message called but not showing?"); - - this.messageShowing_ = false; - this.repainter_.cancel(); - this.repainter_ = null; - - // Hide the warning popup. - var message = this.doc_.getElementById(this.messageId_); - message.hidden = true; - message.style.display = "none"; - var content = this.doc_.getElementById(this.messageContentId_); - content.style.height = ""; - content.style.overflow = ""; - - var tail = this.doc_.getElementById(this.messageTailId_); - tail.hidden = true; - tail.style.display = "none"; - - // Remove the canvas element from the chrome document. - var pageCanvas = this.doc_.getElementById(this.pageCanvasId_); - pageCanvas.parentNode.removeChild(pageCanvas); - - // Hide the dimmer. - var dimarea = this.doc_.getElementById(this.dimAreaId_); - dimarea.hidden = true; -} +PROT_PhishMsgDisplayerCanvas.prototype.hideMessage_ = function() { } /** diff --git a/browser/components/safebrowsing/jar.mn b/browser/components/safebrowsing/jar.mn index 2c7212856c9..51d7b8653dd 100644 --- a/browser/components/safebrowsing/jar.mn +++ b/browser/components/safebrowsing/jar.mn @@ -3,4 +3,5 @@ browser.jar: * content/browser/safebrowsing/sb-loader.js (content/sb-loader.js) + content/browser/safebrowsing/warning-overlay.xul (content/warning-overlay.xul) + content/browser/safebrowsing/report-phishing-overlay.xul (content/report-phishing-overlay.xul) ++ content/browser/safebrowsing/blockedSite.xhtml (content/blockedSite.xhtml) % overlay chrome://browser/content/browser.xul chrome://browser/content/safebrowsing/report-phishing-overlay.xul diff --git a/browser/components/safebrowsing/src/nsSafebrowsingApplication.js b/browser/components/safebrowsing/src/nsSafebrowsingApplication.js index 4649cdf6166..570753c0f41 100644 --- a/browser/components/safebrowsing/src/nsSafebrowsingApplication.js +++ b/browser/components/safebrowsing/src/nsSafebrowsingApplication.js @@ -61,6 +61,13 @@ SafebrowsingApplicationMod.prototype.registerSelf = function(compMgr, fileSpec, fileSpec, loc, type); + + compMgr.registerFactoryLocation(this.cid, + "UrlClassifier Blocked Error Page", + "@mozilla.org/network/protocol/about;1?what=blocked", + fileSpec, + loc, + type); }; SafebrowsingApplicationMod.prototype.getClassObject = function(compMgr, cid, iid) { diff --git a/browser/locales/en-US/chrome/browser/safebrowsing/blockedSite.properties b/browser/locales/en-US/chrome/browser/safebrowsing/blockedSite.properties new file mode 100644 index 00000000000..22cfb423555 --- /dev/null +++ b/browser/locales/en-US/chrome/browser/safebrowsing/blockedSite.properties @@ -0,0 +1,11 @@ +malware.title=Suspected Attack Site! +malware.shortDesc=The web site at %S has been reported as an attack site, and has been blocked based on your security preferences. +malware.longDesc=

Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.

\n

Web site owners who believe their site has been reported as an attack site in error may request a review.

+ +phishing.title=Suspected Web Forgery! +phishing.shortDesc=The web site at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. +phishing.longDesc=

Entering any personal information on this page may result in identity theft or other fraud.

These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.

+ +# Localization note (phishing.learnMoreLink): please leave the text +# as-is. A localized href is pulled in from user preferences automatically. +phishing.learnMoreLink=

You can find out more about how %S protects you from phishing attacks.

diff --git a/browser/locales/en-US/chrome/overrides/appstrings.properties b/browser/locales/en-US/chrome/overrides/appstrings.properties index 357abe385ca..e70e7632de7 100644 --- a/browser/locales/en-US/chrome/overrides/appstrings.properties +++ b/browser/locales/en-US/chrome/overrides/appstrings.properties @@ -60,3 +60,4 @@ externalProtocolUnknown= externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolLaunchBtn=Launch application malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences. +phishingBlocked=The web site at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. diff --git a/browser/locales/en-US/chrome/overrides/netError.dtd b/browser/locales/en-US/chrome/overrides/netError.dtd index 2d3d56a1701..9487d491575 100644 --- a/browser/locales/en-US/chrome/overrides/netError.dtd +++ b/browser/locales/en-US/chrome/overrides/netError.dtd @@ -140,3 +140,9 @@

Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.

Web site owners who believe their site has been reported as an attack site in error may request a review.

"> + + +Entering any personal information on this page may result in identity theft or other fraud.

+

These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.

+"> diff --git a/browser/locales/jar.mn b/browser/locales/jar.mn index 830120e52d1..686a5ba45a2 100644 --- a/browser/locales/jar.mn +++ b/browser/locales/jar.mn @@ -37,6 +37,7 @@ #ifdef MOZ_SAFE_BROWSING locale/browser/safebrowsing/phishing-afterload-warning-message.dtd (%chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd) locale/browser/safebrowsing/report-phishing.dtd (%chrome/browser/safebrowsing/report-phishing.dtd) + locale/browser/safebrowsing/blockedSite.properties (%chrome/browser/safebrowsing/blockedSite.properties) #endif locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd) locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 9e0c5e4fa6e..1d33b089882 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -2853,6 +2853,9 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI, nsresult rv = NS_OK; nsAutoString messageStr; nsCAutoString cssClass; + nsCAutoString errorPage; + + errorPage.AssignLiteral("neterror"); // Turn the error code into a human readable error message. if (NS_ERROR_UNKNOWN_PROTOCOL == aError) { @@ -2947,6 +2950,25 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI, } if (!messageStr.IsEmpty()) error.AssignLiteral("nssFailure2"); + } else if (NS_ERROR_PHISHING_URI == aError || NS_ERROR_MALWARE_URI == aError) { + nsCAutoString host; + aURI->GetHost(host); + CopyUTF8toUTF16(host, formatStrs[0]); + formatStrCount = 1; + + // Malware and phishing detectors may want to use an alternate error + // page, but if the pref's not set, we'll fall back on the standard page + nsXPIDLCString alternateErrorPage; + mPrefs->GetCharPref("urlclassifier.alternate_error_page", + getter_Copies(alternateErrorPage)); + if (alternateErrorPage) + errorPage.Assign(alternateErrorPage); + + if (NS_ERROR_PHISHING_URI == aError) + error.AssignLiteral("phishingBlocked"); + else + error.AssignLiteral("malwareBlocked"); + cssClass.AssignLiteral("blacklist"); } else { // Errors requiring simple formatting @@ -2993,15 +3015,6 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI, // Bad Content Encoding. error.AssignLiteral("contentEncodingError"); break; - case NS_ERROR_MALWARE_URI: - nsCAutoString host; - aURI->GetHost(host); - CopyUTF8toUTF16(host, formatStrs[0]); - formatStrCount = 1; - - error.AssignLiteral("malwareBlocked"); - cssClass.AssignLiteral("blacklist"); - break; } } @@ -3042,8 +3055,8 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI, // URI object. Missing URI objects are handled badly by session history. if (mUseErrorPages && aURI && aFailedChannel) { // Display an error page - LoadErrorPage(aURI, aURL, error.get(), messageStr.get(), - cssClass.get(), aFailedChannel); + LoadErrorPage(aURI, aURL, errorPage.get(), error.get(), + messageStr.get(), cssClass.get(), aFailedChannel); } else { @@ -3066,6 +3079,7 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI, NS_IMETHODIMP nsDocShell::LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL, + const char *aErrorPage, const PRUnichar *aErrorType, const PRUnichar *aDescription, const char *aCSSClass, @@ -3135,7 +3149,9 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL, char *escapedDescription = nsEscape(NS_ConvertUTF16toUTF8(aDescription).get(), url_Path); char *escapedCSSClass = nsEscape(aCSSClass, url_Path); - nsCString errorPageUrl("about:neterror?e="); + nsCString errorPageUrl("about:"); + errorPageUrl.AppendASCII(aErrorPage); + errorPageUrl.AppendLiteral("?e="); errorPageUrl.AppendASCII(escapedError); errorPageUrl.AppendLiteral("&u="); diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index e44a8deb521..6dbd4eb2e0d 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -404,7 +404,8 @@ protected: const PRUnichar *aURL, nsIChannel* aFailedChannel = nsnull); NS_IMETHOD LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL, - const PRUnichar *aPage, + const char *aErrorPage, + const PRUnichar *aErrorType, const PRUnichar *aDescription, const char *aCSSClass, nsIChannel* aFailedChannel); diff --git a/docshell/base/nsWebShell.cpp b/docshell/base/nsWebShell.cpp index d561c75893a..c146c498fd9 100644 --- a/docshell/base/nsWebShell.cpp +++ b/docshell/base/nsWebShell.cpp @@ -1195,6 +1195,7 @@ nsresult nsWebShell::EndPageLoad(nsIWebProgress *aProgress, aStatus == NS_ERROR_NET_INTERRUPT || aStatus == NS_ERROR_NET_RESET || aStatus == NS_ERROR_MALWARE_URI || + aStatus == NS_ERROR_PHISHING_URI || NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) { DisplayLoadError(aStatus, url, nsnull, channel); } diff --git a/dom/locales/en-US/chrome/appstrings.properties b/dom/locales/en-US/chrome/appstrings.properties index b31d45522e7..2efa1b8fed8 100644 --- a/dom/locales/en-US/chrome/appstrings.properties +++ b/dom/locales/en-US/chrome/appstrings.properties @@ -60,3 +60,4 @@ externalProtocolUnknown= externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolLaunchBtn=Launch application malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences. +phishingBlocked=The web site at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. diff --git a/dom/locales/en-US/chrome/netError.dtd b/dom/locales/en-US/chrome/netError.dtd index d92d0808f53..4ea705029c3 100644 --- a/dom/locales/en-US/chrome/netError.dtd +++ b/dom/locales/en-US/chrome/netError.dtd @@ -59,3 +59,9 @@

Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.

Web site owners who believe their site has been reported as an attack site in error may request a review.

"> + + +Entering any personal information on this page may result in identity theft or other fraud.

+

These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.

+"> diff --git a/toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp b/toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp index 6991ed8d6b8..7ad3969172d 100644 --- a/toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp +++ b/toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp @@ -2107,6 +2107,13 @@ nsUrlClassifierClassifyCallback::HandleEvent(const nsACString& tables) tables.EndReading(end); if (FindInReadable(NS_LITERAL_CSTRING("-malware-"), begin, end)) { response = NS_ERROR_MALWARE_URI; + } else { + // Reset begin before checking phishing table + tables.BeginReading(begin); + + if (FindInReadable(NS_LITERAL_CSTRING("-phish-"), begin, end)) { + response = NS_ERROR_PHISHING_URI; + } } mCallback->OnClassifyComplete(response); diff --git a/uriloader/base/nsURILoader.h b/uriloader/base/nsURILoader.h index 854d364d767..2ef4ce74bdb 100644 --- a/uriloader/base/nsURILoader.h +++ b/uriloader/base/nsURILoader.h @@ -93,9 +93,10 @@ protected: }; /** - * The load has been cancelled because it was found on a malware blacklist. + * The load has been cancelled because it was found on a malware or phishing blacklist. * XXX: this belongs in an nsDocShellErrors.h file of some sort. */ #define NS_ERROR_MALWARE_URI NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_URILOADER, 30) +#define NS_ERROR_PHISHING_URI NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_URILOADER, 31) #endif /* nsURILoader_h__ */