The task of the session manager is to manage the link from the current request to the current dialog (i.e. the current session, which is always a dialog for WDialog). By default, the instant session manager is used that does not store the session externally, but simply includes it literally into the current request. The hidden form field uiobject_session contains the data describing the current dialog as BASE64-encoded string. This has one major advantage: You do need to set up an external data store for the sessions, instant sessions work "out of the box". In the rest of this chapter, I will try to convince you that it is better not to trust this session manager, and that the additional work necessary to instantiate the database session manager, memory session manager, or daemon session manager is worth-while.
The Database Session Manager
The database session manager puts the session data into a data store (that can be freely chosen), and the web request only contains a reference to the stored record. Obviously, the web requests and responses become smaller (sometimes much smaller), and your web application becomes faster (sometimes much faster), as fewer bytes need to be transferred over the network. Another advantage is not that obvious, and because of this I am talking about it: your web application becomes much more secure. I hope you understand that this is the real point behind the more complex database managers; the Internet is full of attackers today, and is highly likely that a public application is "tested" by hackers.
Of course, using a database session manager does not ensure that your application cannot be hacked. First, there are other potential weaknesses in the application, and second, sessions can still be "hijacked", although this becomes more complicated.
Using the database session manager
First, you need to instantiate the class Wd_dialog.database_session_manager by passing functions that allocate rows in your database, insert rows, update rows, and lookup rows. These functions must perform the real database accesses, such that the class database_session_manager remains generic with respect to the type of the database system. The functions are exactly described in the module interface of Wd_dialog.
The second step is to pass the new session manager to the WDialog engine. In the case you use Wd_run_cgi, Wd_run_fcgi, or Wd_run_jserv, the entry points of the engine run and create_request_handler accept the session manager as optional argument. In the case you call Wd_cycle.process_request directly, this function accepts the session manager, too.
A complete example can be found in the directory examples/list-dbm-ml of the source distribution. This example stores the sessions in an NDBM database.
The database session manager never deletes sessions. It simply does not know when a session has been dropped by the user, and can now be removed from the database. A strategy to get rid of dropped sessions is to delete all sessions that have not been used for a long time.
The in Memory Session Manager
The memory session manager is an easy to set up, secure alternative to the database session manager, which can only be used by applications which stay memory resident between requests, and which exist within a single process image. In practical terms, it can be used by sequential or threaded FastCGI and Jserv applications.
Its implementation is very simple. It generates an opaque random session identifier, which is sent out to the client as the session id, and is also used as the index of the real session in a hash table. When the client send the id back, the real session is looked up in the hashtable. Because of this simplicity, it does not require any special functions to be written, and only requires the user to configure two paramaters, for how long sessions are valid, and how often to look for and purge from memory invalid sessions.
Besides ease of use, it has one additional advantage over the database session manager. It generates a new session for each request, and it DOES NOT throw away the old application state. This allows it to interoperate with the browser back button where that is possible, just as the instant session manager does.
Using the in Memory Session Manager
The function new
The Daemon Session Manager
The daemon session manager is very much like the memory session manager, however it removes several annoying restrictions.
The daemon session manager is implemented in two parts. There is a small rpc server, which stores session data in its memory image, and there is a wdialog session manager class which talks to it. The session manager class works much like the in memory session manager, except that it takes 3 additional arguments, hostname, user, and password, which are used to contact the session daemon.
Using the Daemon Session Manager
WDialog comes with a both the daemon session manager class, and an implementation of the session daemon, which is called wdstated. The first step in using the session daemon is to configure a user name and password for each application which uses the daemon. This is done in the wdstated.conf file, which is included with the distribution. These credentials ensure that session data is only available to authorized applications. Next you should start wdstated as an unprivileged user. You can pass the location of the config file as an argument to wdstated if it fails to find it. In your application, create an instance of Wd_daemon_session.daemon_session_manager, and pass it to the WDialog engine. Your application should now be storing sessions in the state daemon.
The security problems of the instant session manager
As already pointed out, this manager includes the session data literally into web requests. The data contain essentially marshalled O'Caml values describing the current dialog, and that means all dialog variables except the temporary ones. Because of this we assume that any low-skilled hacker can
Since WDialog-2.1, the marshalling format has been changed to make it secure against attacks based on malformed strings.
The security benefits of the database session manager, the in memory session manager, and the daemon session manager
These managers do not put the session data into the web requests, but only a reference to them, while the sessions are stored in some sort of database. The references are triples (id,key,checksum) where the id is a predictable integer identifying the session, and the key is a non-predictable hash value for the same purpose. Finally, the checksum is a hash value of the session data.
Obviously, it is no longer possible to read the dialog variables by just looking at the value of the session reference. However, a hacker can still modify a dialog variable, because all variables are writeable by default. This is allowed because an interactor might be bound to a variable, and the update of the variable implies the right to modify the variable.
The ui:variable element can declare a variable as protected (protected="yes"). In this case, the variable cannot be modified by web requests at all, even not by binding an interactor to the variable. (Of course, protected variables are only sensible if the database session manager is used, because the instant session manager allows a hacker to replace the whole session by a different one.)
The question remains whether it is possible to attack the application in a completely different way. One idea is to "hijack" the session of another user by stealing his session reference. In theory, this is possible, but it is both difficult to get such a reference and to abuse it. The reference is only included as hidden form field, and it is only transferred as part of a POST request. This means that the reference is normally not written to files (e.g. cookie file, log files, cache files), but exists only in volatile memory. So access to the disks of a computer does not help. However, browsers do (or might) contain so-called cross-site scripting bugs. These bugs sometimes allow the attackers to read form fields such as the reference without having the permission to do so by executing scripts in the browser. Unfortunately, nothing can be really done against these bugs on the server side, one can only try to minimize the damages. WDialog makes it hard to abuse a stolen session reference. First, the session contains the IP address of the browser. Often, this is already a very high hurdle to jump over for an attack. Of course, it may be possible that the attacker has access to the same web proxy as the victim, and so has the same IP address. Second, the checksum of the session changes frequently, but the attacker needs the checksum to take the session over.
Summarized, hijacking a session is possible, but difficult. Normally, the attacker needs at least two other security exploits, one to steal the session reference, one to have access to the IP address the session is bound to.
For a highly secure application, I would additional recommend to secure the network channels, too, i.e. to use SSL/TLS. This makes it much harder to steal the session reference as it is only transmitted in encrypted form.
Another attack one can think of is to simply guess the session reference. This is practically impossible as the key part of the reference is practically unpredictable, and the search space for a brute-force attack is too large (128 bits). Furthermore, you need the checksum, too, which is as difficult to guess as the key.
Of course, it cannot really be excluded that a working brute-force method is found. For a highly secure application, it is recommended to install attack detectors, e.g. by counting the trials for every real key stored in the database, and to drop the session if too much trials happen in short time. This should effectively protect against guessing the checksum.