This past week, I concluded my talk on Security Coding: Best Practices. This was a continuation of Part 1 that I started last week. In particular, I dealt with SQL Injection and issues with Encryption and Cryptography.
I spent a little more time on SQL Injection, because this is a very interesting security issue to me. Even though you think your data is safe behind a few layers (UI, middle-tier), if you are not careful in how you process your calls to your database using the input from the UI, an attacker can easily gain lots of information about and from your database, including retrieving sensitive data and the structure and names of your tables. An attacker can also drop tables and kill your database completely.
SQL Injection is especially possible when concatenated strings are used for SQL queries. For example, if an input form requests a user to enter his/her name and password, and those inputs are used in a query string to determine access:
sql = “select * from users where userId = '“ + userName + “' and password = '“ + password + “'“;
An attacker can use a single quote (') in the userName input field to stop the string. After that, an “ OR 1 = 1 --” could be appended. This sets up a logical condition that will always be true. Plus, the “--” comments out the rest of the SQL query. So, the above query would be sent to the database like this:
select * from users where userId = '' OR 1 = 1 -- ' and password = ''
This would effectively bring back all user information. Very bad.
The key is checking all user input (“Never, ever trust user input“). Check that numeric fields are numeric. Check that string fields have double “single quotes“ (i.e. use a replace function to change single quotes (') into double single quotes ('')). Use stored procedures for access to any data, and when using stored procedures, implement them using the ADO command object or ADO.NET SQLParameter collection and classes so that variables are strongly typed. Always design and code for security from the first day, and test, test, test.
I have put together a list of further resources I have found useful in learning about SQL Injection as well as how to protect against it.
On a personal note:
Last Thursday night, I went to my son David's open house at his school. David is 11, and my second oldest boy out of our six (6) children (two mine, two hers, two ours -- all boys except one girl is hers). His class made these “newspaper” front pages in which they describe their interests, etc. On David's, where he's asked what he wanted to be when he grew up: Computer Consultant. I knew he liked computers, and he puts together killer PowerPoint presenations (complete with story line, graphics, and other multimedia), but this was a nice surprise.
Makes a Dad proud!
I found this great PowerPoint presentation done by Jason Whittington last year called Inside Rotor - Poking at the SSCLI for fun and profit. I found it as part of this set of older wiki links for the Rotor infrastructure.
I have noted in various places (probably old links from a year ago) that Peter Drayton and Jason were collaborating on a book called “CLR Internals“. Is that still in the works? Or is that project put on hold? Does anyone know?
As I mentioned in previous post, I began a series of security talks at my primary client site this past week. Since I have my mind on security, architecture, and unit testing lately, I was thinking about how each of these can be combined.
As we should know by now, security should be of utmost importance in developing robust software. It should permeate all thoughts as we write each method, each class, each web page, each stored procedure, and any other code we write day in/day out. Remember the old sayings: “Don't trust user input”, “Build security in depth”. They all apply here.
A few months ago, Martin Fowler remarked on how surprised he was that some people found it odd that security and architecture/design would be combined in a talk he gave with David LeBlanc (co-author of Writing Secure Code, 2nd Edition). Here are his comments:
One thing that interested me was that several people found the combination odd - implying that few people would be interesting in two such diverse topics. I think this is at the heart of problems about security in the industry. Security is seen as some separate topic area which sits in its silo. Yet security isn't something you can just add to an application by putting in a few encapsulated classes here and there. Security thinking should pervade a whole team - particularly on applications that are available on the internet or a large corporate intranet.
To be fair there's room for people to focus on security issues. There's a lot of stuff to know about on security. But everyone should have a reasonable knowledge about it. As David points out: many eyeballs don't lead to secure code - you need many educated eyeballs. One of the things I like about David's attitude is that educating developers is a key part of the picture, with less emphasis on review steps with security groups.
So, again, security and architecture/design DO go together. They have to be married together. There can be no afterthought for security.
Following these lines of thought, I am wondering about my use of unit testing. Most of my unit testing has to do with testing functionality, correctness, error handling, and other expectations of a method I write. What about security? It seems to me that I should also be writing unit tests to test the security implications of my method. Am I testing for input that could compromise my method, my database, or some other entity that exists after my method?
Typically, I think we rely on other layers to protect our middle-tier layers from the security threats, but if I follow the “security in depth” idea, I still need to take into consideration unit tests for the “possibility” of security holes in my all application layers. I need to think about how a hacker would compromise my middle-layer tiers after moving through the user interface tiers. I need to think about how a hacker would compromise my data tiers after moving through the middle-layer tiers.
What would those unit tests look like? I think the developer would write typical tests for buffer overruns, cross-site scripting, SQL injection, file name issues, and other security coding threats. What other tests could be created?
I am interested in the ideas of others on this topic.
This past week, I completed the first part of my talks on Security Coding: Best Practices at my work place. I didn't get as much covered as I had hoped, but we will continue next week.
The talk was about the various ways a hacker can attack a site on the internet. We dealt with the common threats, and then dived into some developer specific issues such as buffer overruns and cross-site scripting. We spent a long time talking about buffer overruns and the serious problems they cause (as evident recently with the latest security fixes from Microsoft). Although buffer overruns are essentially a thing of the past with managed code, the client site I work for still has thousands of lines of C++ code, so it is still a big issue.
The talk went well, and both the developer and QA departments were interested in how to better code against and test security threats.
Wayne Allen mentions our work with combining Vault and NAnt. It's been great to go from idea to code. Eric Sink has made public an access point for the Vault/NAnt code (for a guest account): http://vaultpub.sourcegear.com/.
Update: Along with Wayne's post, to give credit where it's due, Brian Schkerke did most of the initial work, and Wayne's team made some improvements.
Yesterday and today, I was in Vermont with Sam at the User Group meeting. Sam was presenting an INETA talk on the CLR. Along with others in the group, I have to say it was one of Sam's best presentations I have seen, if not the best. It was something new for him -- not a COM Interop or Managed C++ talk, but a history and use of the CLI/CLR. No IDEs were open -- just a plain text editor and some code, along with our best friends ILDASM and Reflector. Great stuff.
I also enjoyed being a part of Julie's Vermont User Group. I have never seen a better user group experience -- people were very interested, questions were intelligent, and even after the 3+ hour presentation, a large number were still there, eager and alert to learn. That's what its all about. I also enjoyed meeting Dave Burke and Ali Aghareza in person, both bright guys that you should be reading.
I especially enjoyed meeting Julie and her husband Rich. As she mentioned in her post, they were both gracious hosts to me, and I enjoyed my stay with them. The only glitch, as she mentioned, was that we didn't sync up about her cat and my cat allergies. I brought my allergy medicine (which I keep with me all the time), but I didn't have my breathing medicine. That is what affected me adversely last night (and still a touch of it today/now). But, it will pass. I wouldn't have traded the opportunity to get to know both Julie and Rich better.
I wish I had more time to stay in Vermont, but back to work. It is a beautiful area. I took plenty of pictures, and brought back the required Vermont Maple Syrup and Vermont Cheddar Cheese.
I am wondering if there is current interest in .Net Patterns Study Groups?
Continuing my journey into Rotor, I finally got my RedHat Linux 9.0 running through VirtualPC 5.2. Thanks again to Charles Cook and Joseph Cooney for their assistance. Once I created ISO images from the RedHat CDs, and used those for the install, everything worked flawlessly.
One of best books I have seen lately is .NET Patterns: Architecture, Design, and Process by Christian Thilmany:
I found this list of good Secure Coding resources on the MSDN Security section. Here is a summary of the list of articles:
I was noticing John Lam's two posts this morning on .Net Security: Securing ASP.NET using Enterprise Services and Improving Web Application Security: Threats and Countermeasures rocks. These are some areas that I have also been thinking about lately.
Last month, I mentioned that Don Box talked about Generics at the Boston Dot Net Users Group meeting. I didn't mention that he also talked about Iterators and Anonymous Methods, also part of C# 2.0. I wasn't sure if these two topics had been mentioned elsewhere yet.