Browse DevX
Sign up for e-mail newsletters from DevX


How to Spoof-proof Your Logins : Page 2

Who's accessing your Web applications? If you think only humans are registering and logging in, you may be surprised. Learn how to teach your application to differentiate between humans and machines and reject automated registration and login requests.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

How Captchas Work
The login or the user-creation process must include logic whereby the application compares the letters drawn onto an image with some text by the user after reading the characters in the image. If the drawn characters and the user-entered characters match, you can assume the user is actually a person rather than an automated script running from a machine. Verifying the match on the server doesn't solve the problem of spoofing attacks that simply throw large numbers of requests at the server. To achieve a robust solution, the application must meet these constraints:

  • To minimize system resource usage, the application should not use a data store of any sort—it should not write files, store information to databases, etc.
  • The application may not use sessions to manage state. Sessions are not a scalable solution both because they're stored on the server (violating the preceding constraint) and because they may not work well in typical Web-farm load-balanced environments
  • The application must protect itself from multiple-request spoofing attacks by validating the match between the captcha characters and the user's response on the client rather than on the server.
To satisfy the constraints, it becomes obvious that you need to store the generated random letters on the client. This stored data must be encrypted so spoofers can't just read it and submit it via an automated script. The sample application solves that by hashing the letters using the SHA1 hashing technique. A hash is a value or key generated from the content of a string. Once hashed, applications can use the (usually) shorter hash value in place of the original string. Hashing is a lot faster than encryption as it is one-way; you can't recover the original string from the hashed value. There are a number of hashing algorithms available. The SHA1 hash algorithm produces hash values such that (a) hashing a given string always produces the same hash value, and (b) it's extremely unlikely for any other string to produce the same hash value. Therefore, if you have the hash values for two strings, you can compare the hash values rather than the strings themselves to determine if the original strings are identical. You can read more about the SHA1 hash algorithm here.

In this case, you can hash the characters embedded in the captcha on the server, and then send that to the client saved in the form of a HTTP cookie. After the client has sent back the user-entered text read from the image to the server, the server hashes the user-entered data and compares that with the hash value stored in the HTTP cookie. If the two hash values match, the user has successfully entered the same characters embedded in the captcha. Next, you need to decide exactly how and where to store the hash value when you create the page.

Although it's possible to create a Web Form that returns both generated images and content, you can't return them both at the same time. To return a JPEG-formatted image, for example, the page must set the Response.ContentType to "image/jpeg," whereas to return HTML content, the Response.ContentType should be "text/html". Therefore the simplest way to solve the problem is to use two pages: One to return the text content, and another to create and return the captcha image. When the server creates the text content, it will include a <img src="randomimage.aspx"> tag. The browser will parse the img tag and request the image from the server as a separate request. That request will generate the random string and the image, but it can't write text content back to the browser, because, for the browser to render a response as an image, the Response.ContentType must be "image/jpeg." Thus you must come up with a scheme to pass the hashed value back to the client when the browser requests the image so that the client can validate the user entry against the hash value.

Because the constraints remove sessions, files, or database fields as a storage mechanism, you're left with cookies. Before generating the image out of random letters, generate the hash and write a cookie containing the hash value into the HTTP-Headers. That cookie gets sent to the client as part of the response header. As there's no text contained in the HTTP-Content, the Response.ContentType of "image/jpeg" will render without a hitch. So there you have a solution that meets all the constraints. Time to dig into the code:

Thanks for your registration, follow us on our social networks to keep up-to-date