Scenario

  1. Visitor clicks a link to the “destination URL”
  2. The browser connects to the “tracking URL”
  3. The browser redirects to the destination “destination URL”

In demo, I use “http://www.example.com/” for the destination URL and “https://bit.ly/1h0ceQI” for tracking URL, where “https://bit.ly/1h0ceQI” redirects to “http://www.example.com/”.

Classical method

The link with tracking url:

<a href="https://tracking-URL/of/destination-URL">click here</a>

Demo:

  • pros
    • Static, javascript no use.
  • cons
    • Mouse overing displays the tracking url, not destination url.

Protection technique to this tracking method:

  • Replace the tracking link href with the destination link.

Classical method with status bar replacement

The link with tracking url:

<a href="https://tracking-URL/of/destination-URL"
   onmouseover="window.status = 'http://destination-URL';"
   onmouseout="window.status = undefined;">
click here
</a>

Demo:

  • pros
    • The destination link is displayed on the status bar.
  • cons
    • The window.status is no longer used today!

Protection technique to this tracking method:

  • Replace the tracking link href with the destination link.

Google-search method

The link with tracking url:

<a href="http://destination-URL"
   onmousedown="this.href = 'https://tracking-URL/of/destination-URL';">
click here
</a>

Demo:

  • pros
    • The tracking url is intentionally hidden since the destination link is displayed on the status bar.
  • cons
    • Once the user click the link, the tracking link is displayed on the status bar.
    • The tracking is disabled when the user disables javascript.

Protection technique to this tracking method:

  • Disable the event handler

    oLink.onmousedown = null;          // To disable a DOM0 event listener.
    oLink.outerHTML = oLink.outerHTML; // To disable DOM2 event listeners.
    
  • Discard href attribute change

    var mutationObserver = new MutationObserver(function (aRecordList) {
        for (var i = 0; i < aRecordList.length; i++) {
            var record = aRecordList[i];
            if (record.target.href.startsWith("https://tracking-URL/")) {
                record.target.href = record.oldValue; 
            }
        }
    });
    mutationObserver.observe(document, {
        attributes: true,
        subtree: true,
        attributeOldValue: true,
        attributeFilter: ["href"]
    });
    
  • … or disable javascript.

Replace-location-on-click method

The link with tracking url:

<a href="http://destination-URL"
   onclick="if (event.button == 0) { window.location = 'https://tracking-URL/of/destination-URL'; }">
click here
</a>

Demo:

  • pros
    • The tracking url is intentionally hidden since the destination link is displayed on the status bar.
  • cons
    • The tracking is disabled when the user disables javascript.

Protection technique to this tracking method:

  • Disable the event handler

    oLink.onclick = null;              // To disable a DOM0 event listener.
    oLink.outerHTML = oLink.outerHTML; // To disable DOM2 event listeners.
    
  • Discard location field modification using Object.watch()

    window.watch("location", function (aProp, aOldVal, aNewVal) {
        if (aNewVal.startsWith("https://tracking-URL/")) {
            throw new Error("tracking is blocked");
        }
        return aNewVal;
    });
    
  • … or disable javascript.

Google-Analytics method

The link with tracking url:

<a href="http://destination-URL"
   onclick="if (event.button == 0) { var img = new Image(); img.src = 'https://tracking-URL/of/destination-URL'; }">
click here
</a>

Demo:

  • pros
    • The tracking url is intentionally hidden since the destination link is displayed on the status bar.
    • No redirection.
  • cons
    • The tracking is disabled when the user disables javascript.

Protection technique to this tracking method:

  • Disable the event handler

    oLink.onclick = null;              // To disable a DOM0 event listener.
    oLink.outerHTML = oLink.outerHTML; // To disable DOM2 event listeners.
    
  • … or disable javascript.

HTML ping attribute (Note)

The link with tracking url:

<a href="http://destination-URL"
   ping="https://tracking-URL/of/destination-URL">
click here
</a>

Demo:

  • pros
    • The tracking url is hidden.
    • No redirection.
    • Static, javascript no use.
  • cons
    • Almost all browser disable this ping feature.

Protection technique to this tracking method:

  • Remove ping attribute
  • Disable ping feature

References