home *** CD-ROM | disk | FTP | other *** search
/ Windows News 2006 October / wn148cd2.iso / Windows / S'informer / Netcraft / netcrafttoolbar.xpi / chrome / netcrafttoolbar.jar / content / phishtank.js < prev    next >
Text File  |  2005-08-04  |  11KB  |  378 lines

  1. /*
  2.  * NetcraftToolbar - Main Extension Code
  3.  *
  4.  * Copyright (C) 2005 Netcraft Ltd
  5.  * http://toolbar.netcraft.com/ 
  6.  *
  7.  * $Id: chrome:content:phishtank.js,v 1.64 2005/07/21 11:39:26 vb Exp $
  8.  */
  9. const PT_TOOLBARID = "netcrafttoolbar";
  10. const PT_IFRAMEID = "netcrafttoolbar-iframe";
  11. const PT_DESCRIPTIONID = "netcrafttoolbar-description";
  12.  
  13. const PT_RISKBARLEN = 56;
  14. const PT_BUFSIZ = 4096;
  15.  
  16. const PT_SERVERERROR = "Toolbar Server Error";
  17.  
  18. const PT_CHECKURL = "http://mirror.toolbar.netcraft.com/check_url/";
  19. const PT_XSSDATURL = "chrome://netcrafttoolbar/content/xss.dat";
  20. const PT_LBDATURL = "chrome://netcrafttoolbar/content/localblock.dat";
  21. const PT_PHISHINGBLOCKEDURL = "chrome://netcrafttoolbar/content/blocked.html";
  22. const PT_XSSBLOCKEDURL = "chrome://netcrafttoolbar/content/blocked.html";
  23. const PT_LBBLOCKEDURL = "chrome://netcrafttoolbar/content/blocked.html";
  24.  
  25. const PT_ALERTMSG =
  26.     "The page you are trying to visit %ACTION%.\n\n" +
  27.     "URL: %URL%\n\n" +
  28.     "If this is a mistake, please report it using\n" +
  29.     "'Report Incorrect Blocked URL' in the Netcraft Menu.\n\n" +
  30.     "Do you still want to go there?";
  31.  
  32. const PT_BLOCKACTION = "has been blocked by the Netcraft Toolbar because it\n";
  33. const PT_PHISHINGMSG = PT_BLOCKACTION +
  34.     "is believed to be part of a fraudulent phishing attack";
  35. const PT_XSSMSG = "is using Cross-Site Scripting (XSS).\n" +
  36.     "This is a technique commonly used in phishing attacks";
  37. const PT_LBMSG  = PT_BLOCKACTION +
  38.     "contains suspicious characters, indicating that it may be a malicious site";
  39. const PT_NOINFO = "No information available";
  40.  
  41. var phishTank = {
  42.  
  43.     QueryInterface: function(aIID) {
  44.     if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
  45.         aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
  46.         aIID.equals(Components.interfaces.nsISupports))
  47.         return this;
  48.     throw Components.results.NS_NOINTERFACE;
  49.     },
  50.     onLocationChange: function(aProgress, aRequest, aURI) {
  51.  
  52.     if (!aURI) return 0;
  53.  
  54.     var toolbar = document.getElementById(PT_TOOLBARID);
  55.     if ((toolbar != null) && toolbar.collapsed) {
  56.         this.displayHoster("");
  57.         return 0;
  58.     }
  59.  
  60.     switch (aURI.scheme) {
  61.         case "http":
  62.         case "https":
  63.         case "ftp":
  64.         this.changeToolbar(aURI);
  65.         break;
  66.  
  67.         default:
  68.         this.displayHoster("");
  69.         break;
  70.     }
  71.  
  72.     return 0;
  73.     },
  74.     onStateChange: function(aProgress, aRequest, aFlag, aStatus) { return 0; },
  75.     onProgressChange: function() { return 0; },
  76.     onStatusChange: function() { return 0; },
  77.     onSecurityChange: function() { return 0; },
  78.     onLinkIconAvailable: function() { return 0; },
  79.  
  80.     changeToolbar: function (aURI) {
  81.     var key = aURI.scheme + "://" + aURI.hostPort;
  82.     var url = aURI.asciiSpec;
  83.  
  84.     if (ptRoot.xss &&
  85.         this.checkPatterns(ptRoot.xss, this.canonicaliseURL(url)) &&
  86.         this.yesno("Block XSS?", PT_XSSMSG, url)
  87.     ) {
  88.         this.displayHoster("XSS URL blocked!");
  89.         top.document.getElementById("content").
  90.         contentDocument.location.replace(PT_XSSBLOCKEDURL);
  91.         return;
  92.     }
  93.  
  94.     if (ptRoot.lb &&
  95.         this.checkPatterns(ptRoot.lb, url) &&
  96.         this.yesno("Block Suspicious URL?", PT_LBMSG, url)
  97.     ) {
  98.         this.displayHoster("Suspicious URL blocked!");
  99.         top.document.getElementById("content").
  100.         contentDocument.location.replace(PT_LBBLOCKEDURL);
  101.         return;
  102.     }
  103.  
  104.     if (ptRoot.lookup[key]) {
  105.         this.updateIframe(ptRoot.lookup[key], url);
  106.     }
  107.     else if (ptToolbarPrefs.isOffline()) {
  108.         this.displayHoster("offline");
  109.         return;
  110.     }
  111.     else {
  112.         var check_url = PT_CHECKURL + aURI.scheme + "://" + aURI.asciiHost;
  113.         if (aURI.port > 0)
  114.         check_url += ":" + aURI.port;
  115.  
  116.         var ip = ptDns.dnsResolve(aURI.host);
  117.         if (ip) {
  118.         if (ptDns.unroutableIP(ip)) {
  119.             this.displayHoster(PT_NOINFO);
  120.             return;
  121.         }
  122.         else
  123.             check_url += "/" + ptDns.convertIP(ip);
  124.         this.fetchInfo(key, check_url, url);
  125.         }
  126.     }
  127.     return;
  128.     },
  129.  
  130.     fetchInfo: function (key,chkurl,url) {
  131.     var daddy = this;
  132.     var req = new XMLHttpRequest();
  133.     req.open("GET", chkurl, true);
  134.     req.key = key;
  135.     req.onreadystatechange = function() {
  136.         if (req.readyState == 4) {
  137.         daddy.updateIframe(req, url);
  138.         }
  139.         else
  140.         daddy.displayHoster(key + "....!".substr(0,req.readyState+1));
  141.     }
  142.     req.send(null);
  143.     return true;
  144.     },
  145.  
  146.     updateIframe: function (req,url) {
  147.     var descr;
  148.     switch (req.status) {
  149.       case 200:
  150.  
  151.         try {
  152.         var pats = req.getResponseHeader("X-Phishing-Patterns");
  153.         }
  154.         catch (e) {}
  155.         if (pats) {
  156.         var patArray = this.headerArray(atob(pats));
  157.         if (this.checkPatterns(this.buildPatterns(patArray), url) &&
  158.             this.yesno("Block Phishing Site?", PT_PHISHINGMSG, url))
  159.         {
  160.             ptRoot.lookup[req.key] = req;
  161.             this.displayHoster("Phishing URL blocked!");
  162.             top.document.getElementById("content").
  163.             contentDocument.location.replace(PT_PHISHINGBLOCKEDURL);
  164.             return;
  165.         }
  166.         }
  167.  
  168.         descr = req.responseText;
  169.  
  170.         var flag = descr.match(/\[(\w\w)\]/);
  171.         if (flag != null) {
  172.         descr = descr.replace(/ \[\w\w\]/,
  173.             '<img src="chrome://netcrafttoolbar/content/flags/' +
  174.             flag[1].toLowerCase() +
  175.             '.gif"/> $&'
  176.         );
  177.         };
  178.  
  179.         var risk = req.getResponseHeader("X-Risk-Rank");
  180.         if (risk) {
  181.         const PT_ABSPOS = "position: absolute; left: 0px; top: 0px;";
  182.         var barLength = Math.round(risk * PT_RISKBARLEN / 10);
  183.         descr =
  184.             '<div style="position: relative;" tooltiptext="">' +
  185.             '<a href="http://toolbar.netcraft.com/help/faq/index.html#riskrating">' +
  186.               '<img style="' + PT_ABSPOS + '" ' +
  187.             'border="0" ' +
  188.             'src="chrome://netcrafttoolbar/content/risk.png" ' +
  189.                 'tooltiptext="Risk Rating: ' + risk + '"' +
  190.               '/>' +
  191.               '<img style="' + PT_ABSPOS +
  192.             'clip: rect(0px ' + barLength + 'px auto 0px);" ' +
  193.             'border="0" ' +
  194.             'src="chrome://netcrafttoolbar/content/bar.png" ' +
  195.                 'tooltiptext="Risk Rating: ' + risk + '"' +
  196.               '/>' +
  197.             '</a>' +
  198.             '</div>' +
  199.             '<nobr style="margin-left: 60px;">' +
  200.             descr +
  201.             '</nobr>';
  202.         }
  203.         descr = descr.replace(/\<a /g, '<a onClick="phishTank.goTo(this.href); return(false);" ');
  204.         ptRoot.lookup[req.key] = req;
  205.         break;
  206.  
  207.       default:
  208.         descr = "[" + PT_SERVERERROR + ": " + req.statusText + "]";
  209.         break;
  210.     }
  211.  
  212.     this.displayHoster(descr);
  213.     },
  214.  
  215.     displayHoster: function (htmlText) {
  216.     var iframe = document.getElementById(PT_IFRAMEID).contentDocument;
  217.     iframe.open();
  218.     iframe.write('<div>' + htmlText + '</div>');
  219.     iframe.close();
  220.     var doc = document.getElementById(PT_DESCRIPTIONID);
  221.     while (doc.hasChildNodes())
  222.         doc.removeChild(doc.firstChild);
  223.     if (iframe.hasChildNodes())
  224.         for (i = 0; i < iframe.childNodes.length; i++)
  225.         doc.appendChild(iframe.childNodes[i]);
  226.     },
  227.  
  228.     substURL: function (str,url) {
  229.     return (
  230.         str.replace(/%URL%/, this.escapeURL(url.toString())).
  231.             replace(/%UUID%/, ptToolbarPrefs.uuid)
  232.     );
  233.     },
  234.  
  235.     yesno: function (title,str,url) {
  236.     var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
  237.         getService(Components.interfaces.nsIPromptService);
  238.  
  239.     var flags = ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_0 +
  240.         ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_1 +
  241.         ps.BUTTON_POS_1_DEFAULT;
  242.  
  243.     str = PT_ALERTMSG.replace(/%ACTION%/,str);
  244.     if (url && url.length)
  245.         str = this.substURL(str,url);
  246.  
  247.     return ps.confirmEx(window, title, str, flags, "Yes", "No", null, null, {});
  248.     },
  249.  
  250.     openURL: function (aURL) {
  251.     var how = ptToolbarPrefs.newWindow();
  252.     var inBg = ptToolbarPrefs.bg();
  253.  
  254.     var theTop = top.document.getElementById("content");
  255.     switch(how) {
  256.       case 3:
  257.         var newtab = theTop.addTab(aURL);
  258.         if (!inBg)
  259.         window.getBrowser().selectedTab = newtab;
  260.         break;
  261.  
  262.       case 2:
  263.         window.open(aURL);
  264.         break;
  265.  
  266.       default:
  267.         theTop.contentDocument.location = aURL;
  268.         if (!inBg)
  269.         window.content.focus();
  270.         break;
  271.     }
  272.     },
  273.  
  274.     goTo: function (url) {
  275.     var loc = window.content.location;
  276.     url = this.substURL(url,loc);
  277.     this.openURL(url);
  278.     },
  279.  
  280.     checkForUpdates: function () {
  281.     if (ptToolbarPrefs.isOffline())
  282.         return false;
  283.     var upd = new XMLHttpRequest();
  284.     upd.open("GET", "http://mirror.toolbar.netcraft.com/install/update.rdf", true);
  285.     upd.onreadystatechange = function() { return; }
  286.     upd.setRequestHeader("User-Agent","%UUID% netcrafttoolbar/1.0.3.3 (b:20050804163834)".replace(/%UUID%/, uuid));
  287.     upd.send(null);
  288.     return true;
  289.     },
  290.  
  291.     /* Network Read */
  292.     URLarray: function (url) {
  293.     var serv = Components.classes["@mozilla.org/network/io-service;1"].
  294.         getService(Components.interfaces.nsIIOService);
  295.     var chan = serv.newChannel(url, null, null);
  296.     var sis = Components.classes["@mozilla.org/scriptableinputstream;1"].
  297.         createInstance(Components.interfaces.nsIScriptableInputStream);
  298.     sis.init(chan.open());
  299.  
  300.     var buf = "";
  301.     while(sis.available() > 0)
  302.           buf += sis.read(PT_BUFSIZ);
  303.     buf = buf.replace(/\s+$/,'');
  304.  
  305.     sis.close();
  306.     return (buf.length > 0 ? buf.split(/[\r\n]+/) : null);
  307.     },
  308.  
  309.     headerArray: function (str) {
  310.     str = str.replace(/\s+$/,'');
  311.     return (str.split(/\t/));
  312.     },
  313.  
  314.     canonicaliseURL: function (url) {
  315.     url = unescape(url.replace(/\+/g, " "));
  316.     url = url.replace(/[\x00-\x08\x0e-\x1f\x7f-\xff]/g, "");
  317.     url = url.replace(/\\/g, "");
  318.     return url;
  319.     },
  320.  
  321.     escapeURL: function (url) {
  322.     url = url.
  323.         replace(/\#/g, "%23").
  324.         replace(/\%/g, "%25").
  325.         replace(/\+/g, "%2b").
  326.         replace(/\&/g, "%26").
  327.         replace(/\?/g, "%3f").
  328.         replace(/\s+/g,'+');
  329.     return url;
  330.     },
  331.  
  332.     buildPatterns: function (strarray) {
  333.     if (!strarray || strarray.length == 0)
  334.         return null;
  335.  
  336.     var patterns = new Array;
  337.     for (var s = 0; s < strarray.length; s++) {
  338.         strarray[s] = strarray[s].replace(/\(\?[\w-]+\)/g,"");
  339.         patterns[s] = new RegExp(strarray[s],"i");
  340.     }
  341.     return(patterns.length > 0 ? patterns : null);
  342.     },
  343.  
  344.     checkPatterns: function (patterns,str) {
  345.     if (!patterns || patterns.length == 0)
  346.         return false;
  347.  
  348.     for (var pat = 0; pat < patterns.length; pat++) {
  349.         if (patterns[pat].exec(str)) {
  350.         return true;
  351.         }
  352.     }
  353.     return false;
  354.     }
  355.  
  356. }
  357.  
  358. var ptRoot = top;
  359. ptRoot.lookup = new Object;
  360. ptRoot.xss = phishTank.buildPatterns(phishTank.URLarray(PT_XSSDATURL));
  361. ptRoot.lb = phishTank.buildPatterns(phishTank.URLarray(PT_LBDATURL));
  362.  
  363. function ptRegisterPhishTank() {
  364.     window.getBrowser().addProgressListener(
  365.     phishTank,
  366.     Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT
  367.     );
  368. }
  369.  
  370. function ptUnregisterPhishTank()
  371. {
  372.     window.getBrowser().removeProgressListener(phishTank);
  373. }
  374.  
  375. window.addEventListener("load", ptRegisterPhishTank, false);
  376. window.addEventListener("unload", ptUnregisterPhishTank, false);
  377.  
  378.