Wednesday, 30 September 2009

If Domain Driven Security is to be useful, then it must provide some value in usual situations – situations that programmers encounter every day.

So, what are those usual security problems in applications? Well, to start let’s note that we are not looking for the hardest problems, neither for the most intricate solutions. We are looking for the kind of stuff that does harm, just because we have no really good way to handle them.

If we have a look at OWASP Top Ten we find Cross-Site Scripting (XSS) at the top. It is a really interesting problem, but as XSS is not so widely understood I’d like to save that for a moment. Instead, let us have a look at number two and see if we can wrap our heads around it. At number two on the list we find Injection Flaws with SQL Injection as its prime representative. Well, SQL Injection is no news so let’s go for that one.

The canonical SQL Injection flaw is a login/authentication service that handles its parameters a little bit too sloppy.

/** Service for management of user accounts,

* authentication etc. */

public class AccountService {

private DataSource accountDs;

/** Authenticates a user with a given password.

* @param username

* @param passwordMD5 hash of password

* @return user id, or null if no matching account

*/

Integer authenticate(String username, String passwordMD5)

throws SQLException {

Connection con = accountDs.getConnection();

Statement stmt = con.createStatement();

String sqlSelect = "SELECT uid FROM Accounts";

String usernameMatch = "username = '" + username + "'";

String passwdHashMatch = "passwdHash = '" + passwordMD5 + "'";

String sql = sqlSelect +

" WHERE " + usernameMatch +

" AND " + passwdHashMatch;

ResultSet rs = stmt.executeQuery(sql);

Integer result;

if(rs.next()) { // found account with matching password

result = rs.getInt("uid");

} else { // no matching account

result = null;

}

return result;

}

}

The string parameters are probably fetched from some form, where the password is hashed with MD5 before sending off for authentication.

Typing in username’ OR 1=1 -- (note the initial single quote) and password doesntmatter, the executed SQL will look like this, with everything after “--“ being an SQL comment..

Obviously “1=1” is true for any row, so we will get back all rows in the Account table. From this resultset we will get the user id of the first row. And, there is a fair chance this is the first user that entered the database, which might be the fully authorized “bootstrap init user”. So, presenting yourself as ’ OR 1=1 --/doesntmatter gives you full privileges to the system.

A usual reaction on this attack is “what the ---, but that is not a proper username” often combined with “that is just bad indata validation”, where after the problem is dismissed as trivial, uninteresting, and not worth further efforts.

True, the attack string might not be what we consider a valid user name, and there are problem with the indata handling. However, obviously that analysis does not suffice. If those two sentences of analysis where useful, then SQL Injection would not be number two de facto problem on the OWASP list. Bear in mind that the OWASP Ten Top is not the list of the hardest problem around – it is about what we actually find in code out there, and that are exploited on a daily basis. And most of that code is written by pretty smart people.

The usual advice to solve SQL Injection is to use prepared statements. In Java, the SQL API have a PreparedStatment interface, and using “SELECT uid FROM Accounts WHERE username = ? and passwdHash = ?” solves the problem in this specific case. If all SQL Injections where like that, the story could end there.

Unfortunately, the situation can be more convoluted. The SQL might be inside a stored procedure which we call, or locked up in some part of the application we do not have access to – third part vendor or other department with which we have complicated diplomatic relations (yepp, such happens).

It might also be that we are not working with SQL, but with some (possibly legacy) backend-system with some SQL-like syntax, and where the API (if such exists) does not provide any equivalence of prepared statements.

It is easy to dismiss SQL Injection with “bad indata validation” and “use prepared statements”, but I think that is a mistake made by analysing the simplest example without considering that the situation could be a lot more complicated. Had it been so simple, then it would not be so many problems – so evidence speaks against the “SQL Injection is simple” hypothesis.

SQL Injection is clearly a problem that needs to be taken seriously, analysed more in depth, and target for finding design patterns and mindsets that address and avoid it.

Monday, 21 September 2009

Dear JuniorThere was a time whensecurity incidents where often due to bad configurations of firewalls or otherdeficiencies in infrastructure.Those days are long gone. According to my friends who do pen-testing (trying to get into systems while wearing a white hat)– only 5 % of their“success” are bad infrastructure. The remaining 95 % is bad applications. Applications written by programmers like you and me.Applications, whichaccidentallyhaveleftholesbig enough for an attacker to creep through. Holes, left by programmers like you and me.Holes, whichmightenable an exploiterto download all the data in the database, or to installarbitraryprograms on the backend servers. Or, equally bad, to use our site as a springboardto attack the rest of the world– probably starting with our customers.

How come we leave holes in our applications? I think that we programmers in general have not yet realised that the applications we publish on public web sites (such as on-line) are routes that lead down to business critical data and business critical infrastructure.But of course they are, without access to the data, and access to the infrastructure, what value would the application have?So, someone have to stop the outside from using our application to misuse the data and the infrastructure.That someone is you and me.OK, the alarm bell has rung.There are holes in thehull, ship is sinking.What do we do about it?What tools are around to grab?I grab the Domain Driven Design toolbox and hope thatclarity-of-purpose and quality-of-code will coverup at least a fair quantity of thebiggestholes.If we can use those tools to cover up e g Cross-Site Scripting and Injection attacks, then there is hope. Then we might be successful with other more complicated and subtle security problems.That is what Domain Driven Security is about to me.YoursDanps Using value objects can solve SQL injection in a lot of situations, but not the general case.

