WebApp Sec mailing list archives

Re: ASP authentication


From: "saphyr" <saphyr () infomaniak ch>
Date: Sat, 28 Aug 2004 05:58:55 +0200


Hi list !

1. Use SSL to encrypt the traffic to begin with.
Although this is completely right and the best solution, this might need some
explanation. It is critical to ensure the authentication step is providing maximum
security for your visitor and yourself.

Encrypting the 'login' process will allow transmission of credentials (username
+password usually) through a secure chanel, thus, reducing sniffing and other
man in the middle attacks (although those can be accomplished through an
ssl enabled sniffer)...

After the authentication step is terminated, your preocupations change: you
only need to know that 1) that user was really the one he pretented to be
2) who precisely is this user. Those informations do not need any encryption
and can be transmitted clearly through a regular http flow.

So, just remember: encryption is not compulsory, better but not compulsory,
during the entire session. However, I strongly advise you to encrypt at least
the login process .


2. Your login page sets 3 cookies (or hidden form fields)
    - One is a session id
    - One is the time stamp (or epoch seconds) of this page view
    - One is a hash (i.e. MD5) of the session ID, time stamp and their
password using some random salt.

    - On the back end, keep track of who belongs to each session id.


3. On each successive page, you get these 3 values back and reset them (so
the time stamp and hash keep being updated).

4. To determine if the person is authenticated, use the session id to look
up their password in your back end.  Use that and the passed time stamp to
make a hash comparable to the one passed back to you.

    - If the hashes match, then the credentials have not been tampered with
    - If too much time has elapsed, you may want to automatically log
      them off to mitigate the effect of replay attacks.

Even this mechanism has problems with replay attacks
  - The credentials can be sniffed if you do not use SSL or if there is an
    SSL proxy in the middle you are ignoring.
  - The credentials can be obtained by anyone with access to the user's
computer.


I personally see issues in your proposition. Not that they are 'unsafe' but
their objective do not seem to be clearly specified.

When a session is established , the developper must protect the application
through three objectives:

    - the session is not being replayed
    - the session is not being played simultaneously
    - the userid was not corrupted


)the session is not being replayed
In this process are involved the timestamp + hash values. The timestamp provides
the information "when did this event occur" and the hach will provide the
information "the provided event time's integrity is guaranteed".

To achieve this, there must be a cookie containing:

    - the timestamp
    - a hash value including the timestamp (shared secret) and a salt (private
    secret only known by the server).

If the timestamp is modified, the hash will be corrupted. If the attacker tries
to recompute the hach, he will need the 'salt' and can only get it by bruteforcing.

Solution: use a complex enough salt which will take a long long long time to
be bruteforced.

This will enforce your objective number 1: "the session is not being replayed"


)the session is not being played simultaneously
This is harded to achieve. The goal here is to be able to recognize an attacker
from the legit user. Only one solution here: finding user values which will persist
through the entire session. Those values can be:

    - the ip adress (attention to multi-proxy ISP users like AOL)
    - the user-agent string
    - the accept-language string
    - screen resolution ? whatever....

There's a clear "application architect" decision to be made here: how much
values will we take in consideration to 'accept' the fact that those values
all combined together uniquely differentiate a user from another.

Another way to say this would be "what is the probability and acceptable
risk to have 2 people having the same values for all the parameters we chose
to identify them ?".

A solution could be to simply store any selected user information and link
them with the session id in a database. For example:

    - a company chose a 3 values integrity check: ip adress (no customers
    should access the extranet through AOL isp so they don't care about
    multi-proxies ISPs), user-agent and accept-languages;
    - when the user authenticates himself, those 3 values are also stored in
    a database or any other persistence layer;
    - for each request received from this user, the 3 values are checked to
    ensure the user is really the one who logged in a few minutes or hours
    ago.

This would achieve objective number 2: the session is not being played
simultaneously by someone else


)the userid was not corrupted

This one is easy, you can implement it in addition to the timestamp hash:

    - secret salt + timestamp + user id + 3 values hash

That should be very hard to falsify in a short time and would complete
objective number 3: being sure that the userid was not corrupted.


I hope you now have enough informations to begin a basic 'secure'
authentication mechanism in your web application. I just wrote 'basic'
because there are still many features which might be requested to
ensure security like:

    - maximum logon failure threshold
    - concurrent logons : disconnect immediatly
    - account automatic locking mechanism
    - real-time alerts to the administrators in case of a brute force
    or likely attack
    - defining a global maximum allowed timestamp delay
    - .. many more...

. antoine
-- 
Blog Dev et Sécu Web (Swiss blog about Web Security and Development)
http://www.nxtg.net/is/


Current thread: