Section 17.3. Host-Proof Hosting


17.3. Host-Proof Hosting

ASP, DataCloud, Key, Secure, Untrusted

Figure 17-9. Host-Proof Hosting


17.3.1. Goal Story

Reta is dismayed to learn that a malicious hacker managed to download a chunk of the company's database containing personal details about all the customers in her store. Fortunately, she also learns that the pass-phrase she always entered was actually used to encrypt all that data, so the hacker won't be able to make sense of any of the contents.

17.3.2. Problem

How can you mitigate the effects of unauthorized access to your application data?

17.3.3. Forces

  • Web apps require that some form of persistent data hold information about users, business state, past events, and so on.

  • Security restrictionsusing standard web technologiesprohibit users from storing web apps on the user's own hard drives. Even with Richer Plugins that allow it, many benefits of using a web app in the first place are lost. This means that persistent data is usually stored server side.

  • Cookies allow some data storage within the browser, but cookie data is also transmitted to the server where it's vulnerable.

  • Server-side storage is open to abuse: the administrators, along with anyone who is able to gain access to it, are able to extract sensitive information by reading the data, as well as effect malicious changes by tampering with it. The abuse can occur within an organization's own IT department or be inflicted by a third-party hosting company entrusted with the data.

17.3.4. Solution

Host sensitive data in encrypted form so that clients can only access and manipulate it by providing a pass-phrase that is never transmitted to the server. The server is limited to persisting and retrieving whatever encrypted data the browser sends it and never actually sees the sensitive data in its plain form. All encryption and decryption takes place inside the browser itself.

Just what does secure hosting have do with Ajax? The Ajaxian twist comes in the maintenance of the pass-phrase. You could use the browser-side encryption with a conventional application, but the pass-phrase would have to be entered upon each page refresh, since no JavaScript state survives a reload. With page refreshes occurring every few seconds, the pass-phrase is completely unusable. However, using Ajax to avoid page refresh means you can retain all session state in the browser, so the pass-phrase only needs to be entered at the start. After being entered, it can be retained as a standard JavaScript string and will disappear from the browser when the user quits the browser or visits another site. Suddenly, Host-Proof Hosting becomes usable.

Incidentally, don't take this pattern to be a new "Ajax-HTTPS" protocol. The issue here is how the data is actually stored, not how it's transmitted. In theory, the data itself need not travel over a secure connection because it's already encrypted. In practice, a secure connection might be worthwhile in order to reduce some of the vulnerabilities described later in this section.

Before you rush off to upload all your trade secrets to Shonky Hosting Inc., you should be aware that this idea isn't foolproof. On the one hand, the host is assumed to be inherently untrustworthy. But on the other hand, the script for the browser application is held right there on the server, and the browser runs whatever scripts come down from that URL. This leaves open the possibility that the host will tamperto evil endswith either the code itself or the outgoing HTML and JavaScript.

What if a rogue administrator from the hosting company decided to quietly add a small monitoring function to a JavaScript file and append its execution to a window.onload function. Then, the evil monitoring function could be made to run once a minute within the browser. It might, for instance, serialize the entire DOM and upload a summary back to the server with Web Remoting (Chapter 6), where more malicious code would log it somewhere convenient. A third-party hacker sitting between the browser and the server could also inject a script and could upload data to a remote site with one of several established techniquesfor instance, by exporting browser data as CGI variables on the source URL of an external image under the hacker's control. In both scenarios, the application can continue as normal, and the poor user is none the wiser.

The threat of script injection certainly weakens the claim for this pattern, but it doesn't invalidate it altogether. While script injection is theoretically possible, it does require some skill on the host's part and is also detectable if you know what the code should and should not be doing. If you happened to discover that your application is uploading DOM details every sixty seconds (using a tool similar to those described in Traffic Sniffing [Chapter 18]), there's a good chance that something's blatantly wrong.

For practical purposes, also consider what happens if a hacker gains unauthorized access for a short time. She might well grab as much data as possible, but the data will be safely encrypted. In the unlikely event such a hacker was sophisticated enough to use script injection, she would only be able to gain pass-phrases of users who happen to be logged in during the time the server is under her control.

So pragmatic considerations suggest that the technique is safer than hosting the data in plain form, though it's by no means perfect. But is it so much safer as to warrant the extra performance overhead and coding effort and the constraint of zero page refreshes? That's a decision you'll need to make on a case-by-case basis, bearing in mind the critical nature of the datathe likelihood of the various types of attack.

In theory, there's an even stronger claim in favor of this approach. It might be possible to develop a general-purpose plugin to detect script injection. For a given application, such a plugin would have access to a certified copy of the source code. Then, it could monitor traffic and caution you about any unexpected activity. If such a plugin could be developed, the only way for script injection to succeed would be a conspiracy between the host, the code certifier, and the plugin manufacturer.

17.3.5. Decisions

17.3.5.1. What encryption algorithm and framework will be used?

