Preventing Request.Form abuse

M

Mark Rae

Hi,

See the previous thread Request.Form abuse in this newsgroup...

I'm looking for a simple and efficient way to prevent people hijacking the
<form> tags on my websites and using them to send spam. I would imagine
they're using the HttpWebRequest method for this.

Essentially, it would require a property on a WebForm that indicates whether
it is *only* for PostBack (true by default, but configurable), which would
have any client POST request which is not from the URL of the page itself
would be ignored.

Alternatively, a "global" flag which could be set in web.config.

I think this would be of great benefit to everyone, as this sort of attack
is clearly becoming more and more common.

Does anyone have any suggestions for a good way to implement this?

I'm sure, as a group, we could come up with something really solid which
would help us all - as Juan said, we're all up the creek with this.

Let's get our thinking caps on, guys...

Who knows - we might even let Microsoft use it in a future version of
ASP.NET... ;-)

Mark
 
J

John Timney \(MVP\)

Mark Rae said:
Hi,

See the previous thread Request.Form abuse in this newsgroup...

I'm looking for a simple and efficient way to prevent people hijacking the
<form> tags on my websites and using them to send spam. I would imagine
they're using the HttpWebRequest method for this.

Essentially, it would require a property on a WebForm that indicates
whether it is *only* for PostBack (true by default, but configurable),
which would have any client POST request which is not from the URL of the
page itself would be ignored.

Alternatively, a "global" flag which could be set in web.config.

I think this would be of great benefit to everyone, as this sort of attack
is clearly becoming more and more common.

Does anyone have any suggestions for a good way to implement this?

I'm sure, as a group, we could come up with something really solid which
would help us all - as Juan said, we're all up the creek with this.

Let's get our thinking caps on, guys...

Who knows - we might even let Microsoft use it in a future version of
ASP.NET... ;-)

Mark
I'll start with a suggestion and see where the holes spring from!

A list of forms that are only subject to postback on submission is easy to
create and could reside in web.config (or anywhere cachable) - crude, but we
can think of another way later. A begin request intercepted in an
ihttpmodule could verify the ispostback property of any request. If its not
a postback form, and is in the list of forms that require postback then dump
the request and return a redirect to some random fictitious URL. It wont
even touch the actual form being requested.

--
--
Regards

John Timney (MVP)
VISIT MY WEBSITE:
http://www.johntimney.com
http://www.johntimney.com/blog
 
M

Mark Rae

John,
A list of forms that are only subject to postback on submission is easy to
create and could reside in web.config (or anywhere cachable) - crude, but
we can think of another way later. A begin request intercepted in an
ihttpmodule could verify the ispostback property of any request. If its
not a postback form, and is in the list of forms that require postback
then dump the request and return a redirect to some random fictitious URL.
It wont even touch the actual form being requested.

I like it!

If we were to use a real rather than a fictitious URL for the redirect, do
you think that would be a good thing or a bad thing? I guess it would be a
bad thing because (I suppose) it would look to the target URL that the
posting was coming from our IP address rather than the spammer's IP
address...

Being based in the UK, I think I would find it rather satisfying if the
spammers suddenly found themselves trying to post here:
http://www.met.police.uk/computercrime/

:)
 
J

John Timney \(MVP\)

I think I would redirect them to a large video file on one of the online
video places which may well crash their program with the size of the
response. That said, its not fair to send them to someone else server and
use their bandwidth, hence the suggestion of the fictitious URL.

On detecting an attempt to use a postback it would actually be quite easy to
also block their IP real time in the filter, so any future request from them
was always dropped or always resulted in a large video being sent as the
response. It would be a one hit system.

I've done most of what we're dicsussing in the past on net 1.1, but not for
this reason so the code should be very easy to put together.......I'm still
waiting for people to find holes in the suggestion though - Juans a likely
candidate for sinking my idea......lol

--
--
Regards

John Timney (MVP)
VISIT MY WEBSITE:
http://www.johntimney.com
http://www.johntimney.com/blog
 
B

bruce barker \(sqlwork.com\)

this is what validation of viewstate is for. there is nothing you can about
people that know to do a get before the post to get required hiddenfields.
all screenscrape tools help to do this.

-- bruce (sqlwork.com)
 
J

Juan T. Llibre

re:
I'm still waiting for people to find holes in the suggestion though - Juans a likely candidate for
sinking my idea......lol

