Navigation

>> Home
 
ASP.NET (13)
Security (5)
"Classic" ASP (2)
C# (1)
VB.NET (1)
ASP and Flash (1)
 
About Us
 
Chinese Content German Content

 

Enforcing Banners

Written by: Christoph Wille
Translated by: Bernhard Spuida
First published: 10/1/2001

Many users surfing the Net use so called banner blockers (ad blockers), which block advertising banners - a well known tool in this category is the WebWasher. However, there are many Web sites on the Internet financing their contents by means of banner advertising on their pages. For these Web sites, such tools as the WebWasher truly are "Killer Apps" as they effectively filter out their source of revenue.

As a colleague of mine uses WebWasher, I sat down with him to discuss the technical possibilites for outwitting WebWasher as a Web site operator:

  • Non-standard sizes of the ad banners. This is obviously a no go.
  • As the filters are for URL as well as image size, all graphics for the page are created in banner size. Should the user then attempt to filter the banners, he will experience a 'white surprise'.
  • Cut up the banner ads, and send in non-standard sizes. As long as no animated banners are used, this would actually work.
  • Do not display the page when the banners weren't loaded.

The last item sounds almost naive, but after some thoughts this was the approach we liked best.

The Basic Idea

The idea behind this is amazingly simple: every modern browser supports CSS and DIV tags. Using CSS, DIV tags can be rendered invisible - it is thus a nearly obvious idea to hide the page content inside an invisible DIV tag until the banners were loaded. In case the banner does not arrive, the DIV tag won't be set to visible - tough luck for the advertisement shy.

The toggling from invisible to visible is done using an event on the banner ad image tag. This means that JavaScript must be enabled - this way, we also automatically have a browser test included.

In the file bannerpage.htm I have implemented a simple page using this idea:

<html>
<head>
        <title>Bannerpage</title>
</head>
<body>

<div id="pleaseWait">
Please wait while the page is being loaded. Should you experience problems,
<a href="">please klick here</a>.
</div>

<div id="mainDiv" STYLE="display:None;">
<p>This content is only displayed after the banner has loaded - together with the Banner.</p>
<img src="http://ads.softartisans.com/servead.asp?s=11&b=1" onload="yesImage()">
</div>

<SCRIPT LANGUAGE=JavaScript>
<!--
function yesImage()
{
  document.all.pleaseWait.style.display = "none";
  document.all.mainDiv.style.display = "";
}
//-->
</SCRIPT>

</body>
</html>

There are two DIV tags - pleaseWait containing the message that the page is being loaded and mainDiv which is hidden and encloses the content of the page which is to be protected. The onload event with the function yesImage is hooked to the image tag - when the event triggers, the image is done loading and the visibility of the two DIV tags is swapped.

With this, our content is efficiently protected - should the image be 'killed' by a banner blocker, the event is never triggered. As CSS is automatically executed, the user also will not have a chance to render the content visible (unless he saves the file to disk and modifies the HTML).

The idea behind the "please wait" message containing the link is to let the customer who does not get to see the content due to blocking go to a page where he will find a courteous explanation of why he did not get to see anything. On sites with only a few banner ads (such as AspHeute) most visitors will probably not be upset.

Implementation in ASP

The HTML page presented has certain disadvantages - the DIV tags have fixed names and would thus be prone to be easily deleted automatically. Therefore we will somewhat 'take this into consideration' in our implementation in ASP - and extend this protection toward the variable and function names in JavaScript as well.

I implemented the desired functionality in bannerfunctions.asp which can be included into any file to be protected.

The Include

An important prerequisite for us is that the names of the DIV tags are not to be set as givens. This suggests that we might adapt the functions of the German-only article Generierung eines sicheren Passworts somewhat:

<script language="vbscript" runat="server">
Function GenerateRandom(ByVal Laenge)
  Dim intI, strRandom
  strRandom = ""
  For intI = 1 to Laenge
    strRandom = strRandom & GenerateCharacter()
  Next
  GenerateRandom = strRandom
End Function

Function GenerateCharacter()
  Dim intRnd, strRnd
  Randomize
  Do
    intRnd = Int(Rnd * 60)
    If intRnd >=52 Then
      strRnd = CStr(intRnd - 51)
    ElseIf intRnd >= 26 Then
      strRnd = Chr(Asc("A") + intRnd - 26)
    Else
      strRnd = Chr(Asc("a") + intRnd)
    End If
  Loop Until (strRnd <> "0" And strRnd <> "l" _
    And strRnd <> "I")
  GenerateCharacter = strRnd
End Function
</script>

By calling the function GenerateRandom we obtain a random string of characters we can use as names for DIV tags, variables and functions as well. GenerateRandom first shows up in the functions ShowWaitMessage and PreCreateSections.

<%
Dim m_nSections, m_arrSections(), m_strFunctionName, m_nNumberOfImages
Dim m_strWaitSection
m_nSections = -1
m_nNumberOfImages = 0