You'll need an algorithm that's available in JavaScript as well as in your server-side environment. If the data is accessed by other clients, they obviously must have access to the algorithm too. A search reveals that several algorithm implementations are available, each with its own strengths and weaknesses. All of the following are open source.

  • RC4, AES, Serpent, Twofish, Caesar and RSA are provided by Michiel Van Everdigen's open source package (http://home.zonnet.nl/MAvanEverdingen/Code/).

  • TEA (Tiny Encryption Algorithm) is provided by Moveable Type UK (http://www.movable-type.co.uk/scripts/TEAblock.html).

  • Blowfish is provided by farfarfar.com (http://www.farfarfar.com/scripts/encrypt/encrypt.js).

17.3.5.2. When will the pass-phrase be requested?

The browser will need to query for the pass-phrase as soon as encrypted data must be rendered. However, that might not be immediately. To make the encryption less intrusive, you might consider using something like the Lazy Registration pattern, where regular data is shown as soon as the user accesses the application, with encrypted data only accessible after the pass-phrase has been entered.

17.3.6. Real-World Examples

There are no public real-world examples to my knowledge. One precedent is Hushmail (http://hushmail.com), which uses a Java applet to allow access to email encrypted on the server.

17.3.7. Code Example: Host-Proof-Hosting Proof-Of-Concept

Richard Schwartz provides a proof-of-concept demo (http://smokey.rhs.com/web/test/AjaxCryptoConceptProof.nsf/blowfish?OpenPage)(Figure 17-10). For encryption, it delegates to a JavaScript Blowfish library. The application accepts a pass-phrase, a message key, and some message content. It then encrypts the message and uploads it. It also uploads the key, along with an encrypted version of the key, which can be used later to check that the user has the correct pass-phrase. The application then shows that the server is holding only the encrypted content and the key. You can then pull the encrypted content back down and decrypt it with the original pass-phrase.

Figure 17-10. Host-Proof Hosting


The application itself is quite simple: it manipulates the "display" style settings of a series of forms in order to show or hide them. Thus, the user's pass-phrase remains in the pass-phrase input field at all times. This is the important thing about the demo; there's no form submission, so the pass-phrase needs to be entered only once.

When the application is ready to upload the encrypted data, it sets up the global variables required by the Blowfish library (ideally, the library would accept these as parameters). encodetext( ) is called (with "2" to specify the Blowfish algorithm), and it outputs the encrypted version in the form of a global variable:

   saveCryptoText( ) {     ...     inpdata=window.document.inputForm.plaintextInput.value;     passwd=window.document.inputForm.password.value;     // invoke blowfish     encodetext(2);     data = data + "&check=" + outdata ;     ...   } 

The encrypted key is also attached:

   inpdata=window.document.inputForm.check.value;   encodetext(2);   data = data + "&check=" + outdata ; 

The data can now be sent to the server:[*]

[*] RESTful principles suggest that, in practice, the data would be uploaded with a POST, because the data would affect the server state. Another reason to use POST is that it's not practical to encode an entire message in the URL. However, this application is a proof-of-concept, so GET is used here instead.

   url = "http://smokey.rhs.com/web/test/AjaxCryptoConceptProof.nsf/SaveBlowfishDoc ?OpenAgent" + data   httpPost(url) 

Later on, the application provides a list of message keys that have been sent to the server. When the user chooses one, the application requests an XML document from the server containing the message and key details (in practice, the message key could be verified before the body is downloaded). It first performs a check that the key is valid for this pass-phrase, then decrypts the message itself. Finally, a DOM object is morphed to display the decrypted text:

   inpdata = "";   inpdata = getElementText(valuenode);   outdata = ""   decodetext(2);   ...   window.document.all.decryptedText.innerHTML = stripNulls(outdata); 

17.3.8. Alternatives

17.3.8.1. Richer Plugin

You might consider exploiting the increased permissions of a Richer Plugin (Chapter 8) to access a local data store. However, with this there is still a risk of malicious script injection from the server. Furthermore, you'll lose several key benefits of holding the data server side:

  • Users will not be able to access the data from remote locations.

  • Each local data store will need its own backup process. Uploading to a backup server will defeat the purpose of the local store.

  • Each local data store must be protected against unauthorized access.

  • The data stores will sometimes need to be migrated as the system changes.

Another application of Richer Plugin would be to hold the data server side but use the Richer Plugin in place of the JavaScript code to manage the local encryption and decryption. A plugin like this could also retain the pass-phrase.

17.3.9. Related Patterns

17.3.9.1. Direct Login

Direct Login, like Host-Proof Hosting, also involves using JavaScript for encryption-related activity.

17.3.9.2. Timeout

Apply a Timeout to clear the key from browser state after an idle period. This will help you prevent unauthorized users from accessing the encrypted data.

17.3.10. Metaphor

Caesar wonders whether he can entrust his aide with the top-secret recipe for victory wine. Fortunately, he's a pioneer of cryptography, so he just hands over the recipe in encrypted form.

17.3.11. Want to Know More?

Check out Richard Schwartz's blog entries:

  • Overview of the idea and pertinent conversation in the comments section (http://smokey.rhs.com/web/blog/PowerOfTheSchwartz.nsf/d6plinks/RSCZ-6C5G54)

  • Practical implementation issues (http://smokey.rhs.com/web/blog/PowerOfTheSchwartz.nsf/plinks/RSCZ-6CCMCD)

  • Introducing the proof-of-concept application (http://smokey.rhs.com/web/blog/PowerOfTheSchwartz.nsf/plinks/RSCZ-6CATX6)

  • A hypothetical scenario elaborating the idea (http://smokey.rhs.com/web/blog/PowerOfTheSchwartz.nsf/plinks/RSCZ-6CHL5J)

  • My blog entry summarizing the idea (http://www.softwareas.com/ajax-and-the-great-data-cloud-in-the-sky)

  • Chris Hammond-Thrasher comments on Ajax as a general solution to encryption issues, e.g., digital signatures and secure timestamps (http://thrashor.blogspot.com/2005/05/more-on-ajax-and-secure-web.html)

17.3.12. Acknowledgments

Richard Schwartz's blog entries provided the idea for this pattern, and its name is attributed to Richard Schwartz, Michael Griffes, and their colleagues at eVelocity. I am also grateful to others who have commented on the approach, notably Alex Russell, who has cautioned on the vulnerabilities of this approach, such as script injection.




Ajax Design Patterns
Ajax Design Patterns
ISBN: 0596101805
EAN: 2147483647
Year: 2007
Pages: 169

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net