Within a couple of weeks, though, I noticed a rather severe hole. Some person had been creating random comments with random user names. E.g. Rohit Khandekar’s page had a comment made by Rohit Khandekar in the “others” section, which should not have been possible. Obviously someone was subverting the security. This person had not done anything malicious, but had also not told me anything voluntarily.
I figured out what the problem was. I was handling the form inputs by means of a “get” method. In other words, the structure of my url would be something like http://poorvi.cse.iitd.ernet.in/~csu96163/add_comment.cgi?comment_by=csu96140&comment_on=csu96136. The URL would show up in the address bar once you had logged in. However I had completely missed the fact that a user could directly input the URL in the address bar and make the comment entry. My check was only to see if the comment_by and comment_on had been provided.
I guess you have seen the problem by now … I was not using sessions!!! The realization hit me like a freight train. I did not have the know-how to implement sessions and neither did anyone else. Luckily I figured out who had discovered the flaw – it was Kunal Talwar a.k.a. KT. Cursing Sud under my breath and with the tacit understanding that KT wouldn’t tell others how to exploit the flaw, I went into firefighting mode. With Mayank’s help I switched from “get” to “post”. At least that way you couldn’t subvert the login directly from the address bar.
After a bit of research KT pointed out the next part of the flaw. Since guys had access to my source code, they knew what my header was expecting. So technically a user could write an HTTP client and post the information to the add_comment.cgi page, again subverting the login process. Of course, it would involve a lot more time and some basic hacking skill to do this, but it was still not acceptable to me.
Finally here is what I did. I retained the “post” mechanism for updates, then I made sure that the raw password was passed from page to page as a hidden field. On each page I would verify the credentials and then let the user proceed – the way sessions work in real life. There really was no other way to do it without a major overhaul. An encrypted password could be obtained from the /etc/passwords file, hence the raw password had to be used. Note that all my attempts were done in a single day, to ensure smooth running.
Many weeks later KT pointed out yet another flaw in this approach, but this was of a much less risky nature. Since the raw passwords were being passed in the requests and responses, they were getting stored in Netscape’s cache for each user. However I wasn’t very concerned because the Netscape cache folder for a user was not accessible by other users. The only way someone could get hold of your browsing history was if you had left your terminal unattended. And after the misdeeds of the semester past, few dared to leave a terminal unlocked.
Apart from this incident there was no other flaw reported. In hindsight, the single biggest obstacle to security was the fact that I had everything in my home directory. No matter what I did, since the client side scripts and server side scripts were both available to everyone, all these approaches were rendered void. Even if I had used a database I would have the same problem: the login and password for the database would have to reside in one of the CGI files, which would be accessible to everyone. So someone could potentially go ahead and update the database directly, if he / she wanted. Though this was merely a class yearbook and the worst that could happen was a slanderous comment here or there, this opened my eyes to being more secure in terms of what I wrote on the web. There was no real danger in this case, since most people were too busy handling assignments to bother breaking security on the class yearbook. Of course, the uberintelligent folks like KT had ample time on their hands, but then I am yet to meet someone more intelligent than him.