I wish I could say that I came up with this list, but alas I did not. I came
across it on the Assessment,
Consulting & Engineering Team blog from Microsoft, this morning. They
are a core part of the Microsoft internal IT Security Group, and are around to provide
resources for internal and external software developers. These 6 rules are key
to developing secure applications, and they should be followed at all times.
Personally, I try to follow the rules closely, and am working hard at creating an
SDL for our department. Aside from Rule 1, you could consider each step a sort
of checklist for when you sign off, or preferably design, the application for production.
--
Rule #1: Implement a Secure Development Lifecycle in your organization.
This includes the following activities:
-
Train your developers, and testers in secure development and secure testing respectively
-
Establish a team of security experts to be the ‘go to’ group when people want advice
on security
-
Implement Threat Modeling in your development process. If you do nothing else, do
this!
-
Implement Automatic and Manual Code Reviews for your in-house written applications
-
Ensure you have ‘Right to Inspect’ clauses in your contracts with vendors and third
parties that are producing software for you
-
Have your testers include basic security testing in their standard testing practices
-
Do deployment reviews and hardening exercises for your systems
-
Have an emergency response process in place and keep it updated
If you want some good information on doing this, email me and check out this link:
http://www.microsoft.com/sdl
Rule #2: Implement a centralized input validation system (CIVS) in your organization.
These CIVS systems are designed to perform common input validation on commonly accepted
input values. Let’s face it, as much as we’d all like to believe that we are the only
ones doing things like, registering users, or recording data from visitors it’s actually
all the same thing.
When you receive data it will very likely be an integer, decimal, phone number, date,
URI, email address, post code, or string. The values and formats of the first 7 of
those are very predictable. The string’s are a bit harder to deal with but they can
all be validated against known good values. Always remember to check for the three
F’s; Form, Fit and Function.
-
Form: Is the data the right type of data that you expect? If you are expecting a quantity,
is the data an integer? Always cast data to a strong type as soon as possible to help
determine this.
-
Fit: Is the data the right length/size? Will the data fit in the buffer you allocated
(including any trailing nulls if applicable). If you are expecting and Int32, or a
Short, make sure you didn’t get an Int64 value. Did you get a positive integer for
a quantity rather than a negative integer?
-
Function: Can the data you received be used for the purpose it was intended? If you
receive a date, is the date value in the right range? If you received an integer to
be used as an index, is it in the right range? If you received an int as a value for
an Enum, does it match a legitimate Enum value?
In a vast majority of the cases, string data being sent to an application will be
0-9, a-z, A-Z. In some cases such as names or currencies you may want to allow –,
$, % and ‘. You will almost never need , <> {} or [] unless you have a special
use case such as http://www.regexlib.com in
which case see Rule #3.
You want to build this as a centralized library so that all of the applications in
your organization can use it. This means if you have to fix your phone number validator,
everyone gets the fix. By the same token, you have to inspect and scrutinize the crap
out of these CIVS to ensure that they are not prone to errors and vulnerabilities
because everyone will be relying on it. But, applying heavy scrutiny to a centralized
library is far better than having to apply that same scrutiny to every single input
value of every single application. You can be fairly confident that as long
as they are using the CIVS, that they are doing the right thing.
Fortunately implementing a CIVS is easy if you start with the Enterprise
Library Validation Application Block which is a free download from Microsoft that
you can use in all of your applications.
Rule #3: Implement input/output encoding for all externally supplied values.
Due to the prevalence of cross site scripting vulnerabilities, you need to encode
any values that came from an outside source that you may display back to the browser.
(even embedded browsers in thick client applications). The encoding essentially takes
potentially dangerous characters like < or > and converts them into their HTML,
HTTP, or URL equivalents.
For example, if you were to HTTP encode <script>alert(‘XSS Bug’)</script>
it would look like: <script>alert('XSS Bug')</script>
A lot of this functionality is build into the .NET system. For example, the code to
do the above looks like:
Server.HtmlEncode("<script>alert('XSS Bug')</script>");
However it is important to know that the Server.HTMLEncode only encodes about 4 of
the nasty characters you might encounter. It’s better to use a more ‘industrial strength’
library like the Anti
Cross Site Scripting library. Another free download from Microsoft.
This library does a lot more encoding and will do HTTP and URI encoding based on a
white list. The above encoding would look like this in AntiXSS
using Microsoft.Security.Application;
AntiXss.HtmlEncode("<script>alert('XSS Bug')</script>");
You can also run a neat test system that a friend of mine developed to test your application
for XSS vulnerabilities in its outputs. It is aptly named XSS
Attack Tool.
Rule #4: Abandon Dynamic SQL
There is no reason you should be using dynamic SQL in your applications anymore. If
your database does not support parameterized stored procedures in one form or another,
get a new database.
Dynamic SQL is when developers try to build a SQL query in code then submit it to
the DB to be executed as a string rather than calling a stored procedures and feeding
it the values. It usually looks something like this:
(for you VB fans)
dim sql
sql = "Select ArticleTitle, ArticleBody FROM Articles WHERE ArticleID = "
sql = sql & request.querystring("ArticleID")
set results = objConn.execute(sql)
In fact, this
article from 2001 is chock full of what NOT to do. Including dynamic SQL in a
stored procedure.
Here is an example of a stored procedure that is vulnerable to SQL Injection:
Create Procedure GenericTableSelect @TableName VarChar(100)
AS
Declare @SQL VarChar(1000)
SELECT @SQL = 'SELECT * FROM '
SELECT @SQL = @SQL + @TableName
Exec ( @SQL) GO
See this article for a look at using
Parameterized Stored Procedures.
Rule #5: Properly architect your applications for scalability and failover
Applications can be brought down by a simple crash. Or a not so simple one. Architecting
your applications so that they can scale easily, vertically or horizontally, and so
that they are fault tolerant will give you a lot of breathing room.
Keep in mind that fault tolerant is not just a way to say that they restart when they
crash. It means that you have a proper exception handling hierarchy built into the
application. It also means that the application needs to be able to handle situations
that result in server failover. This is usually where session management comes in.
The best fault tolerant session management solution is to store session state in SQL
Server. This also helps avoid the server affinity issues some applications have.
You will also want a good load balancer up front. This will help distribute load evenly
so that you won’t run into the failover scenario often hopefully.
And by all means do NOT do what they did on the site in the beginning of this article.
Set up your routers and switches to properly shunt bad traffic or DOS traffic. Then
let your applications handle the input filtering.
Rule #6: Always check the configuration of your production servers
Configuration mistakes are all too popular. When you consider that proper server hardening
and standard out of the box deployments are probably a good secure default, there
are a lot of people out there changing stuff that shouldn’t be. You may have remembered
when Bing went down for about 45 minutes. That was due to configuration issues.
To help address this, we have released the Web Application Configuration Auditor (WACA).
This is a free download that you can use on your servers to see if they are configured
according to best practice. You can download it at this link.
You should establish a standard SOE for your web servers that is hardened and properly
configured. Any variations to that SOE should be scrutinised and go through a very
thorough change control process. Test them first before turning them loose on the
production environment…please.
So with all that being said, you will be well on your way to stopping the majority
of attacks you are likely to encounter on your web applications. Most of the attacks
that occur are SQL Injection, XSS, and improper configuration issues. The above rules
will knock out most of them. In fact, Input Validation is your best friend. Regardless
of inspecting firewalls and things, the applications is the only link in the chain
that can make an intelligent and informed decision on if the incoming data is actually
legit or not. So put your effort where it will do you the most good.
The other day I had the opportunity to take part in an interesting meeting with Microsoft.
The discussion was security, and the meeting members were 20 or so IT Pro’s, developers,
and managers from various Fortune 500 companies in the GTA. It was not a sales call.
Throughout the day, Microsofties Rob Labbe and Mohammad Akif went into significant
detail about the current threat landscape facing all technology vendors and departments.
There was one point that was paramount. Security is not all about technology.
Security is about the policies implemented at the human level. Blinky-lighted devices
look cool, but in the end, they will not likely add value to protecting your network.
Here in lies the problem. Not too many people realize this -- hence the purpose of
the meeting.
Towards the end of the meeting, as we were all letting the presentations sink in,
I asked a relatively simple question:
What resources are out there for new/young people entering the security field?
The response was pretty much exactly what I was (unfortunately) expecting: notta.
Security it seems is mostly a self-taught topic. Yes there are some programs at schools
out there, but they tend to be academic – naturally. By this I mean that there is
no fluidity in discussion. It’s as if you are studying a snapshot of the IT landscape
that was taken 18 months ago. Most security experts will tell you the landscape changes
daily, if not multiple times a day. Therefore we need to keep up on the changes in
security, and any teacher will tell you, it’s impossible in an academic situation.
Keeping up to date with security is a manual process. You follow blogs, you subscribe
to newsgroups and mailing lists, your company gets hacked by a new form of attack,
etc., and in the end you have a reasonable idea of what is out there yesterday. And
you know what? This is just the attack vectors! You need to follow a whole new set
of blogs and mailing lists to understand how to mitigate such attacks. That sucks.
Another issue is the ramp up to being able to follow daily updates. Security is tough
when starting out. It involves so many different processes at so many different levels
of the application interactions that eyes glaze over at the thought of learning the
ins and outs of security.
So here we have two core problems with security:
-
Security changes daily – it’s hard to keep up
-
It’s scary when you are new at this
Let’s start by addressing the second issue. Security is a scary topic, but let’s breaks
it down into its core components.
-
Security is about keeping data away from those who shouldn’t see it
-
Security is about keeping data available for those who need to see it
At its core, security is simple. It starts getting tricky when you jump into the semantics
of how to implement the core. So let’s address this too.
A properly working system will do what you intended it to do at a systematic level:
calculate numbers, view customer information, launch a missile, etc. This is a fundamental
tenant of application development. Security is about understanding the unintended
consequences of what a user can do with that system.
These consequences are of the like:
-
SQL Injection
-
Cross Site Scripting attacks
-
Cross Site Forgery attacks
-
Buffer overflow attacks
-
Breaking encryption schemes
-
Session hijacking
-
etc.
Once you understand that these types of attacks can exist, everything is just semantics
from this point on. These semantics are along the line of figuring out best practices
for system designs, and that’s really just a matter of studying.
Security is about understanding that anything is possible. Once you understand attacks
can happen, you learn how they can happen. Then you learn how to prevent them from
happening. To use a phrase I really hate using, security is about thinking outside
the box.
Most developers do the least amount of work possible to build an application. I am
terribly guilty of this. In doing so however, there is a very high likelihood that
I didn’t consider what else can be done with the same code. Making this consideration
is (again, lame phrase) thinking outside the box.
It is in following this consideration that I can develop a secure system.
So… policies?
At the end of the day however, I am a lazy developer. I will still do as little
work as possible to get the system working, and frankly, this is not conducive to
creating a secure system.
The only way to really make this work is to implement security policies that force
certain considerations to be made. Each system is different, and each organization
is different. There is no single policy that will cover the scope of all systems
for all organizations, but a policy is simple.
A policy is a rule that must be followed, and in this case, we are talking about a
development rule. This can include requiring certain types of tests while developing,
or following a specific development model like the Security Development Lifecycle.
It is with these policies that we can govern the creation of secure systems.
Policies create an organization-level standard. Standards are the backbone of
security.
These standards fall under the category of semantics, mentioned earlier. Given
that, I propose an idea for learning security.
-
Understand the core ideology of security – mentioned above
-
Understand that policies drive security
-
Jump head first into the semantics starting with security models
The downside is that you will never understand everything there is to know about security.
No one will.
Perhaps its not that flawed of an idea.
In the previous post Make it Right I
asked the question
Why aren’t more people making it right?
I was curious why people don’t take the time to write software properly. There
are lots of jokes about bad software development:
If houses were built the same way programmers build programs, we’d all be living on
the street.
Unfortunately it’s a fair statement. Most programs out there suck*. I
used to come back with the argument that people have been building houses for thousands
of years, but software for only a few decades. There are bound to be issues.
But then it occurred to me.
Mike Holmes is all about making it right, as I said in the previous post. His
TV show was about fixing the problems that professionals made. Professionals
who have been building the same thing people have built for thousands of years.
Wait a minute. I just flawed my own argument.
Houses are built the same way programmers build programs.
Why?
I see three very apparent reasons.
-
Cheapness – People want software built quickly, as cheap as possible.
-
Laziness – Why strain your mental processing or follow best practices when you can
just do whatever first comes to mind?
-
Uneducated – Sometimes (a lot of times) the person doing the building/development
just doesn’t know what they are doing.
There are numerous other reasons why, but these three are by far the biggest across
all aspects of building stuff. I think they answer the basic question asked
earlier, but now I have another question.
Why do we let people who are lazy or uneducated build applications for us, just so
we can save a few bucks? We will end up paying loads more in support after the
fact…
*I said programs, not programmers.
I hated school. Technically, I’m still enrolled in college. Bachelors
of Business Management. Blech. I figured at least with business, I would
learn something useful later in life. I chose against Comp. Sci. for a few reasons.
One being that I know a couple PhD’s that know nothing about building applications
in the real world.
In Comp. Sci., you learn how to build data structures, and how to make Mandelbrot
Set’s process faster. In business, you learn why people buy stuff.
Or more appropriately, you learn how to get people to buy your stuff.
Seeing as I learned (taught myself?) about things like linked-lists and pointers while
in grade 10-ish, and wrote/re-wrote/re-re-wrote Mandelbrot Set builders as a final
project in grade 11, I think I can safely say I would be bored as all hell in University.
Not to mention all the theory. Comp. Sci. is all about theory. Maybe 10%
is actually coding. F-that.
Business is inherently hands-on.
I like hands-on. It’s tangible.
The only problem I had was finding resources. My programming teachers were pretty
cool, and were always willing to help me on algorithms that confused me, as well as
extra-curricular programs when something just wasn’t jiving. But I had cool
teachers. Not everyone is as lucky as I was. And with the teachers, they
weren’t thinking in C# or ASP.NET everyday like I tended to do. Trying to ask
them why something trivial like
<asp:TextBox ID="txtUsername">
didn’t compile was kinda painful. I usually got a response along the lines of
“what’s the colon for?”. I always felt funny trying to explain the quasi-xml
structure of ASP.NET to teachers. This left me in a lame position of needing
to find help. Forums are great, but separating the wheat from the chaff is a
waste of time. Enter stackoverflow.com (4
years late, mind you) and you get answers quickly. I like it. I use it
all the time. I’d like to think that those who are willing to look for resources
will find the site fairly easily. However, there is another site out there that
not too many people know about. It’s the Microsoft
Student Experience site. Yeah yeah, brain wash them early. I drank
the kool-aid early.
Part of the website is dedicated to the DreamSpark program.
Free, fully-licensed Microsoft products. Nuff said.
The other half of the site is dedicated to students. Good thing, given the name.
Not just students studying software development either. All students.
It provides tangible resources for students. Stories, tutorials, and templates
look to be the main content. It’s all surprisingly good stuff too. It
ranges from school studies to general life, to post-school life.
These resources may help those students who are struggling with school – at any level.
There are students out there with lots of potential. Let’s not see it go to
waste.
Good enough is sometimes not good enough. I’ve been doing a lot of thinking
lately (well, I’m always thinking), and security has been an issue that has come up
a lot. Frankly, I’m a two-bit software developer. I know my code isn’t
the best, nor the most secure. I use strong passwords, encrypt my sensitive
data, and try to limit access to the applications for those who need to use it.
In theory this works. Problem is, it’s a lame theory. There are so many
unknown factors that have to be taken into account. Often times they aren’t.
When I go to build an application I spend time designing it and architecting it.
This is usually the case for most developers. What I’ve noticed though, is that
I don’t spend time securing it. I can’t.
Imagine building a house. You put locks on the doors, bars on the windows, and
someone breaks in. Why? Because someone left the key in the door.
You can’t build against that. You just can’t.
You can follow the Security
Development Lifecycle, which I recommend to each every single developer I meet.
There are tons of resources available.
But it can only go so far. It’s designed more for being part of the iterative
processes, not the architecture. Or at least, that’s how most people interpret
it.
So?
My last post talked about Single
Sign-On (SSO). It’s a great sellable feature for any product. What most
people don’t realize though is the inherent security benefit to it. With it,
that means one less password to remember, one less password that could get intercepted,
one less password to change every month. This is a fundamental architectural
issue. But at the same time, it’s common sense.
What is sometimes the simplest idea, is usually the correct solution
What the hell does that mean? It means keep it simple. Security is simple.
Keep data from prying eyes, and keep it from getting lost. This is common sense.
Security is not difficult to comprehend. It becomes difficult when academics
get involved. Spouting theories and methodologies scares people into thinking
security is extremely difficult to implement. It’s not!
Follow the Data
Understanding the flow of data is crucial in properly architecting an application.
It’s crucial in properly securing an application as well. SSO
is a perfect example of this.
The SSO feature in Office SharePoint Server 2007 maps user credentials to back-end
data systems. Using SSO, you can access data from server computers and services that
are external to Office SharePoint Server 2007. From within Office SharePoint Server
2007 Web Parts, you can view, create, and change this data. The SSO feature ensures
that:
It makes perfect sense. It’s simple when you think about, and it affects every
subsystem of SharePoint. Make security a feature.