case
11May/101

Check if user visited certain websites

Today I found a website called http://www.stayinvisible.com/ that uses a really clever technique to peak in your browser history. They can't see everything of course but they can see whatever they are interested in and that is a list of web-proxy websites.

So how are they doing it ?

First, they have a list of websites they are interested in, like i said, a list of web-proxies.

1
2
3
4
5
6
7
var sites = {
    "hidemyass.com": ["http://www.hidemyass.com", "http://forum.hidemyass.com"],
    "freeproxy.ca": ["http://www.freeproxy.ca"],
    "proxy4free.com": ["http://www.proxy4free.com"],
    ....
    ....
    }

Second, they create a temporary IFRAME where they write a simple 2 lines CSS that does the magic

1
2
a { color: #000; display: none}
a: visited { color: #F00; display: inline }

... and in the body they append all the links from the sites list.

The browser renders the links, and all the sites that appear in your history will use the "a:visited" CSS class. The others use the normal "a" class that has a display:none property and will be hidden.

What's left to do is iterate all the links from the frame and check if they are visible or not to know which of them are in your history and which of them aren't. Pretty simple eh ?

So here's the class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
var bHistory = function(){
  var sites = {
    "hidemyass.com": ["http://www.hidemyass.com", "http://forum.hidemyass.com"],
    "freeproxy.ca": ["http://www.freeproxy.ca"],
    "proxy.org": ["http://www.proxy.org", "http://www.proxy.org/cgi_proxies.shtml", "http://www.proxy.org/forum/index.html"]
  };
  var visited = {};
  function getStyle(el, scopeDoc,styleProp) {
    if (el.currentStyle) var y = el.currentStyle[styleProp];
    else if (window.getComputedStyle) var y = scopeDoc.defaultView.getComputedStyle(el,null).getPropertyValue(styleProp);
    return y;
  }
  function remove( el ) {
    el.parentNode.removeChild( el );
  }
  function createIframe() {
    var iframe = document.createElement("iframe");
    iframe.style.position = "absolute";
    iframe.style.visibility = "hidden";
    document.body.appendChild(iframe);
    if(iframe.contentDocument) iframe.doc = iframe.contentDocument;
    else if(iframe.contentWindow) iframe.doc = iframe.contentWindow.document;
    iframe.doc.open();
  	iframe.doc.write('<style>');
  	iframe.doc.write("a{color: #000000; display:none;}");
  	iframe.doc.write("a:visited {color: #FF0000; display:inline;}");
  	iframe.doc.write('</style>');
    iframe.doc.close();
    return iframe;
  }
  var iframe = createIframe();
  function embedLinkInIframe( href, text ) {
    var a = iframe.doc.createElement("a");
    a.href = href;
    a.innerHTML = site;
    iframe.doc.body.appendChild( a );
  }
  for( var site in sites ) {
    var urls = sites[site];
    for( var i=0; i<urls .length; i++ ) {
      embedLinkInIframe( urls[i], site );
      if( urls[i].match(/www\./) ){
        var sansWWW = urls[i].replace(/www\./, "");
        embedLinkInIframe( sansWWW, site );
      } else {
        var httpLen = urls[i].indexOf("//") + 2;
        var withWWW = urls[i].substring(0, httpLen ) + "www." + urls[i].substring( httpLen );
        embedLinkInIframe( withWWW, site );
      }
    }
  }
  var links = iframe.doc.body.childNodes;
  for( var i=0; i<links.length; i++) {
    var displayValue = getStyle(links[i], iframe.doc, "display");
    var didVisit = displayValue != "none";
    if( didVisit ){
      visited[ links[i].innerHTML ] = true;
    }
  }
  remove( iframe );
  var usedSites = [];
  for( var site in visited ){
    usedSites.push( site );
  }
  return usedSites;
}

To use it:

1
2
   var visited = new bHistory();
   alert(visited); // an array with visited websites from the defined list

All credits go to the smart man who did this. Cheers!