Wednesday, 16 September 2009

As you know I have always had a soft spot for security.It has been one of myfavouritenon-functional requirements, both because it contains so many facets, and because it is often the onecraving themostmaturity from both tech-side and business-side.When starting at Omegapoint about six years ago I had two missions: to build up a Java/J2EE group, and to apply the security competence of the company into the system architecture space.The first half, well I have been doing that quite a lot with all the talentedcolleagues I have had thepleasure of working with. The second half has just come full circle around.

In various discussions, my colleague John Wilander and I have talked about the tangent points and crossroads of Domain Driven Design on one hand and application security a la OWASP on the other hand– coming from two different directions, but with an interested eye on the other side. We have now come so far we dare to put a label onour ideas, and we call it“Domain Driven Security”. John is really the one to explain it from the application security point of view, read his description at the OWASP Sweden blog.

I will try to say what I see from my Domain Driven Design point-of-view.

The OWASP community have identified what they classify as the top ten threats against security of applications.At the top of the current listareCross-Site Scripting (XSS) and Injection Flaws (e g SQL Injection). So, the list points out things you should be aware of, but is not specific on how to avoid them. To me, there are good breeding ground for taking ideas from Domain Driven Design and using them as tools to address these security concerns, even though the tools were not originally designed specific for security issues.

For example XSS is an attack where some text is send in as“content” (text) and the system is fooled to interpret it asexecutable code, often executing it as javascript inside the browser of the victim. Likewise, the basics of SQL Injection is to write some maliciously designed value in a textfield thatis used as an SQL parameter– and doing so in a way that makes themalicious text become part of the query structure, bending it into doing something completely different.The underlying problem is that something intended for one context(data)is misinterpreted in another context (code)– in DDD terminology a domain model violation. My idea is that using DDD mindset and ajudicioususe of e g value objects couldaddress this.

Addressing the OWASP Top Ten is however not the complete ambition of Domain Driven Security– I think it might range furtherthan so. I see potential to also address more subtle problems with informationsecurityin different forms.

I better get a little bit more specific and give some examples. As security issomething that is oftensurrounded by hush-hush I will tell you some stories. They might be true, they might be not; I might have been there, I might have not; it might be hearsay, it might be not.

An internationalSwedish retailer (there are several, sellingdifferent kinds of stuff) had an on-line order system on their website.However, if you ordered“-5” of their popular Kagazboo-stuff, the system reacted by issuing a debit note.Well, you can simply say that it is bad indata validation, but what should you validate against if not a model of the domain? And for that validation to be valuable, the model must be strict in the same way thatDDD prescribes. In this case, the missing concept is“amount”, which is only allowed to be non-negative. This might have caused the retailer monetary harm as they where exploited, or itmighthave not as the problem was found by a pen-test team. Either is possible and plausible.

Another kind of reseller had lotsofsimilarterminology forclosely related stuff around delivery of goods and money. They where taking about“order”,“payment agreement”,“contract” and“imbursement” together with a bunch of different terms.As the company was quite big, the different departments used almost the same words. Some departments did not need the full set ofterms; sometimes they used the same word with different meaning, and sometimes with the same meaning apart from some subtle detail.Well: it turned out that in some cases customers could cancel an order and get areimbursement– even though they had not paid the goods yet. This was because the reimbursement systems thought that an order with status“final” had been paid, because that is what shipping thought, and that is where they got their data from.However, shipping only got the“payment agreements” from sales (what they called“payments” for short), and not the“imbursements” from accounting– because they had never had need for that data. Or, itmight have beenthe other way around…

Nevertheless, the bottom line of this semantic soup is that it is totally uninteresting whether someone was right or wrong, or whoever“owned” the definition of‘payment agreement’. For each system the terminology made perfect sense and fulfilled its purpose. However, on a‘holistic’ scaleloopholes appeared when systems where integrated. The company might have lost money, or they might have not. It might not even have happened, but as story it serves explain my idea.

The obvious, and wrong,solution wouldbeto call everybody into a room and workshop until you had created a full Enterprise Information Model (“model in the sky”). People have tried that and it simply does not work once you scale up to the level where you need it.

However, using Context Mapping a la Strategic DDD, would concentrate on each integration and ensure that not only the right data was transformed, but also that it was interpreted in a correct way.Doing that would probably have surfaced that the integration was“conceptually broken” and the integration patterns would have changed.

So, I see anenormous potential in using Domain Driven Design to address information security problems– whichI see as the goal of Domain Driven Security.

To start somewhere we arepreparinga presentation for Omegapoint’s upcoming annual“competence conference”where John and I will attempt to sort out the XSS and SQL Injection problem using Domain Driven Design value objects. If that turns out well, we will try other audiences, conferences andstart working with our clients.

I realise thatdescribing this as“coming full circle” is simply not true. This is not a closing. It is the start of a really interesting field.