Is it possible to prevent image hotlinking ?

Dec 2, 2010 at 12:38 PM

I have two questions


1)I wonder if this great Blogging CMS also has any mechanism to prevent hot linking or leeching...If some one directly place <img src=....image.axd...  inside their code how to prevent that from happening...

2)How to know what post GUID has been served from code behind in Site.Master

-- I am creating Category-wise recent posts widget for my blog and will share with community


I would also like to thank Ben Amanda (Moderator , BE)  without whom i could not have created the

Category - Sub Category Menu for my BE powered blog - http://bit.ly/gtcRWc

It uses Jquery and is a menu widget for Arthemia theme.I will soon share this widget (minor fixes) with the community..

Thanks in advance...

Coordinator
Dec 2, 2010 at 11:55 PM

Your site is looking good.  Good theme.

In site.master.cs, you can add this to determine what Post is being served.  It's intended to work when an individual post is being viewed (i.e. not the homepage).

if (System.IO.Path.GetFileName(Request.Url.GetLeftPart(UriPartial.Path)).Equals(
  "post.aspx", StringComparison.OrdinalIgnoreCase) &&
  !string.IsNullOrEmpty(Request.QueryString["id"]) &&
  Request.QueryString["id"].Length == 36)
{
	Guid postId = new Guid(Request.QueryString["id"]);
	Post postBeingServed = Post.GetPost(postId);
}

Below is an extension I created (with minimal testing) you could add to the App_Code\Extensions directory.  It will not serve the image, and instead return a 403 error if the request is coming from a different site -- i.e. a person adds your image into their post or HTML page.  You'll see that it allows NULL referrers, which is probably okay to do.  This logic could be adjusted, but seems to work good.

using System;
using System.Linq;
using System.Web;
using BlogEngine.Core;
using BlogEngine.Core.Web.Controls;
using BlogEngine.Core.Web.HttpHandlers;

[Extension("Prevents image leeching", "1.0", "BlogEngine.NET")]
public class ImageLeeching
{
    static ImageLeeching()
    {
        ImageHandler.Serving += new EventHandler<EventArgs>(ImageHandler_Serving);
    }

    private static void ImageHandler_Serving(object sender, EventArgs e)
    {
        HttpContext context = HttpContext.Current;
        Uri referrer = context.Request.UrlReferrer;

        // allowing a NULL referrer, this could be changed.

        if (referrer != null &&
            !referrer.Host.Equals(context.Request.Url.Host,
            StringComparison.OrdinalIgnoreCase))
        {
            context.Response.Clear();
            context.Response.StatusCode = 403;
            context.Response.Write("Stop leeching...");
            context.Response.End();
        }
    }
}

Dec 3, 2010 at 11:59 AM

Thanks you very much, works like a charm.

One thing: You should remove "www." from context.Request.Url.Host and referrer.Host since one can include a "www." and the other not -> preventing the display of your images at your own blog.

 

Dec 3, 2010 at 6:00 PM
Thanks for the appreciation !

With that handy code underbelt i expect my work will take lesse time.

Request.QueryString["id"] is the keypoint...hmm..

Thanks again for the anti-leeching codes..I will be back with the results soon.:)

Bye !!

BenAmada wrote:

Your site is looking good.  Good theme.

In site.master.cs, you can add this to determine what Post is being served.  It's intended to work when an individual post is being viewed (i.e. not the homepage).

 

if (System.IO.Path.GetFileName(Request.Url.GetLeftPart(UriPartial.Path)).Equals(
  "post.aspx", StringComparison.OrdinalIgnoreCase) &&
  !string.IsNullOrEmpty(Request.QueryString["id"]) &&
  Request.QueryString["id"].Length == 36)
{
	Guid postId = new Guid(Request.QueryString["id"]);
	Post postBeingServed = Post.GetPost(postId);
}

 

Below is an extension I created (with minimal testing) you could add to the App_Code\Extensions directory.  It will not serve the image, and instead return a 403 error if the request is coming from a different site -- i.e. a person adds your image into their post or HTML page.  You'll see that it allows NULL referrers, which is probably okay to do.  This logic could be adjusted, but seems to work good.

 

using System;
using System.Linq;
using System.Web;
using BlogEngine.Core;
using BlogEngine.Core.Web.Controls;
using BlogEngine.Core.Web.HttpHandlers;

[Extension("Prevents image leeching", "1.0", "BlogEngine.NET")]
public class ImageLeeching
{
    static ImageLeeching()
    {
        ImageHandler.Serving += new EventHandler<EventArgs>(ImageHandler_Serving);
    }

    private static void ImageHandler_Serving(object sender, EventArgs e)
    {
        HttpContext context = HttpContext.Current;
        Uri referrer = context.Request.UrlReferrer;

        // allowing a NULL referrer, this could be changed.

        if (referrer != null &&
            !referrer.Host.Equals(context.Request.Url.Host,
            StringComparison.OrdinalIgnoreCase))
        {
            context.Response.Clear();
            context.Response.StatusCode = 403;
            context.Response.Write("Stop leeching...");
            context.Response.End();
        }
    }
}

 

 

Request.QueryString["id"]
Jan 26, 2011 at 10:20 AM

On the anti-leeching extension...

Thanks for that, looks useful. I tried it, modified for the presence of "www" as suggested, but it doesn't seem to work for me. Even if I comment out the test and just try to 403 all requests (through file.axd), I can't get it to work.

I think I'm missing something... is there more I have to do. Here's precisely what I did.

  1. Save the above code (just he ImageLeeching class and decoration into a the class file ImageLeeching.cs.
  2. Put that in the in the App_Code/Extensions directory.
  3. Bounce the site and check that the extension's in the list (it is). Check that the source is there (it is).
  4. Try to load the image from /BlogEngine.NET/file.axd with the path copied from my blog. Works fine, even though I can see the referrer is wildly different from my site name.

Other tests:

  1. Comment out the tests, and try to get it to return 403 for everything. This fails: it looks like the event handler isn't being registered/ called.

Any ideas: which dumb mistake did I make, anyone?

 

Jan 26, 2011 at 10:45 AM

I think you need to get the image using 'image.axd' instead of 'file.axd'. I don't know the code behind but

ImageHandler.Serving += new EventHandler<EventArgs>(ImageHandler_Serving);

looks like a different handler than the file handler. Maybe this works...

Jan 26, 2011 at 11:04 AM

You are quite correct sir: thanks!

It also points out a slight work-around to anyone smart enough to know and not smart enough to copy the images and host them locally: use the file format and you can still leech. I think I'm not too bothered by that, although I guess I could fix it with the same extension, just hook the file  handler also.

thanks all

Apr 24, 2011 at 1:17 AM
Edited Apr 24, 2011 at 1:20 AM

Thanks for the code.  I was wondering if that was possible as I've had people hotlinking my images.  

I added the handler to FileHandler.Serving as well, to prevent file hotlinks.  Will test it out pronto.  

May 17, 2012 at 4:01 PM
WildNelson wrote:

Thanks for the code.  I was wondering if that was possible as I've had people hotlinking my images.  

I added the handler to FileHandler.Serving as well, to prevent file hotlinks.  Will test it out pronto.  

 

WildNelson,

Did you manage to add the handler to FileHandler.Serving as well, to prevent file hotlinks.  I have managed to restrict access to my blog by using SqlMembershipProvider and SqlRoleProvider. However all the files and images that I post within my membership access only blog have the url http://www.itradepod.com/Blog/file.axd?file=[filename].pdf and members are able to share these links with non members who should not be able to access those files but they can and this a major security loop hole. Any help would be much appreciated. Thanks.