When writing software, we often don’t think about the security implications of our actions. Probably because we write software to do something, we’re not always aware of what it shouldn’t do. Their are a lot of guidelines for writing secure code, and designing secure systems. Rather than going in to all of the areas, let me just hit on some of the especially important topics that I’ve come across…

In addition to this post, I’ve included a slide deck that I use when I give talks about writing secure code. A lot of the original slides I got from a talk that Ron Jacobs did at TechEd. I hope you enjoy both!

Buffer Overflows and Overruns

OK… so I’m mostly going to deal with issues that affect .NET developers. .NET prevents Buffer overflows by not giving your code direct access to memory addresses and instead by managing memory access for you and by making sure that everything is type safe.

Here’s my non-technical version of what a Buffer Overflow is. First, a Buffer overflow is something that affects unmanaged code (or unsafe C#). Let’s say that a memory address is designed to hold 9 bits of user input, and instead the user forces 10 bits a information in to it. Normally, the last bit of memory is a return address and tells the code where to go next. In a Buffer overflow attack, a different return address is forced in to that last slot so that the attack can control the flow of the code.

For example, the code might say something like, “If the user is not authorized return to login” and instead the attack forces a return code so that it ends up doing something like this “If the user is not authorized go to the bank account withdrawal screen”. By simply changing the flow of an application, and attacker can do really bad things.

Fixes:

Use .NET (and get out of that unmanaged C++ code 😉 )

Use safe libraries. Many of the C++ common libraries have been re-written to help prevent Buffer Overflow exposure. Make sure that you are using the updated libraries.

Check out the “Banned.h” header file from Microsoft. It’s is a sanitizing resource which supports the SDL requirement to remove banned functions from a code. It lists all banned APIs Download.

Use the /GS Compiler switch. This was introduced by Microsoft to automatically add safety checking to your code when it compiles.

XSS

XSS is an abbreviation for Cross Site Scripting attack. (I know, but CSS was already taken 😉 ) XSS attacks are something that has affected every major web site at one time or another.

Background: When you connect to a website, like amazon or ebay (or any other site that you log in to) it often uses a session cookie to know who you are, and what you are allowed to see (your account info for example). Cookies are not a problem in and of them selves, in fact, your browser makes sure that it only send cookies to the web site that it was issued from. See – your browser trusts the site that you are on.

What is it: In a XSS attack, a malicious user figures out how to load their JavaScript to a trusted site. So that when your browser sends them your cookie, the malicious JavaScript has access to your cookie and forwards it on to the attacker. Then the attacker can impersonate you and access your information.

How it works: Have you ever searched for a random product on a site, like foo, and received a response message that said something like “your search for foo was not found.”? Try searching for “<b>foo</b>”. What happened? If the message looks like this: “your search for foo was now found.”, then they are probably not sufficiently checking the user input. Now image searching for this:

If you get a pop up that say’s “oh noes!” then this site is definitely vulnerable. You see, as far as your browser is concerned, this JavaScript is coming from the server that is generating the result page. Now imagine sending someone an email with a link to go check out this great deal on a new bike http://newbikesforSale.com!

The link above looks legitimate, but it’s actually a link that contains JavaScript to open an simple alert box. You can trust it (it won’t hurt you I promise), but in a XSS attack an attacker uses HTML mixed with JavaScript to embed their JS code in an email link, or more likely on a comment thread, in a blog review, or any place that will let it in.

Fix: All user input is considered evil until proven otherwise. The problem is that we haven’t traditionally considered search forms and product reviews as user input in to our systems, but they are. You can scrub user input easily enough by doing something like string SafeToDisplay = Server.HTMLEncode(userInput); but really you should look at incorporating some of the libraries that are specifically designed to handle these scenarios. Check out Microsoft’s Anti-Cross Site Scripting Library, it’s very comprehensive and covers many more scenarios.

SQL Injection

All user input should be considered evil until proven otherwise. This has never been more true than it is with SQL Injection vulnerabilities.

How it works: Imagine that you have an application with a log in: User name and password. Pretty simple so for huh? Now think about the SQL that you would write to validate a user… It *might* start off looking something like this:

So far so good… as long as everyone enters a user name and password in to the correct textbox on the screen this should validate them perfectly…

but what happens when you enter something unexpected in to one of the boxes..

what would the resulting SQL?

the problem here is that the text from the form is now being executed as part of the SQL statement itself. SQL injection just allowed this person to operate this application with the username BillG… I’m sure that wouldn’t be a problem!

Not just Log In Screens. Any place that user input is translated in to a query to the database is open to attack. Search fields are a notoriously overlooked place for SQL Injections, and not just for logging, at this point the attack can do anything that the application can do. Even worse, many application run as SA (Sql Administrator) just to make “life easy” on the developer. That opens up a whole new problem. Imagine a random user being able to log in to your system, add themselves as an administrator, shut down your server, rewrite your website, reformat your hard rive all from a search box. See the problem?

Fix: the fix is easy, don’t let user input run as SQL. You can prevent SQL Injection by moving away from concatenated string for building sql queries. if you need the flexibility of ad-hoc sql, then write your adhoc sql using parameterized SQL. Otherwise you can move to stored procedures or an ORM like Linq to SQL, Microsoft’s Entity Framework, or nHibernate that will automatically use parameterized sql for you.

White List vs Black List Principle

One thing that I want to call out at this point. It is very tempting to try and “sanitized” every user input instead of moving to one of the more robust solutions mentioned above. I had a friend (a very good developer) that was sanitizing all user input for “bad” words before he would process it. In his words, “we don’t have any products called drop, delete, execute… so I should be able to do a string.Replace on those words and then be fine.

Here’s the problem with that. In Security there is a concept of White List vs Black Lists. A white list approach says, here is what I will allow, and throw away anything else. A Black list take the approach that says, “here is what I won’t allow, I’ll let in anything else that’s not on this list.” The problem with the black list approach is that security is a moving target, there are vulnerabilities today that we didn’t know about yesterday, there will be more tomorrow that I don’t know about today. Just because something isn’t on my “bad” list today, doesn’t mean that it shouldn’t be.

I went to my friends bad word scrubber and entered this : ‘deldeleteete” do you see the word delete in there? What will happen after your scrubber removes it… you’ll be left with “delete”. He started using parameterized SQL.

Encryption

I once interviewed a really smart computer science guy that wanted to come work for our consulting company (primarily focus on business applications). Saying this guy was smart is an understatement. He was a Computer Science PhD candidate with cross disciplines in artificial intelligence and game theory. wow! The problem was that he had very little knowledge or experience writing actual applications. When I asked him about if we should write out own encryption for some application that we were working on, he got all excited and started to go in the details about what it would take to implement out own encryption. I’m pretty sure he had taken a class on this, wrote some thesis on it or something because he was really excited that I had asked him about this topic. Here the thing, never write your own encryption.

Getting encryption done right is hard.. like really hard. In fact, if you are good at it, maybe you should go work for the government, or a university, or RSA directly, but you have no business trying to do that for a business application. Use the tried and true, multiple encryption, publically available libraries to do it right.

3-Types of encryption.

Private Private Key, also known as a symmetrical encryption uses the same key to encrypt and unencrypt. Symmetrical encryption is very fast, so it’s great for encryption transmissions and it used for things like secure communication and SSL. the problem is that it’s less secure because you have to have a secure way to hand out the private key.

Public Private Key, also known as asymmetrical encryption uses two different keys. One key (the public key) is used for encryption, the private key is used for decryption. The benefit here, is that you can yell out for the world to here your public key, but only the person with the private key can do the decrypting. The problem is that it’s very slow and computationally expensive.

So how can two computers talk securely to each other in an open environment like the Internet? The answer is a combination of the above. SSL, or secure socket layer uses a public key to securely transmit a “session” key that will be used for symmetrical encryption for the rest of the communication.

1-Way Hashes cannot be encrypted. How is that helpful? It’s very helpful. A hash can me used to make sure that two values are equal without actually knowing what the values are. For example, my application should never store plain text passwords. If they did it might be possible for those passwords to become compromised. By storing a 1-way hash instead the password cannot be retrieved even if the database (or a backup of the database) is compromised. How do I log user in to the system then? Simple, I take the password they give me, I has it using the same method and compare the two results.

Digital Certificates – Digital Certificate use a combination of the above concepts to support secure communication and identification. We’re just not going to go in to all of that now.

Least Privilege Principle

Reduce your Attack Surface – if you don’t need a service, turn it off. If your application doesn’t need permission to do something, don’t supply it. By limiting the scope of what can be done, you also limit what can be broken if and when things go bad.

Default to Fail – Here’s an example.

What’s wrong with this code? (ok, a lot ) But what we want to focus on is that if there is an exception along the way, it will default to the user being authenticated. The [valid] should have been set to false, until proven otherwise.

Don’t reveal more than is helpful to the user. Be helpful, but you don’t have to thrown up every SQL exception on your users.. log that stuff, let the debug team look at it, but knowing what version of SQL server you’re running or what the stack address is completely useless to your users… but bad people love that stuff.

I love this screen shot. Is that error helpful to you? It says “Error 0x80090022” but it means “No smart card inserted in reader.

Don’t give away your system internals, at the same time make sure that your user errors are helpful!

More resources…

OK.. as you can imagine there’s a lot more that we could cover, but instead take a look at some of these resources.

Threat Modeling Tool – Threat modeling is all about identifying assets, vulnerabilities, resolutions, evaluating a business value on assets, then balance the cost of a resolution with real business value.

SDL Process Template for Team System – SDL is the Security Development Lifecycle, it’s a set of practices and tools that help integrate secure development in to all aspects of SDLC (Software Development Life Cycle). This is Microsoft’s template to integrate SDL with Team Foundation Server (Microsoft’s Application Lifecycle Management Server).

About Caleb Jenkins

Caleb Jenkins is an international speaker, author and 6 time Microsoft MVP award recipient. An entertaining and informative speaker that approaches software from a fresh perspective that spans UX, Agile and enterprise customers from across the globe. He has previously led UX product design teams, coached multi team agile transformations and architected and mentored at some of the largest companies in the world.
As a long time community leader and former Microsoft Developer Evangelist Caleb is well known for his engaging speaking style, depth of knowledge and creative energy. Founder and Principal Mentor at Proaction Mentors, former UX Manager and Agile Coach for Sabre, former Senior Architect for Six Flags Corporation, Caleb currently helps agile development teams working with Slalom Consulting in Dallas.
You can follow him on twitter (@calebjenkins) or his blog, DevelopingUX.com
and if you're still reading this, then you could also subscribe to his blog RSS feed or sign up to receive updates by email