New Security Notes from v2.3 ***************************** - Added an important bit of code to fsql_setup.pl - &create_session_id, to prevent the possibility of endless looping in case someone forgets to make a 'sessions' directory for session ids, or in case of any other type of file write problem during the creation of session ids (in the &create_session_id subroutine). In that subroutine, the script checks for $max_write_seconds (set by default to 1 minute) and if that limit is reached, the script aborts with an error message. Otherwise, it would go into an endless loop (it happened to me, and I had to kill the script process with a 'kill -9 PIDNO' command). I created the loop during the file creation section, in order to ensure that the session id file is unique, using sysopen(FH, $session_file, O_WRONLY | O_EXCL | O_CREAT, 0600). If the script tries to create a file that already exists, it keeps looping, with a new value for the time() section of the file name, until it finds a unique file name. This would only come into play if two web users were trying to write a session id file with exactly the same parameters at exactly the same second, and exactly the same 'random' number in the file name. Unlikely, but worth testing against. So, now, the script aborts if that process takes longer than $max_write_seconds. - changed some code in fsql_setup.pl - &connect_to_db so that session ids are created for public users, mainly so that my new application 'FutureSQL:Shop' will work properly. New Security Notes from v2.2 ***************************** The main issues that I wanted to take care of with session ids were: 1) stop passing the password as plaintext in a hidden field, and 2) store the password outside of the web tree, encrypted, and as securely as possible I'm not a security consultant or an encryption specialist, so someone may look at my method and code, and suggest improvements. In fact, I'd really like that -- especially if it results in an overview that shows that my method is reasonably secure :-) or results in a better method that I can incorporate into FutureSQL. Here's the breakdown: - To login using SSL, you of course need to pull up your login form with https. This assumes you've got an SSL cert. - I've created a new subroutine that the SSL login uses, called secure_login. After logging in with https, the user will see a continue button, which will then go to the regular 'Home' Menu, 'breaking out' of the https connection, but correctly passing the session id, rather than the password. SSL slows things down considerably, because it encrypts the entire contents of each page, so it's better to break out of the SSL connection after logging in. Thus, I use the above method, even though it adds a step. - If you don't have an SSL connection, or don't wish to use it, simply login as before, pointing the login form to the normal admin_menu subroutine. The session id will still be created. - The Session ID method is as follows: . I only deal with the password. The user name is still passed as plain text, because I don't think it's a security problem, and the script often makes use of it. . After logging in the first time, the &connect_to_db routine grabs the password and passes it off to a new routine: 'create_session_id'. . If the session id exists, connect_to_db checks the new routine 'decrypt_session_id' and gets the password from there. . I've made a new directory called 'futuresql/sessions', outside the web tree, and set to 777 so that Apache can write to it. This dir is for the session id files. Check out the session id vars in fsql_site_db.pl . create_session_id does these things: -- creates a unique file name, using sysopen -- encrypts the password, using a modified, handrolled version of one-time pad xor encryption -- creates the keypad to the password -- creates a session id which consists of part of the file name, followed by the keypad My theory is that the keypad, which is being passed as a hidden value in the browser, is not being stored on disk. The file on disk contains the encrypted password, but no reference to which user it belongs to (the session id and thus file reference are also in the session id, but these are only being passed temporarily). In my less than lengthy readings about one-time pad encryption, I noted that the keys need to be truly random and should only be used once. I would imagine that any serious hacker could, if using sniffing technology, read from the web browser data stream, and then read the session id files. However, the plus side (I think) is that the session id files are set to 600 and owned by Apache. They're also deleted every so many seconds (set in fsql_site_db.pl). Also, the other side of the encryption, the padkey, is only briefly passed across the net, so I think that breaking things would require: a) someone gains root access to the machine, so they can read the session id files b) someone sniffs the data from browser logins, simultaneously. My view is that if someone gains root access, you're a dead duck anyway. I would, however, very much appreciate feedback from programmers who are more versed in cryptology than myself, so that this method could be made even better (assuming it's good enough, now :-) ---------