<lol>

I've been mulling it over, trying to think of a failsafe method...and drawing a blank.

re:
A list of forms that are only subject to postback on submission is easy to create and could reside
in web.config (or anywhere cachable) - crude, but we can think of another way later.

That could get cumbersome.

re:
A begin request intercepted in an ihttpmodule could verify the ispostback property of any request.

Remember that the legal use of the form also involves a postback ( does it, Mark? ),
so you can't block on the basis of the request being a postback.

re:
If its not a postback form, and is in the list of forms that require postback then dump the
request and return a redirect to some random fictitious URL. It wont even touch the actual form
being requested.

If what I suspect is true, the reverse procedure would work.

As far as I can determine, the crux is that they aren't using postback, but posting directly to the
form.
( Am I right in assuming that ? ) I need a reality check ... ;-)

If that is so, we shouldn't be thinking about payback (as tempting as it is),
but about a solid defense, preferably one which is simple to implement.

So, if the request being a postback is a requirement, would checking for IsPostBack and,
if it isn't a Postback, clearing all the fields accomplish what we want ?

If the hackers/spammers are *not* using Postback (I am assuming that...) that should work.

The key is whether they *are* POSTing without having requested the page.
If not, then I need to think about this some more.

re:
On detecting an attempt to use a postback it would actually be quite easy to also block their IP
real time in the filter

Wouldn't blocking postbacks also block the intended legal use of the feedback form ?
 
K

Kevin Spencer

I was thinking more along the lines of extending the Page class. I have done
several ASP.Net apps that use an extended Page class for various purposes.
One could easily add a property that handled the situation. But I'm not
saying that the configuration idea is a bad one. I honestly don't know which
would be better.

--
HTH,

Kevin Spencer
Microsoft MVP
Short Order Coder
http://unclechutney.blogspot.com

What You Seek Is What You Get
 
M

Mark Rae

I've been mulling it over, trying to think of a failsafe method...and
drawing a blank.

Yes - it's not as straightforward as it sounds...
That could get cumbersome.

I would agree.
Remember that the legal use of the form also involves a postback ( does
it, Mark? ),

In this particular case, no it doesn't - that's the weird thing! They have
chosen (at random, I'm sure) a ContentPage whose MasterPage has a <form> tag
(obviously, or nothing would work) - but the ContentPage in question doesn't
actually have any data-entry controls nor any submit buttons...
so you can't block on the basis of the request being a postback.

That's right, in this case anyway...
If what I suspect is true, the reverse procedure would work.
Yes.

As far as I can determine, the crux is that they aren't using postback,
but posting directly to the form. ( Am I right in assuming that ? ) I
need a reality check ... ;-)

That is correct - I suspect they're using HttpWebRequest or somesuch...
If that is so, we shouldn't be thinking about payback (as tempting as it
is),
but about a solid defense, preferably one which is simple to implement.
Indeed.

So, if the request being a postback is a requirement, would checking for
IsPostBack and,
if it isn't a Postback, clearing all the fields accomplish what we want ?

No, because there aren't any fields to clear! They are adding fields to the
page's Request.Form object dynamically...
Wouldn't blocking postbacks also block the intended legal use of the
feedback form ?

As above, this isn't a feedback form!!! It has no textboxes or submit
buttons etc. All it has is text and hyperlinks.
 
M

Mark Rae

Yes - it's not as straightforward as it sounds...

Has anyone made any further progress with this, because I certainly
haven't...

In fact, as Bruce hinted, I'm not sure that it's even technically
possible...

So, in the meantime, I've gone with an IP blocking solution which has killed
the spammers dead in their tracks.

If anyone's interested, the IP addresses I've caught (so far!) are:

206.83.210.59
216.224.117.178
58.65.233.129
66.79.163.226
 
J

John Timney \(MVP\)

I think a list of IP's would probably have to do, and as for blocking them
do it in the module as suggested and actually redirect them to one of the
large download sites. Stop them with some payback. I think I have this
written already on another server - might power it up and ressurect the
code, although it can only be 30 lines or so. Now if you could autoextract
the IP's by identifying they were a nusicance to your site, it would be a
useful little sytem......but I agree with Bruce also, not a lot you can do
other than blocking the IP's.

--
Regards

John Timney (MVP)
VISIT MY WEBSITE:
http://www.johntimney.com
http://www.johntimney.com/blog
 
