Thursday, March 25, 2004

Redesign of a Secure Website

I'm in the process of redeveloping my company's secure website. This website allows our clients to access confidential data in a secure way. I thought to share it with the world. Maybe it's all old news for you, but hopefully I can contribute just that little bit extra to your understanding of building secure websites. [DISCLAIMER: I'm not working for one of the big companies, so maybe some things here are not exactly according to widely used standards. But hey, as we're just a very> small IT department, everything here has to be done in a DIY-kind-of-way. Not some tester around here, who'll come up with all kind of smart things I didn't consider. No, my complete knowledge stems from my own desire to gain knowledge. And when things seem to be seriously wrong here, please don’t hesitate to use the comments. I'll be glad to discuss matters a bit further. Well, let's take of then:

Convenient Access
These data consists of multiple types of information: automatically generated but static HTML pages, Word / PDF documents, and dynamic pages pulling data right from our Management Information System in real-time. Of course, access must be secure on one side and convenient for both administrators and clients at the same time. We had some thought as to the best way to do all this, so even direct links to Word documents would yield an Unauthorized error, unless the right credentials are given. Right now we use:
  • HTTPS-only access on all pages, to ensure data is encrypted in transit. 128-bit encryption is required, as most browsers support this nowadays; and we didn't have any complaints about it so far.

  • As to the client, the usual username / password method of authentication is used. Every clients has her own Windows Local User account

  • All pages checks for an authenticated user, and whether this person is the right user? Would you forget the last, it would be possible for one authenticated client to impersonate another one. If the user is not authenticated, or she is authenticated but not working under the expected credentials, she is logged off and redirected to the company homepage

As you see only a server certificate is used, as we're mostly concerned that data will not be sniffed along the way. It's too restraining for the clients to also have to cough up a client certificate. The use of client certificates doesn't seem to be in wide use nowadays, so I don't think this is a major flaw in our system. You could argue about that, but we're not talking military grade security here (note the irony in the term military :)

Getting Rid of Windows Accounts
One of the disadvantages of the current system is; having to add a new Windows user account for every new client takes some administrative hurdles. Lacking remote access to the webserver, we need physical access to it for every new client that has to be added, or passwords which have to be changes on request. We'd like to be able to use the standard Forms Based Authentication (FBA), with the usernames stored in a database table, and passwords in hashed form. We plan to include the option that clients can change their passwords as they wish; and they're definitely forced to change them at their first login. I guess hashed passwords require a client must be able to reset their own passwords anyway, as administrators will not have the possibility anymore to change them. Using a table for storing user login information will make administration as easy as adding a record to a table. Additional functionality should be the system generates a random password, which is then communicated to a pre-set email address (of the client, presumably).This will probably be done by means of an ordinary email (meaning a password is sent out unencrypted, but I see this system used even in major forum based sites; and chances that an informed [1] attacker can take hold of this specific email are quite small, I'd say. In that case they probably 0wn the network already to some amount, so they can take hold of much more information by then.

Reducing Data Redundancy
Other things I want to accomplish is reducing data redundancy while we're at it. Right now, we upload copies of all kinds of documents which are used on the local intranet, to the webserver. Every now and then these documents are updated. You'll have to take very good care that webserver documents stay in sync. One way would be some nightly super batch script which copies all stuff to the webserver, but it's kind of rough. I want to put everything into a database, and have both internal and external customers use that one. For internal users, there's no access restrictions necessary. However, external clients must be restricted to seeing only information for which they are cleared. This can be complete sets of documents, or only specific ones, anything. A smart way of handling this requirement is on its way.

SQL Injection ahead!
Abandoning Windows Authentication, and using FBA instead, means SQL Injection comes into the picture even more than now. You know about SQL Injection
don't you? By not checking user input in some way, you risk people can access confidential parts of your site with no password at all. Or worse; they're able to enumerate all kind of information about your database, database server etcetera. They could even bring your server down, drop your database or execute commands on your database server by using xp_cmdshell. And, actually Windows Authentication is kind of easy, come to think of it. Authentication is performed by the Operating System, the user is given an server variable USER, which is trivial to check for. With table based login details you'll have to do everything yourself, setting and bookkeeping Session / Cookie variables and what have you. However, a big advantage of the future system will be the possibility to really log a user off from the system. Windows Authentication requires the user to close the browser after use, even Outlook Web Access does this (have you ever tried to log off, and go back to your inbox: you'll still be able to take care of your email)

Another thing we're not clear on: should we use the SessionID in the QueryString. A method you'll find on lots of sites, e.g. web based email clients, shopping sites and the like. You can use it to double check whether the user is allowed access to the page: don't have the expected SessionID: you're instantly logged off, taken to or whatever. Actually, I've learned the mantra "QueryStrings are bad", but they can be used to your advantage when handled the right way. However, I'm considering no using them, as Cookies / Session variables can be handled without resorting to QueryString, of course.

[1] With informed I mean the attacker has knowledge about the system and wants to gain access. In the process he tries to sniff the email containing a password. As these emails are only sent once to new clients, and afterwards only on clients' request, this will happen in such low frequency that chances of intercepting for an attacker are quite low. He might have to monitor all network traffic maybe for several days, and still not know when this will happen. Maybe it's more feasible than I think, but still I don't think it's the smartest way of finding out a password. Too much trouble, and chances are the client will soon find out the password doesn't work, contact us, and we'll just reset it. There's no elevation of privileges possible with just this attack; the worst thing that can happen is that the attacker is able to view some confidential data for a certain amount of time.