A web user activity is organized upon multiple requests into a logical entity that is enabled by HTTP sessions.
A HTTP session can not be secured without prior semantic code analysis on each elementary transaction. HTTP protocol is "stateless". When the user query the server at one point, it is not possible to know if the same user is querying the site or not at web server level, because the HTTP protocol was not designed to keep a state or a trace of a any transaction.
Each query is a single entity, and requests are all independent of one another. For a web application, a context is created to keep track of the user as and whatever he is on when he access the web application. This session context has to be secure.
Session identifier
A session is initiated on user access, and generally follows a user identification process. The user is then given a "token" that uniquely identifies him within the application, which allows to keep a single statement about it.
It's easy to see that any hacker will try to appropriate it to pretend to be someone or to win the rights of someone else. Once the session starts, strong user identification is needed.
Let's start with securing the identification process. SSL is a good way to encrypt data exchanged between the client and server, to avoid their possible interception. Complexity of the used password must be sufficiently high to prevent dictionary attacks.
It is also expected to implement a counter, deadlines and thresholds to counter strike DOS attacks. For example the user will have to wait 5 minutes after 3 identification tests inconclusive or other equivalent stuff...
Similarly, it must avoid the "default identifiers" (such as root / password) which can be given to a new person coming on a site, as it must be mandatory to re-identify the user when handling high-risk transactions in its own session (validate a credit card, change password, etc ...).
Once identified, the token assigned to the user must be unique, encrypted, and not easily guessable. A timestamp associated with multiple encryption process and gambling can be used. It is better to useknown and recognized algorithms, rather than trying to re-invent the wheel which may be easily pierced.
Passing the session identifier from a request to another, through cookie or sent to the client, have to be returned to the server for each request. Doing this is possible through the URL, but in which case can represents a major security hole, because the session ID is then glued to the end of each HTTP request, and is therefore in most cases visible in HTTP requests. The id can also be present in the Referer, and therefore when the user accesses an external site, is send with to the previous site session id.
About the cookies
If the connection is not secure (SSL), then the cookie travelsover the network unencrypted to each HTTP request from client to server. This is very bad, considering the facility to hack requests as for example the many "open" wifi hotspots that we find today. Tcpdump or Wireshark usage with a gain antenna on the street, can steel easily valid Session cookies that can be repeated to impersonate someone, without relying on passwords that circulate in the air without encryption...
Session termination
The termination of the session is an extremely important point. A session left open too long and abandoned is a security weakness. Every effort should be made to shorten the most possible the lifetime of a session. Sessions must end in the following cases:
- An inactive session: a session that has not been reactivated since a reasonable period, typically 5 to 15 minutes;
- Two Long session: a session remains active, but reaches the maximum limit of validity regarding user activity, needing the user to re-identify;
- Dots: a user should be able at any time to "sign off" and close / destroy explicitly session and the session cookie;
- Security Errors: any security alert raised in the application should lead to immediate closure of all sessions.
Creating application reports or security audit trail is a must. It must follow a predetermined logic when designing the application. For example, when creating a user, fulffillment process make a succession of several steps in a pre-determined order. No one should be able to jump from a step to another without validation.