Coding
Using a HttpModule to protect your content from 3rd party referrals.
by Anand Balaji on May.25, 2010, under Coding
There are certain cases under which you may wish to “discourage” external sites from linking directly to public content (images, documents …) on your site. You may for example, prefer to have user’s visit your site first before accessing any of your resources.
The sample code attached to this post illustrates how to use a HttpModule to act as a filter which prevents third-party sites from linking to your content. You can use this approach to prevent others from linking to pages, images and other resources.
Revision History
v1.0 – Initial code base (25/5/2010) – Download from here.
Section 1.0 – Configuration
a. Unzip the file and deploy it to a folder of your choice.
b. Register “non-standard” extensions – You will need (under IIS 5.x and 6) to register non-standard file extensions (e.g. .js, .jpg, .gif etc.). This enables requests for these resources to be channelled via the ASP.NET engine.
The image below depicts .jpg files being associated with the ASP.NET ISAPI engine. You should limit the HTTP verbs to a range that is supported by your web-site.
![]()
The image below shows the application configuration screen that is used to add file mappings under IIS.
c. Open the web.config file and locate the xanWebFilter node. Next, add file extensions that you wish to ban. I’ve added asmx files which would cause requests from third party sites to be redirected to yahoo.com. Similarly, I’ve added a jpg key that causes all non-validated requests to be transferred to banned.htm
1: <!-- Xanthium web-filter specific values. -->
2: <xanWebFilter>
3: <add key="asmx" value="http://yahoo.com"></add>
4: <add key="jpg" value="http://localhost/banned.htm"></add>
5: </xanWebFilter>
d. Ensure that the web.config file refers to the HTTP Module (IIS <= v6 or IIS7 classic mode)
<system.web>
<httpModules>
<add type="XanIISUtils.BannedExtensionFilter"
name="xanthiumContentFilter"/>
</httpModules>
</system.web>
web.config changes (IIS7 integrated mode)
<system.web>
<httpModules>
<add type="XanIISUtils.BannedExtensionFilter"
name="xanthiumContentFilter"/>
</httpModules>
</system.web>
e. Compile the code and run it. You will see that requests for asmx and jpg files that do not have HTTP referrers set will result in redirects to yahoo and banned.htm respectively.
Section 2.0 – How it works
The application makes use of the functionality provided by the HttpModule class which allows HTTP events to be subscribed to. This allows a piece of code for example, to be invoked when a request is received for a resource managed by the ASP.NET subsystem.
In a similar fashion, you could subscribe to the Http_EndRequest event to append data (for example) to a stream returned by the server.
The following code in BannedExtensionFilter illustrates how an event is registered
public override void Init(HttpApplication app)
{
...
// Register handlers that are called each time a request is received.
app.BeginRequest += new EventHandler(this.Application_BeginRequest);
}
Next, when an event is called, the framework automatically invokes Application_BeginRequest() within BannedExtensionFilter. This method is responsible for determining whether a request should proceed unhindered or should be redirected. The following steps briefly describe the steps performed -
1. Determine whether the requested resource is part of a banned extension. In our example, this would be true for asmx and jpg files.
2. If the file is “black-listed”, determine whether the request should be redirected based on the return value of IsValidRequest().
IsValidRequest() performs a simple check to determine whether the HTTP referrer is set to the current application server. If the referrer is something else – the method flags this request for rejection.
protected Boolean IsValidRequest(HttpApplication app)
{
Uri fromUrl = app.Request.UrlReferrer;
if ( null == fromUrl )
{
return false;
}
// Referrer is not empty - check to see whether it happens to
// be this server's name
return _serverName.ToLowerInvariant() == fromUrl.Host ? true : false;
}
The current method of validating the HTTP request header for the referrer leaves a lot to be desired, you can start by using some sort of cookie/session check to make things more robust as well as to cater to those (usually custom coded) HTTP clients that may not set a referrer. You can either completely replace IsValidRequest() or override it in a derived class.
Section 3.0 – Conclusion
The code helps illustrate how HTTP modules could be better alternatives to performing similar tasks within the (beloved?) global.asax file. You should typically use this approach if -
1. You are using IIS7 in integrated pipeline mode and want to marshal ALL application requests through your code. I realise that I have not yet talked about setting up the handler for IIS7 – I’ll update the article at a later stage.
2. You need to keep the code modular and reusable within multiple applications. All you need to do is to compile the files into a library and store it within the GAC.
3. You believe in keeping a clean, non-complicated global.asax file.
Section 4.0 – Disclaimer
This code is released “as-is” without any sort of warranty. Please feel free to use it and modify it in your own projects. The code has been kept as simple as possible so that key concepts can be easily understood by the reader.
Please do feel to drop me an email if you find the code useful or if you have any questions.
Anand Balaji
Wix – How to forcibly overwrite pre-existing files during installation.
by Anand Balaji on Mar.07, 2009, under Coding
The fly in the ointment
Wix v2 is a pretty nifty tool but since there are a few nasty surprises in store for those who don’t know exactly what it does behind the scenes. More importantly, the Windows Installer tries to perform the intelligent thing of not installing files if the source and destination are exactly the same. This is done by comparing a checksum of the source and destination files. If the checksums match, the file isn’t overwritten at all!
Why would you want to overwrite the same file?
There are a few cases where you might need to do this. For example, if your application relies on the date-time stamps of files for copy-protection or versioning (amongst other things), the checksum comparison will ensure that files having the same checksums are not overwritten. This is not what you might have expected from an installer as one would logically (and sensibly) expect a well behaved installer to blindly overwrite pre-existing files on disc.
It thus becomes impossible for one to overwrite files that are exactly the same even though their timestamps do not match!
Solution
Fortunately enough there is a “directive” which can override this behaviour. Simply add the following line to your .wxs file -
<Property Id=”REINSTALLMODE” Value=”amus”/>
Conclusion
Admit it! Quick fixes aren’t usually as simple as this little tit-bit! I was lucky to come across this solution on the Internet (after a long and arduous journey) and decided to put it on a page exclusively devoted to this topic. Hope that someone finds it helpful!
Anand
Wix – My perfectly imperfect msi file
by Anand Balaji on Oct.16, 2008, under Coding
Wix is an extremely powerful tool that should help you create installers for almost every conceivable type of setup scenario. It’s not without its flaws though and some of its quirks can result in you wasting a not so inconsiderable amount of time. I’ve listed a few of the items that frustrated me. The solutions over here should hopefully prove helpful to you.
My perfectly behaved yet perfectly useless SAPI installer
I had taken the responsibility of creating an installer for one of the products designed by my firm. As part of the install process, the installer needed to install version 5.1 of Microsoft’s Speech Engine.
Microsoft had played their part and created a set of nifty merge (basically a bunch of .MSM files – if you didn’t know that, you’ve got a long way to go buddy!) modules. What could be simpler than adding the msm files to your wixproject, referencing them and then compiling your shiny new creation?
Well to cut to the chase, my spanking new MSI was created. It appeared to install fine but it didn’t actually seem to install all of the files.
Before this incident, the general impression that I got was that MSIs were more of a “plug-and-play” solution and that one didn’t have to worry about the fine intricacies of what the MSM was doing. Wix changed all that…
After a day of accomplishing almost nothing, I came to the conclusion that Wix did almost certainly not know what to do with the contents of the MSI file beyond installing them. My hunch turned out to be correct.
It seems that Wix needs to be (ahem) “prodded” to perform additional tasks that are contained within the MSM database. It won’t do them unless your application -
a. Performs the same tasks as part of its installation routine. For example, if your wxs/wxi files add registry entries as part of the install routine, then Wix will ensure that any registry entries required by the MSM are carried out at runtime as well.
b. Explicitly “prods” Wix to perform one or more tasks within the InstallExecuteSequence directive.
Once you’ve understood that, all you need to do is to add the following snippets of code to your wxs file
<InstallExecuteSequence>
<RemoveFiles />
<InstallFiles />
<WriteRegistryValues />
<CreateFolders/>
<RegisterTypeLibraries/>
<DuplicateFiles/>
<RegisterClassInfo/>
<RegisterProgIdInfo/>
<SelfRegModules/>
</InstallExecuteSequence>
You might need to add a few additional entries, but I think that the ones given above should suffice. Note that the WIX team does not count this as a bug. They claim that the MSM files have been “improperly” created. Basically it sounds that a lot of inter-office “blame the other party” nonsense, but I don’t have the time nor the mental-bandwidth to care.
PS: Users of Crystal Reports’ MSM modules may face the same problems too. The solution is more or less the same…
- Anand Balaji