SafeMode

Advocating for changes to our web infrastructure for more secure applications

Free-Form Input is Bad for Security

Sometime back in the early days of computing, it was decided that free-form input made programs more versatile and therefore better.  Today, most applications that have a command language have adopted this design decision.

When stand-alone, console applications were the norm, free-form input made sense.  It made the end user's job easier.  However, with today's dynamic web content, free-form input has become the ruin of applications the world over.  If the programmer doesn't take special precautions, dynamically generated code that contains user supplied inputs can be manipulated to cause code injection.  For Web applications, the two most common forms of code injection are SQL Injection and Cross Site Scripting.  These vulnerabilities sit atop of the OWASP Top Ten list of web application security risks.


Code Injection

With free-form input, code and data are intermingled, and this facilitates code injection.  Programs use keywords to differentiate code from data and the keywords can be located anywhere within an input statement.  When dynamically generating coding statements, if the programmer doesn't do proper input validation, a malicious user can inject code where the programmer expects data to occur. 

Let's consider the following code:

Sql = "SELECT * FROM users WHERE name = '" + username + "';";

The programmer is dynamically constructing a SQL statement to select a row from the users table.  The input is expected to be the name of a user. 

Unfortunately, a malicious user might input code to change the intended use of the SQL statement. 

a'; DROP TABLE users; --

This input results in the final SQL statement:

SELECT * FROM users WHERE name = 'a'; DROP TABLE users; --';

Now, in addition to selecting a row as the programmer intended, the second part of the SQL statement deletes the "users" table.


What We're Doing Now Isn't Working

Current thinking is that code injection is a problem for the application programmer to solve.  A variety of best practices are recommended, including input validation, character encoding, and parameterized queries.  Our current solutions sound easy enough to accomplish, yet they aren't getting done. 

Unfortunately, the reality is that security is usually a secondary concern for the developer.  Making an application work and meeting a typically aggressive development schedule is usually the primary concern.  The simple fact is that most often security concerns are not addressed until the development team is informed of a problem. 

Many developers have yet to be educated on secure software development.  In fact, software development is quite often not the coder's primary area of expertise.  Even those developers that do know how to code securely sometimes make mistakes or forget to handle a specific instance. 

It only takes one missed injection point to completely compromise an application or its users.  Barely a week goes by without a news media story detailing the latest security exploit.  Code injection is all too often the root cause. 


SafeMode

Browser and database engine vendors can lend the application developer a helping hand.  Ideally, the developer would validate all input data.  However, if he fails to do so, it would be nice if the browser or database programs operated in a "safe" mode.  One way to do this is by structuring command language input.  With a predefined command language structure, these programs could always distinguish code from data and thereby prevent code injection. 


Here's How SafeMode Might Work

Vendors would create a new method for parsing code input for SafeMode operation.  The user would determine which parsing method to use.  A comment within the command language code would initiate SafeMode.  This new "mode" allows for backward compatibility.

When in SafeMode:

By confining where keywords can occur within the input stream, we give our input a structure that separates code from data.  This structured input allows us to effectively prevent code injection.

By signaling his intention to operate in SafeMode, the developer by default prevents code injection in the process of making his code work.  SafeMode gives developers a standardized way of preventing code injection.  When dynamically generating code, they would need only guard against newline characters within user input. 

SQL example
HTML example


Skeptical?

Adding structure definitely can make an activity safer.  Take driving for example.  If you've ever been walking through a parking lot and encountered a driver cutting across aisles, you know the dangers of "free-form" driving.  Society has added structure in the form of road lanes, signs, signals, and driving conventions to make driving safer.  Adding structure to browser and database command languages can make use of these tools safer as well.


Next Steps

With dynamic code generation, application programmers are using browsers and database engines in ways not originally designed for in those programs.  It's time that our vendors took these new requirements into account. 

This whitepaper doesn't attempt to solve all the fine details of implementing SafeMode.  This is a task for the development community at large.  Discuss the details of how SafeMode might be incorporated into our web application tools and urge vendors to adopt these changes.

Code Injection is a problem for both developers and vendors to address. 


Dan Kranz, CSSLP



Downloads:

HTML Formatter
SQL Formatter
A proof of concept extender to Burp Proxy that implements SafeMode web browsing



SafeMode SafeMode hosted on SourceForge.net.
  Fast, secure and Free Open Source software downloads