![]() [UP] Reference
|
Session Managers 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 is worth-while. 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 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 longer time. 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
A skilled hacker might even be able to do more serious attacks, as the marshalled value is only a dense format of a memory image, and that means he can break any security walls you have carefully built into the application. The security benefits of the database session manager This manager does not put the session data into the web requests, but only a reference to them, while the sessions are stored in a 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.) Furthermore, invalid marshalled values can no longer be injected by attackers, so this security hole is closed, too. 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 it 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. |