Click here to Skip to main content
Email Password   helpLost your password?

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.)

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.

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.

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!

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.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralMy vote of 1
small_programmer
21:27 1 Nov '09  
its not work
GeneralDoesn't work
delucia
11:19 25 Sep '06  
The scripter and get the page first, find the read the generated IDs and then do a post with them.
GeneralDownload page once, use many times
Vladimir_Davidov
4:41 1 Apr '05  
Well actually this aproach is not very good to my mind, coz a hacker or whoever it will be, can download the page once (with all the keys in the viewstate) and then, after developing quite a simple programm, submit the page with the non changeable viewstate to the server as many times as one wants (as for example Application Center Test does that). Correct me if I'm wrong.
GeneralGreat Script
infecting
20:08 20 Feb '05  
To: Oblacek
Why would you want the browser to repeatedly remember your username and password?
You will only login once or you love to test the login system so much or logout so frequently
that you want the browser to 'remember'. I guess 'that' really is a pain in the ass.
Well, I sort of know what you are asking, but Real-World usage is that legitimate user will probably
login once only. So to improve on security, let make it a pain in your ass, okay? Okay.

To: MorgP
Microsoft has no intention to hide the true value of ViewState, hacker can hack all they want. But true
hacker won't be terribly interested in ViewState either. So guess what!! You are right, err Nothing is Gained. Cool.

To: _BOFH_
Nobody says it is easy! But it is no dead end either. 3 times automatic logout is a requirement from the client,
not a requirement from the code. This script won't address this issue and yup, CAPTCHA!!?? I really never saw it in login page.

To: Anonymous
What the heck are you talking? Search for text called "User name", use "Username/Password" image?? And with
random names?? Well you mean unique GUID which JohnnyUSA has so randomly...err sorry uniquely generated?
Care to really re-phrase? The only real problem you are addressing is the JavaScript access to
form using indexing, but well that is being address by other user...boring

To: Tom Celuszak
Nothing to say

To: Phan Dung
The ViewState is really just that, a state for every public to view. It is free. Just, you know encoded
in a way to compact the state information and also to make it look cool and nice.
And I agreed with you that this script is quite cool...

To: Yitzhak Gootvilig
Yup and you should encrypt your HTML also. And dun forget the JavaScript.
Encrypting ViewState is plain silly. Common!! you have a GUID generated field called "f5e67052-e906-4bee-a16a-8dd92060bdc6"
and that is supposed to represent UserID. We encrypt this GUID and then stored it in ViewState, let's say the encrypted
ViewState is now "hehehaha456". Does this encrypted ViewState represent the field name?? DOES IT?? What the hell. It does and
you want to encrypt it for WHAT!!!
Well encryption do make ViewState more secure, but isn't tamper-proofing's what we want here?

To: DejaVudew
Damn! the Back Button is truly evil.
Well, this script is used to combat automated software from repeatedly injecting dictionary data into the
form page assuming the field name is the same throughout. With the Back Button, then i guess a simple
JavaScript can always be customized to automate that process. sh*t ME!! Please tell me I still can
use this script!!

To: POMARC
The attacker has to get the correct authenticated cookie, modify the ViewState correctly as to not
trigger tampering protection, and POST the data and hope that the Page_Load() is well sleeping and not doing its duty!!

To: Uwe Keim
So how do we sovle the damn DOM and JavaScript accessibility problem..those index...

To: Johnny USA
Way to go. A Great Idea. Cool...and please improve on it and post again..
Really how would you solve the DOM/JavaScript Index problem man....

To: Anonymous
THIS WILL WORK!!! You just need to.. you know "think out of your #$%ing Brain-Box".


GeneralStored usernames
Oblacek
1:10 23 Jan '05  
With this techique, the user's web brower can't store and remember the username and the password for the next use, so the user must type his username and password each time. This is a pain in the ass, if you ask me.
GeneralNothing is gained.
MorgP
11:18 16 Jan '05  
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
_BOFH_
22:08 14 Jan '05  
Very interesting idea, but I'm afraid you are in a dead end. Implementing client side security is not very safe. Would'nt it be much easier to implement a solution that works on the server side. If a user has provided a wrong password a configurable number of times in a configuramble ammount of time, lets say 5 times in 5 minutes then that account will be locked for another configurable ammount of time - say 2 hours.

In this approach, given the above parameters, a hacker cannot check for more than approximately 60 passwords in a day.

But is this really the intent for CAPTCHA? When I see CAPTCHA images it is more often when I wish to create an account or when trying to retrieve one of my forgotten passwords to my own email address. I have never seen CAPTCHA images when I try to log in.

My two cents...


GeneralWon't work
Anonymous
5:16 14 Jan '05  
the bad guy just has to parse the HTML DOM and search for the
text "User name" that you render in HTML to the user.
You need to make the Username/Password image elements which have
random names.
Also as another user stated, field order is predictable, so you are hosed as again if you parse the HTML DOM, you can predict stuff.

Smile
GeneralSwitch off/on for stress testing?
Tom Celuszak
7:05 13 Jan '05  
You'd want to consider that stress testing tools need to know the field names, so perhaps a switch to turn this feature off and on would be helpful.
GeneralInteresting approach
Phan Dung
16:18 12 Jan '05  

Creative solution! There is a suggestion: the ViewState for userID & password is stored in a hidden field in the webform. What happen if the hacker uses the content of these hidden fields & post them back each time he attempt to guest the userid and password?

:-DAnyway, this approach is very interesting.
GeneralEncrypt
Yitzhak Gootvilig
6:37 10 Jan '05  
You must encrypt the viewstate or save the keys in the server.
Hackers can get your key out of the viewstate string.

About ViewState encrytion and server side see :

Taking a Bite Out of ASP.NET ViewState[^] and Understanding ASP.NET View State[^]

And here in CodeProject: ViewState Provider - an implementation using Provider Model Design Pattern
[^]
GeneralBack button
DejaVudew
4:09 10 Jan '05  
Couldn't I just use the back button and use the same keys again?
Generaljust a get away?
POMARC
1:34 10 Jan '05  
Your approach is indeed interesting, but tell me if I got it wrong.
An attacker could get the page, parse it to understand the keys and then do the post.
If I am right your technique just added one get for each try. Right?
GeneralThe Order is constant
Uwe Keim
21:17 9 Jan '05  
Very interessting approach.

Yet, even if the names change, the order of the controls is constant. I.e. if I would need a script, I do not access by name, but by index.

To accomplish this, you could add additional, unused text boxes, maybe hidden by HTML or JavaScript or something like that (just an idea).

--
Affordable Windows-based CMS: www.zeta-producer.com

GeneralRe: The Order is constant
Johnny USA
9:35 10 Jan '05  
Thank you for your feedback. I have indeed thought of that and will be working on it, and a few other glitches, when I upgrade this into a web control.

JohnnyUSA
Smile
GeneralRe: The Order is constant
Anonymous
2:40 17 Jan '05  
The viewstate is hackable so this will never work.
GeneralRe: The Order is constant
alireza_progman
12:37 23 Sep '08  
That's a big mistake, if you don't read the form fields by name, the hacker can post it's value by any name!
Although this solution doesn't work as other user mentioned the hacker can read the fields many times and post them... but it was a nice try and these tries are good


Last Updated 9 Jan 2005 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010