Function ShowWaitMessage()
    Dim strMessage
    m_strWaitSection = "div" & GenerateRandom(12)
    strMessage = "<div id=""" & m_strWaitSection & """>" & vbCrlf
    strMessage = strMessage & Please wait while the page is being loaded. "
    strMessage = strMessage & "Should you experience problems, " & _
         "<a href=""xplain.htm"">please klick here</a>."
    strMessage = strMessage & vbCrlf & "</div>" & vbCrlf
    ShowWaitMessage = strMessage
End Function

Sub PreCreateSections(ByVal nSections)
    Dim i
    m_nSections = nSections
    ReDim m_arrSections(nSections)
    For i = 0 To (nSections-1)
        m_arrSections(i) = "div" & GenerateRandom(10)
    Next
    m_strFunctionName = "set" & GenerateRandom(15)
End Sub

In ShowWaitMessage, GenerateRandom is used to generate the name of the DIV tags surrounding the 'please wait' message. The PreCreateSections function serves a very special purpose - after calling it, all the DIV tag sections to be hidden are known by name and can have the corresponding JavaScript rendered using GetDisplayFunction in arbitrary locations (for this however, GetImageFunction would have to be adapted).

Function BeginSection(ByVal nSection)
    If (nSection < 0 Or nSection > m_nSections) Then
        Response.Write "ERROR: BeginSection - section requested does not exist: " & nSection
        Response.End
    End If
    BeginSection = vbCrlf & "<div id=""" & m_arrSections(nSection-1) & _
                """ STYLE=""display:None;"">" & vbCrlf
End Function

Function EndSection()
    EndSection = vbCrlf & "</div>" & vbCrlf
End Function

Function GetImageFunction()
    GetImageFunction = " onload=""" & m_strFunctionName & "()"" "
    m_nNumberOfImages = m_nNumberOfImages + 1
End Function

Function GetDisplayFunction()
    Dim strScript, strVariable, i
    strVariable = "var" & GenerateRandom(10)
    strScript = "<SCRIP" & "T LANGUAGE=JavaScript>" & vbCrlf
    strScript = strScript & "<!--"  & vbCrlf
    strScript = strScript & "var " & strVariable & "=" & m_nNumberOfImages & ";" & vbCrlf
    strScript = strScript & "function " & m_strFunctionName & "() {" & vbCrlf
    strScript = strScript & strVariable & "--;" & vbCrlf
    strScript = strScript & "if (0 == " & strVariable & ") {" & vbCrlf
    strScript = strScript & "document.all." & m_strWaitSection & _
                  ".style.display = ""none"";" & vbCrlf
    For i = 0 To (m_nSections-1)
        strScript = strScript & "document.all." & m_arrSections(i) & _
                ".style.display = """";" & vbCrlf
    Next
    strScript = strScript & "}" & vbCrlf & "}" & vbCrlf & "//-->" & vbCrlf & _
                        "</SCR" & "IPT>" & vbCrlf
    GetDisplayFunction = strScript
End Function
%>

The function BeginSection marks the beginning of a content section, while EndSection marks its end. Why hide several content sections at all? Well, we won't want to make it too easy for blockers to strip out our code, won't we?

The GetImageFunction call is important, as it must be called for each image tag to be protected (example will follow immediately). This way the script knows how the JavaScript function in GetDisplayFunction is to be adapted.

A Banner-Enforcing Page

Enough of preparatory work - now what does the code look like that we have to insert into a page that is to be protected? An example is bannerpage.asp:

<% Option Explicit %>
<html>
<head>
        <title>Bannerpage</title>
</head>
<body>

<!--#include file="bannerfunctions.asp"-->
<%=ShowWaitMessage()%>
<%PreCreateSections(2)%>

<%=BeginSection(1)%>
<p>This content is only diplayed after the Banner has loaded - together with the Banner.</p>
<img src="http://ads.softartisans.com/servead.asp?s=11&b=1" <%=GetImageFunction()%>>
<%=EndSection()%>

<%=BeginSection(2)%>
<p>Further text, merely intended to be a demo.</p>
<%=EndSection()%>

<%=GetDisplayFunction%>

</body>
</html>

First ShowWaitMessage is called, then PreCreateSections creates the sections (in this case, two). Now we can protect the content using BeginSection and EndSection. In each banner image, GetImageFunction is called. Using GetDisplayFunction at the end, the JavaScript is generated.

The HTML then looks as follows:

<html>
<head>
        <title>Bannerpage</title>
</head>
<body>

<div id="divQLyVKAQ3JtdV">
Bitte warten Sie, w&auml;hrend die Seite geladen wird. ...
</div>

<div id="divoFkEnsWByT" STYLE="display:None;">

<p>Dieser Content wird erst nach dem Banner sichtbar - inklusive dem Banner.</p>
<img src="url removed" alt="" onload="setqBv4nJ7uobMWXV2()" >

</div>

<div id="divQi3jesvMdf" STYLE="display:None;">

<p>Weiterer Text, nur als Demo gedacht.</p>

</div>
<SCRIPT LANGUAGE=JavaScript>
<!--
var varKBKozSWZPk=1;
function setqBv4nJ7uobMWXV2() {
varKBKozSWZPk--;
if (0 == varKBKozSWZPk) {
document.all.divQLyVKAQ3JtdV.style.display = "none";
document.all.divoFkEnsWByT.style.display = "";
document.all.divQi3jesvMdf.style.display = "";
}
}
//-->
</SCRIPT>

</body>
</html>

With each request of the page the IDs of the DIV tags, the function name and the variable storing the number of images change. Mixed with a number of content sections this is a tough one to crack for banner blockers.

Conclusion

The script presented of course isn't flawless - the lengths of the names of the DIV tags, variables and function should change randomly. One problem, however, cannot be solved by this script, even with the cleverest modifications: the banner blocker sends a placeholder image instead of the banner ad.

Downloading the Code

Click here to start the download.

©2000-2004 AspHeute.com
All rights reserved. The content of these pages is copyrighted.
All content and images on this site are copyright. Reuse (even parts) needs our written consent.