Click here to Skip to main content
15,884,176 members
Articles / Web Development / ASP.NET
Article

Preventing Automated / Dictionary Login Attacks without the use of CAPTCHA

Rate me:
Please Sign up or sign in to vote.
2.88/5 (28 votes)
9 Jan 20053 min read 77.4K   615   31   18
A simple way to prevent automated / dictionary login attacks without the use of CAPTCHA (Completely Automated Public Turing Test to Tell Computers and Humans Apart) images.

Image 1

Introduction

Automated and Dictionary attacks to login is a security threat that every IT is quite aware of. There are many techniques that help address this problem, one of which is the CAPTCHA - an image that contains characters and/or numbers that presumably only humans can read; its value is then entered by the user manually. This helps filter out automated logins. However, this technique can be quite difficult to implement and also costly because you would have to generate image on the fly. Further, some software are designed to figure out the value on the image using technologies similar to OCR scanning. Although CAPTCHA may work most of the time, like I said, it is difficult, expensive, and does not work all the time, plus, requires your user to enter yet another value from an already difficult to read text.

Background

I began thinking about this problem and wanted to come up with a solution that...

  1. Is easy to implement
  2. Cost effective (needs no image generation on the fly)
  3. Does not require user to read and input another text box
  4. Works! (Of course, there is no such thing as 100% secure or unbreakable)

Suddenly, it dawned upon me when I started thinking like a hacker that if I wanted to automatically try to login using brute force, I would have to continuously generate different user ID and password combinations until I find the one that will get me through, but what is common in this? The keys! Let me explain... for example, if the login page contains two text boxes, one named "userid" and the other "password", all I have to do is submit values to these fields, something like http://address/loginpagename.aspx?userid=John&password=cool, and keep on changing the values "John" and "cool" until I find the right combination and I will get in. The keys that are common in this scenario are "userid" and "password". What if these keep changing every time you make a submit attempt? You would never know which key to provide the value to, hence cripple the key-value combination attack altogether!

Using the code

The basic idea in accomplishing this is to assign a different name to the userID text box and password text box every time the page is loaded, either by first loading or a postback is triggered. To make sure that the keys (the names assigned to the userID textbox and password textbox) are unpredictable, I elected to use GUID. There are four parts to this technique.

Part 1: UserIDKey and PwdKey private properties. (I use ViewState to store the assigned key instead of Session so that if the user spawns another instance of login page, each page would have its own keys.)

C#
private string UserIDKey
{
    get
    {
        if(ViewState["UserIDKey"] == null)
            ViewState["UserIDKey"] = Guid.NewGuid().ToString();
        return (string) ViewState["UserIDKey"];
    }
    set
    {
        ViewState["UserIDKey"] = value;
    }
}

private string PwdKey
{
    get
    {
        if(ViewState["PwdKey"] == null)
            ViewState["PwdKey"] = Guid.NewGuid().ToString();
        return (string) ViewState["PwdKey"];
    }
    set
    {
        ViewState["PwdKey"] = value;
    }
}

Part 2: Assign new names to the text boxes when the page is first loaded.

C#
private void Page_Load(object sender, System.EventArgs e)
{
    if(!IsPostBack)
    {
        MakeFieldNamesSecret();
    }
}

private void MakeFieldNamesSecret()
{
    txtPwd.ID = PwdKey;
    txtUserID.ID = UserIDKey;
}

Part 3: Validation. When the Submit button is clicked, retrieve the values of the two text boxes to validate.

C#
private void btnLogin_Click(object sender, System.EventArgs e)
{
    string userID = Request.Form[UserIDKey];
    string pwd    = Request.Form[PwdKey];

    //You must provide your own validation 

    if(userID == "John" && pwd == "cool")
        Server.Transfer("PostLoginPage.aspx");
    else
        lblErr.Text = "Invalid UserID or Password";

}

Part 4: Change the names of the text boxes on postback. This is what really prevents the key-value attack!

C#
private void LoginPage_PreRender(object sender, System.EventArgs e)
{
    if(IsPostBack)
    {
        UserIDKey = null;
        PwdKey    = null;
        MakeFieldNamesSecret();
    }
}

Points of Interest

What I found to be very interesting is the magic of thinking outside the box. What most people are doing trying to solve this problem is how to make the input values more difficult to automate, but few, perhaps thought about changing the variable that takes the value. With this very simple technique, I think I have solved a real problem. What do you think?

History

First revision: January 5, 2005.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralYou are completely wrong Pin
Elmue11-Nov-10 9:54
Elmue11-Nov-10 9:54 
GeneralMy vote of 1 Pin
small_programmer1-Nov-09 20:27
small_programmer1-Nov-09 20:27 
GeneralDoesn't work Pin
delucia25-Sep-06 10:19
delucia25-Sep-06 10:19 
GeneralDownload page once, use many times Pin
Vladimir_Davidov1-Apr-05 3:41
Vladimir_Davidov1-Apr-05 3:41 
GeneralGreat Script Pin
infecting20-Feb-05 19:08
sussinfecting20-Feb-05 19:08 
GeneralStored usernames Pin
Alen Oblak23-Jan-05 0:10
Alen Oblak23-Jan-05 0:10 
GeneralNothing is gained. Pin
MorgP16-Jan-05 10:18
MorgP16-Jan-05 10:18 
The viewstate is a simple base64-encoded string which is accessible from the client so its a simple call to System.Convert.FromBase64String to get the real string.

GeneralThis is going to be difficult indeed Pin
_BOFH_14-Jan-05 21:08
_BOFH_14-Jan-05 21:08 
GeneralWon't work Pin
Anonymous14-Jan-05 4:16
Anonymous14-Jan-05 4:16 
QuestionSwitch off/on for stress testing? Pin
Tom Celuszak13-Jan-05 6:05
Tom Celuszak13-Jan-05 6:05 
GeneralInteresting approach Pin
Phan Dung12-Jan-05 15:18
Phan Dung12-Jan-05 15:18 
GeneralEncrypt Pin
Yitzhak Gootvilig10-Jan-05 5:37
Yitzhak Gootvilig10-Jan-05 5:37 
GeneralBack button Pin
DejaVudew10-Jan-05 3:09
DejaVudew10-Jan-05 3:09 
Questionjust a get away? Pin
POMARC10-Jan-05 0:34
POMARC10-Jan-05 0:34 
GeneralThe Order is constant Pin
Uwe Keim9-Jan-05 20:17
sitebuilderUwe Keim9-Jan-05 20:17 
GeneralRe: The Order is constant Pin
John Narula10-Jan-05 8:35
John Narula10-Jan-05 8:35 
GeneralRe: The Order is constant Pin
Anonymous17-Jan-05 1:40
Anonymous17-Jan-05 1:40 
GeneralRe: The Order is constant Pin
alireza_progman23-Sep-08 11:37
alireza_progman23-Sep-08 11:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.