This concern motivates the following research paper, "Building Secure Web Applications with Automatic Partitioning," where the authors describe a tool they built—Swift—that provides a general-purpose programming language, an extension of Java, for building partitioned Web applications. The secret sauce in Swift is its handling of annotations, placed by the programmer, which declare security properties for objects and variables within the program. These annotations speak toward secrecy or integrity constraints on the data.
For example, say you’ve got a list of passwords (or hashed passwords or whatever else) on the server and you want to validate a client-supplied password. Clearly, you want to perform that comparison on the server side, such that an attacker cannot access other passwords or impersonate other users. But how do you guarantee such a thing? Swift lets us declare the list of passwords to be "sensitive." We don’t want to disclose it to any user. With such annotations, the program partitioning system can figure out that the password-checking logic can only happen on the server side, satisfying the information flow constraints.
Sounds easy, right? Not really. In fact, there’s an important problem. Information flow systems are really good at saying "no." You validated the password, and now you want to let the user know. Unfortunately, that very fact is sensitive information because it was derived from sensitive information. We can’t release that to the user? That’s a problem. Clearly, we need to carve out exceptions to the rules in order to get anything useful done. Swift allows a programmer to make these sorts of exceptions in a controlled fashion, but those will still need to be carefully audited.
Information flow technologies, whether operating statically like Swift, or operating dynamically like the "tainting" mechanism used in Perl, are clearly an important mechanism for building and maintaining secure Web applications. One only has to look at the never-ending parade of cross-site scripting, cross-site request forgery, SQL injection, and other such Web attacks, none of which rely on traditional buffer overflows, to recognize the importance of high-level automated systems built into the development tool chain to improve our assurance that systems are secure. Manual, labor-intensive code audits by security experts cannot scale to support the vast number of new Web applications being deployed each and every day.
The challenge for the research community, with sophisticated tools like Swift, is to simplify the development process, making it easier to get the security labels written properly. Ultimately, our ability to prove that a system is secure, whether Web-based or anything else, is limited by our ability to understand the security model and convince ourselves that the labels we’ve written and properties we’ve derived from those labels are consistent with our high-level security goals. Swift takes us a big step closer to achieving those goals.