M

Mark Rae

I think a list of IP's would probably have to do, and as for blocking them
do it in the module as suggested and actually redirect them to one of the
large download sites. Stop them with some payback. I think I have this
written already on another server - might power it up and ressurect the
code, although it can only be 30 lines or so. Now if you could autoextract
the IP's by identifying they were a nusicance to your site, it would be a
useful little sytem......but I agree with Bruce also, not a lot you can do
other than blocking the IP's.

This is how I did it...

/* SQL Server */
CREATE TABLE [dbo].[tlkpBlockedIP](
[strIP] [varchar](15) NOT NULL,
CONSTRAINT [PK_tlkpBlockedIP] PRIMARY KEY CLUSTERED
(
[strIP] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

CREATE PROCEDURE [dbo].[uspBlockedIPSelect]
AS
SELECT * FROM tlkpBlockedIP

/* Global.asax */
<%@ Application Language="C#" %>
<%@ Import Namespace="shared" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>

<script runat="server">

void Application_Start(object sender, EventArgs e)
{
SqlDataReader objDR = null;

try
{
List<string> lstBlockedIP = new List<string>();
objDR = CDataAccess.GetSqlDataReader("uspBlockedIPSelect");
while (objDR.Read())
{
lstBlockedIP.Add(objDR.GetString(0));
}
Application["lstBlockedIP"] = lstBlockedIP;
}
catch (Exception ex)
{
CApplication.GlobalExceptionHandler(ex);
}
finally
{
if (objDR != null)
{
if (!objDR.IsClosed)
{
objDR.Close();
}
objDR = null;
}
}
}

void Application_BeginRequest(object sender, EventArgs e)
{
try
{
if
(((List<string>)Application["lstBlockedIP"]).Contains(HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]))
{
HttpContext.Current.Response.StatusCode = 404;
HttpContext.Current.Response.SuppressContent = true;
HttpContext.Current.ApplicationInstance.CompleteRequest();
return;
}
}
catch (Exception ex)
{
CApplication.GlobalExceptionHandler(ex);
}
}

}

</script>
 
J

John Timney \(MVP\)

Nice of you to share the code, that'll do it nicely. :)

--
--
Regards

John Timney (MVP)
VISIT MY WEBSITE:
http://www.johntimney.com
http://www.johntimney.com/blog


Mark Rae said:
I think a list of IP's would probably have to do, and as for blocking them
do it in the module as suggested and actually redirect them to one of the
large download sites. Stop them with some payback. I think I have this
written already on another server - might power it up and ressurect the
code, although it can only be 30 lines or so. Now if you could
autoextract the IP's by identifying they were a nusicance to your site, it
would be a useful little sytem......but I agree with Bruce also, not a lot
you can do other than blocking the IP's.

This is how I did it...

/* SQL Server */
CREATE TABLE [dbo].[tlkpBlockedIP](
[strIP] [varchar](15) NOT NULL,
CONSTRAINT [PK_tlkpBlockedIP] PRIMARY KEY CLUSTERED
(
[strIP] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

CREATE PROCEDURE [dbo].[uspBlockedIPSelect]
AS
SELECT * FROM tlkpBlockedIP

/* Global.asax */
<%@ Application Language="C#" %>
<%@ Import Namespace="shared" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>

<script runat="server">

void Application_Start(object sender, EventArgs e)
{
SqlDataReader objDR = null;

try
{
List<string> lstBlockedIP = new List<string>();
objDR = CDataAccess.GetSqlDataReader("uspBlockedIPSelect");
while (objDR.Read())
{
lstBlockedIP.Add(objDR.GetString(0));
}
Application["lstBlockedIP"] = lstBlockedIP;
}
catch (Exception ex)
{
CApplication.GlobalExceptionHandler(ex);
}
finally
{
if (objDR != null)
{
if (!objDR.IsClosed)
{
objDR.Close();
}
objDR = null;
}
}
}

void Application_BeginRequest(object sender, EventArgs e)
{
try
{
if
(((List<string>)Application["lstBlockedIP"]).Contains(HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]))
{
HttpContext.Current.Response.StatusCode = 404;
HttpContext.Current.Response.SuppressContent = true;
HttpContext.Current.ApplicationInstance.CompleteRequest();
return;
}
}
catch (Exception ex)
{
CApplication.GlobalExceptionHandler(ex);
}
}

}

</script>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top