[Subject Prev][Subject Next][Thread Prev][Thread Next][Subject Index][Thread Index]
Implementing security in CGI
Sometime back we had asked questions on how to implement a secure system
under CGI, which did not draw response from this group.
Meanwhile there was a hot discussion on this issue in the mod_perl news
One person has come up with a brilliant note on the same, which I thot will
be most useful for any CGI programmer.
Please read on if you are interested.
From: DeWitt Clinton <dclinton@xxxxxxxxxx>
To: Differentiated Software Solutions Pvt. Ltd. <diffs@xxxxxxxx>
Cc: modperl@xxxxxxxxxx <modperl@xxxxxxxxxx>
Date: 21 April 2000 11:20
Subject: Re: Implementing security in CGI
>Interesting thread and interesting question.
>It makes sense to start with the requirements for what it means to
>implement those secure features. My requirements have an obvious
>e-commerce bias, and should probably be heavily reviewed by anyone
>thinking of using this design for online banking or government work.
>First, I'd like to introduce the notion of a secure session. Secure
>sessions have some subtle differences from the traditional notion of
>the session, and I'll point those out when they appear.
>The secure session has the following properties:
>*) The user is able to initiate a secure session by providing proper
>credentials (i.e., a username and password pair) via a login process.
>*) The user is able to terminate the secure session via a logout
>*) Secure sessions must be able to time out automatically.
>*) Secure sessions must *never* transmit sensitive data (such as the
>password) over insecure channels.
>*) The secure session, while it requires the use of a secure protocol
>however, can be employed to extend the functionality of the system.
>Additionally, I feel that one of the essential requirements to any
>enterprise quality, highly scalable, and fault-tolerant system is the
>ability to store session state on a tier other than the front-end.
>This usually means storing state in a shared database, but there are
>A very effective method of meeting the requirements above is to use a
>two token architecture. The first token is a user identifier, which
>can be passed over insecure channels. This user identification token
>can be used to restore state that isn't particularly sensitive, such
>as a shopping cart or user preferences. The second token is a secure
>identifier, which is never passed over insecure channels. The secure
>identifier is required to access sensitive data, such as credit card
>data. (It is possible to create an architecture that uses *only* the
>secure token, but there are significant benefits in terms of
>flexibility afforded by using two tokens, so I won't go into the one
>token model here.)
>The fundamental goal of the secure token is to a) keep it safe from
>prying eyes, and b) use it is a requirement for accessing secure data.
>Tokens can be passed in one of two ways. First, the token can be
>passed as part of the URL. Second, the token can be passed in a
>cookie. I've found it very useful to create an initialization
>procedure inside applications that check both places for these tokens,
>and abstract the particular mechanism used to pass them. Note,
>however, that is important to remember how the token was passed -- if
>it came from a cookie, it is cosmetic to not pass it around in the
>URL. I also recommend creating a library used in your templates that
>has a function to build URLs that automatically append the tokens if
>necessary. Since it is critical that secure tokens are never passed
>in the clear, it really helps to have that function, because it can
>prevent the secure token from being sent via an insecure page in a URL
>(i.e., only setting secure tokens in URLs that contain "https").
>The user identification token is typically used to restore state from
>the database. It is created whenever a page is viewed and the client
>has either not provided one (via the URL or a cookie), or the token
>they provide doesn't exist in the database. This token should then be
>set in both the URL and in a cookie. On the subsequent page request,
>if the user identification token is found in a cookie, it is probably
>safe to stop putting it in the URL. However, if the token is found
>server should not try writing the cookie again.
>The advantage of the cookie is such that the user can insecurely
>identify themselves across browser sessions. This is perfectly
>acceptable when used to restore some insensitive state data (such as a
>name or shopping cart). However, the system still functions without
>the cookie. The user can now login to associate their client with
>particular stored user information.
>The login process is as follows:
>1) The client connects to a secure page that presents a form
>requesting a username and password. (There has been much discussion
>about whether a HTTP form that POSTS to a secure page will encrypt the
>posted data. There is too much ambiguity here -- I recommend using
>HTTPS on the login form as well.) The ACTION of the form must also
>be a secure page.
>2) On receiving the username and password, the server compares an
>encrypted version of the password with the stored encrypted password
>associated with that customer. If the passwords do not match, the
>user is returned to the login page. (For highly secure sites, storing
>a count of the number of failed logins may be desirable.)
>3) The server compares the client supplied user identification token
>with the one associated with that username in the database. If they
>are different, the server should use the procedure outline above to set
>the new user identification token in the URL and cookie.
>4) The server now generates a unique secure token. Using the
>techniques I mentioned, this should be appended to all links from the
>page that use HTTPS, as well as set in the cookie. *Important* --
>when setting this in the cookie, use the "secure" flag in the cookie
>string. This will tell the browser never to send the cookie over
>insecure channels. (I don't know whether to trust the browser here,
>5) The secure token is associated on the server side (preferably on
>another tier, such as a database) with the user identification token.
>Additionally, to support secure session timeouts, the current time
>must be recorded.
>The customer is now technically logged in, and will be able to access
>sensitive pages, providing they provide the proper tokens, and certain
>other requirements are met. When a sensitive page is accessed, the
>following requirements must be met:
>1) The page must be viewed over a secure protocol (i.e., HTTPS).
>2) The client must present a valid user identification token.
>3) The client must present a valid secure token that matches secure
>token that is stored associated with that user identification token.
>4) To implement secure session timeouts, the last access time of the
>stored secure token is compared with the current time. The delta must
>be less than some predetermined value (such as 15 minutes or one
>5) The current time must be stored as the last access time for the
>stored secure token.
>6) If the secure token was not found in a cookie, then all the exit
>links for that sensitive page should contain the secure token, if and
>only if they point at another secured page (similar to the login
>If any of these requirements are not met, the user can *not* access
>the sensitive page. The server can then display the login page
>instead (or redirect to it over a secure protocol, in the case that
>requirement #1 was not met).
>Obviously, it helps to encapsulate all of those steps inside a simple
>routine that each page or module can call at the beginning of the
>process. Even better, enforce some external control that won't even
>let the particular page's code run unless those requirements are met.
>To explicitly logout, the user should simple be presented with a URL
>that requests that the secure session end. When this happens:
>1) The server then erases the stored secure token identified with the
>user identification token. (Now, step #3 of the sensitive page view
>requirements will fail on future requests.)
>2) As a courtesy, the server should set the secure token in a cookie
>to null. (This isn't required for security, but it makes the user
>feel they have logged out. Do this even if you think the client isn't
>accepting cookies -- some users are manually accepting/declining
>cookies to test your system.)
>3) Optionally, generate a new user identification token and set this
>in the cookie and URL. (I prefer this approach, because it is very
>useful for someone accessing your site from a shared computer.)
>There are occasions in which it makes sense to clear the secure cookie
>without being asked to. For example, after a customer on an
>e-commerce site makes a purchase, you may want to assume that the
>secure session is over. You can leave the user identification token
>in effect, however. Additionally, you can clear the stored secure
>token after a secure session timeout.
>Briefly, the advantage to using cookies is that:
>a) The user identification token can persist between browser sessions,
>provided they don't explicitly log out.
>b) The user can move between viewing secured and insecured pages.
>Recall that if the user access an insecure page, the secure token will
>*not* be passed along in the URL. When they return to a secure page,
>they will fail check #3, and need to log in again. Cookies, however,
>will still contain the secure token (which is okay, because they will
>only be passed to secure pages) and will pass check #3, but perhaps
>not check #4 (if the timeout has occurred).
>Well, that about sums it up. Obviously there is a lot of work
>involved in correctly supporting secure authentication in a flexible
>fashion. I've found that most other approaches, even on high profile
>e-commerce sites, don't come anywhere close to doing it correctly (or
>securely!). Apologies if I forgot something important here. I
>welcome any comments on this technique, and how to improve it.
>[OT] This is the approached used by eZiba.com. eZiba, the leading
>online provider of handcrafted goods from around the world, recently
>closed a $70M round of financial, with about $20M of that coming from
>Amazon.com. One of the reasons eZiba has attracted so much attention
>is that we elected to build the e-commerce platform from the ground
>up. When evaluating e-commerce platforms, such as Microsoft's or
>OpenMarket's, we found that nothing currently available provided a
>foundation extensible enough to meet our needs. And the open source
>alternatives, such as OpenSales and MiniVend, while certainly
>interesting, don't have the enterprise features we required.
>The mod_perl side of the eZiba platform is actually just the
>presentation layer for the customer. The actual business logic has
>been developed in a stand-alone, threaded, Java server that consists
>of modules that interface with external clients (such as the mod_perl
>StoreFront application, or the database) via an high-level abstraction
>layer (TCP/IP and XML based, obviously). Other clients include a
>product and content management suite and customer support tools. The
>architecture was designed from the start to be flexible, extensible,
>and highly scalable and fault tolerant.
>Over the past six months, eZiba was overwhelmed by requests to use
>this technology. I'm happy to say that we are spinning of a new
>venture, Avacet, Inc., to make this platform available to the
>community. And here's the best part -- everything Avacet does will be
>available open source and free via the GPL. Currently, there are no
>GPL'd e-commerce platforms that come close to providing the
>functionality and enterprise quality of the IBM's and OpenMarket's of
>the world. Avacet, in the next few months, will provide that
>alternative. Additionally, Avacet will be providing consulting
>services to qualified e-commerce companies that seek to lead their
>The reason I mention it here, other than to give people some hope that
>they won't be stuck on WinNT for the rest of their e-commerce lives,
>is to spread the word, and perhaps attract some mod_perl talent to
>Avacet. We are recruiting experienced developers and program managers
>for the team. Since we are moving very quickly, and already have a
>rather accomplished team, I am particularly interested in developers
>that have a rich background in internet application work. If you are
>interested in hearing more about Avacet, please don't hesitate to
>send me a mail at dclinton@xxxxxxxxxxx
>Okay, obligatory apologies for the off-topic job pitch. :)