Sunday, February 28, 2010

Why a Crippling Attack Against US Companies is Very Possible

Sure, some people are doomsayers and we look at them as fringe folks with a grain of truth expanded out to being an entire movement. I'm not being a doomsayer, but a realist, when I say that a concerted web attack on US companies is very possible.

First, in America we believe we are invincible and the smartest, most savvy people on the earth. We are prideful and boastful and believe we deserve every good thing, whether we work for it or not. I know that is a generalization but look around at the people in your neighborhood...I may not be describing YOU but look around you. In the "You serve me" mentality, people think security is someone else's thing, and that others will protect them. In companies, I've seen it where dollars outweigh quality and bad software gets shipped. If they are cutting corners on functionality, do you think they are even doing security on the pieces they create?

Second, we all know security is not "baked in" yet. It is something people add on top of the functionality that makes them money, if they get time. And right now times are tough financially...do you think companies are going to invest in baking security into the software lifecycle? While cutting jobs or shipping them overseas? While cutting corners and costs?

But the bad guys aren't taking time off to let us retool. What happened to Google and Intel and other companies lately is going to continue. Our image of everyone else in the world being less intelligent than us leads us to both our lack of diligence and to their anger against us. Do IT folks (and comical TV ads) bash Microsoft for just the same reasons of them being the arrogant big guy? Like it or not, people are putting our machines under their silent control and putting things in our hands to use against our own companies, government agencies, etc. Some of these botnets are for spam but it is clear now that no one is immune to flat out attack. A little social engineering and mom & pop machine takeover and you have a virtual army set to strike.

Recent stats say that 3-10% of all corporate PCs are compromised right now with malware that most likely puts them into a botnet. These are the places with good protections in place.

This blog started because I was floored at how many developers in big named companies were building sites with big security flaws. I assumed the little guys weren't doing security the best but to see some big companies not doing it floors me. As "invincible" Americans we learn many lessons the hard way and it is not going to do us, and the country we love, any good to learn this lesson that way.

If you are not learning about web security today, and making sure your sites don't allow for attack on/by them, then you are giving some really bad, money-driven people a foothold, a soldier. Enough footholds and you have an army.

My thinking is that many of the devs won't read this post at all even if presented with it, and if they do read it they will poo-poo it as someone else's concern or some doomsayer's rant. It is the way we are as humans and Americans, and we run a strong risk of falling hard simply by not doing the grunt work today.

Saturday, February 27, 2010

Chilean Earthquake search results and your code

So after this morning's earthquake in Chile, it appears that the lovely new (and effective) fake anti-virus software is being propagated out through bad web sites that have cloaked themselves as being about the earthquake and had gotten themselves to the top of the search results on engines like Google. Unwary clickers would go to their site and voila, you've got a virus and they'd LOOOVE to fix it for you. Sigh. Sure, the bad sites will start going further down the list as the day wears on and real sites start getting back to the top based on volume and people linking to those articles.

"Whew!" you say, "Better that this isn't something that is on MY site! Man I could get in trouble for that!" Well, other than just plain old bad sites willingly hosting the fake anti-virus software, you have to be aware that there are other valid sites that the software is coming from (until it is noticed and removed). Is it one of yours?

If you have XSS allowed on your site, especially if you are hosting a forum or discussion group at all, you may have links right to that software ON YOUR SITE. You have to make sure you have XSS covered in all places. If I am a hacker, I'd set up the bad site for search results to have an IFRAME that points to your site which has another hidden IFRAME that grabs the software from a third server. You may be an unwitting contributor to today's malware distribution.

Lock it up and keep your sites out of the mix!

Friday, February 19, 2010

Top Groups Say Devs Should Be Liable

I love this! I'm not the only one saying this stuff. SANS and Mitre are now saying it out loud too -- developers should be held responsible for their product's security.

"Vendors Should Be Liable for Code Security (February 16 & 17, 2010) The 2010 CWE (Common Weakness Enumeration)/SANS Top 25 Most Dangerous Programming Errors list points to cross-site scripting (XSS), SQL injection, and buffer overflow vulnerabilities as the causes of nearly all major cyber attacks in recent years. The consortium behind the list, headed by the SANS Institute and Mitre Corp., is also publishing draft language to use in procurement documents that would hold software development organizations liable for product security."

http://www.sans.org/top25-programming-errors/

http://www.computerworld.com/s/article/9157218/Hold_vendors_liable_for_buggy_software_group_says

Monday, February 1, 2010

XSS Part 3 - How to stop the attacks

In this third of four posts on XSS you will learn how you can stop XSS attacks cold in your ASP.NET apps. "What? Me? Stop them? But those are vicious, deadly attacks by professionals and I am just a newb!" Oh cut it out. Quit your whining and understand that if you don't stop them, they will get your data or attack your company. Find out how to stop the attacks and make it so.

So, in previous posts, we saw what XSS is and how the attacks are executed. Keep in mind the nasty things like img tags that simply execute what is in their "src" attribute without any thought to whether or not there is a real image being returned. If a hacker puts inline script or a URI to an offsite script into the src attribrute, then the script will be returned and executed in your browser.

Ow! So what can be done? Is all lost?? No of course not...settle down. First of all, the bad img tag needs to be on your site somehow. YOU won't put one there, so how else can it get there? Well, if you allow comments on your press releases or on photos on your site, or you allow users to supply input that gets stored or processed for redisplay on your site (comments, posts, discussion groups, user content, profile, etc) then you have to block XSS from happening.

Whitelist Data Entry

Go to those points of data entry into your system, and don't forget things like URLs that you process. Consider whitelisting all input. What is whitelisting? Well, you know that a blacklist is something you don't want to be on because it keeps you out of fun places. Anyone not on the list is allowed in -- but in our case, what if you forget to add the next new method of attack that comes out? And did you catch every way that the attack could be encoded to hide it and beat your filters? A whitelist is the list of acceptable input for a point of entry. Everything else is disallowed -- this protects you now AND in the future. And the maitre d' doesn't accept bribes.

Think about your site's contact form that asks for name and address info. Why accept 4000 characters in the city field? Why accept special characters in a zip/postal code field? Whitelist acceptable input for those fields.
  • Limit your input

  • Strongly type input where possible

  • Do NOT rely on input constraints to save you

Do NOT Rely on Input Validation/Whitelisting Only

That last point is important. Very important. In many cases you use javascript to constrain and validate input on the client side. Whoops...I just turned off scripting in my browser and now I am entering a script tag into the address field! So why bother constraining input at all? Good question. The thing to keep in mind is that input validation should be viewed as a help to your users. Constraining your input is good to stop casual hackers from trying some things, but anyone really trying to get in will not find your input validation a hindrance. So you should set up validators to help someone realize that your address field is only 30 characters when they entered 35, or that a valid phone number does/doesn't accept dashes. That sort of thing.

What To Do If The Whitelist Idea Isn't Possible

Another reason to not rely on input validation is that in some cases your whitelist is going to be too broad to stop some things from happening and/or you can't whitelist easily. Let's say you have a piece of code that looks at the querystring and spits some things out to the screen based on it:

www.site.com/showregiongraph.aspx?region=South for example.

This page is going to get data based on the region querystring variable, and then use that variable as the title to the graph of data. Sure, not a best practice website right there, but you sometimes have to work with other peoples' code, dontcha? So the code grabs the region variable and pulls data, showing a message "No data found" if there is an error or if there is no data found. The logic then takes the region variable and puts it in a label control on the screen. Easy enough! Weeeelllll, let's put some script in the querystring and see what we get!

www.site.com/showregiongraph.aspx?region=<script>alert('hi')</script>

Clearly, this "region" will not return any data and will probably return an error of some sort. But what about when we take the variable and put it into a label control? Can you be sure it won't be put to the browser "as is" and executed as script?

What if the web page takes in a comment about the website and upon postback says "Thank you for your feedback. The following has been sent to our staff: your comment here."? And you want to let people put html in the field so they can bold their nasty words and up the font size when they are yelling at you. What if someone puts the above script tag in that field? You get the idea. People can and will misuse your forms to put script in there. Will the script attack you? Maybe. Could be setting up shop to use your server as a member of a botnet...or opening a gate to distributing malware to attack Land's End. Who knows? Anyway, whitelisting won't help you in some cases.

Encode Your Output To The Screen

One of the best (and only) ways to protect your web pages is to encode all output to your browser. Assume it has been tampered with or is user-generated (we never trust users) and put the proper encoding on all of it. Hey, let the input come in decoded and nasty, and then process it normally, but then encode it before you put it back to the screen. Like with the region example above, who cares if you try to query the database for a region with a script name? (It DOES matter, but we will cover this when we talk about SQL Injection.) So the database returns no records. Great! But if your page takes the input and does a Response.Write() or some other method of putting the raw input to the screen, you need to encode it.

To encode it, you may think to use HttpUtility.HtmlEncode() as mentioned in Microsoft's Patterns and Practices on preventing XSS attacks. This works great for data going to HTML. But what if the data is going to an img tag, an attribute of another tag, the URL, or is being inserted into javascript? HTML encoding may not be what you want. I highly recommend you use Microsoft's new Anti-XSS Library which gives you more granular control with different methods that go to javascript, URL, HTML, etc. You just put the dll in your bin and use the methods in your code.

Whatever you use, encoded script won't run. Period. Doesn't matter what the pesky script would have done, it becomes plain old text that is output as is to the browser rather than executed.

ASP.NET's Default Protection Against XSS

The nice thing for all of us is that ASP.NET 1.1+ has built-in protection against XSS by looking for script tags or other dangerous things. If someone tries to put script in there, including ways where they try to obfuscate what they are doing, the ASP.NET engine sees it and gives you an error message like the following:

A potentially dangerous Request.QueryString value was detected from the client (txt="<SCRIPT SRC=http://h...").

This is turned on by default. Great, right? Well, us lovely developers hit a message like that and wonder "How can I turn that off so I can allow b tags in my content?" We see, "Oh! It is just a page-level attribute!" and turn it off. Sigh. The attribute is ValidateRequest and it is set to True by default. Sure, set it to False and then tags are allowed through...but hey wake up! Tags are allowed through! You've just given hackers an open door. Find other ways to allow b tags. Which is better, a user complaining they can't bold something or a user complaining their social security number was stolen off your site? Your call.

Remember that the default protection is only on the request so you still need to encode the response.

Also

Another reason for going only after the output to the browser is that the browser is where these scripts run. You do have to consider how your data is being used by other people/systems, however. Web input can go to an internal reporting system and that can be as big a problem.

One thing you might not have considered is error logging. Be careful! Don't throw the raw data put into your fields to your event log without encoding it! Think about it -- you drop the script into the event log and there is some internal PHP page your system admins have put in place to view errors called from your site. BAM...script runs in THEIR browser and it might be silent and behind the scenes. Your site is fully protected, your input is validated, your output is encoded, you don't allow scripts to affect your processing, etc. But you dropped the script into a data store (event log) that can be used by other groups who don't have all that security in place. In my opinion, your system admins need to be better about security...they don't have an excuse either. Just like you. But don't give someone a lit bomb either. You are the one in control of the data so you are responsible for it...and you are the one that should be held responsible for the script running on their machines. You handed them a lit bomb. Don't blame them for not disarming it.

Summary

That is really all there is to it. Blur your eyes on all my explanation and it boils down to three things:
  1. Validate and whitelist all input but don't rely on these alone

  2. Encode all output to the screen, plus to any data store that might have consumers of the data that don't/can't encode their output.

  3. Don't turn off default ASP.NET protection of ValidateRequest unless you plan on writing the code you need to whitelist and protect your input sources.

And doing all of these is easy. Use good validators from ASP.NET's toolbox, and use the Microsoft Anti-XSS Library to encode your output.

The next and last post on XSS will give you links and ideas on where to learn the details of how you perform the actual protection in your code.

XSS Part 2 - How the attack works

In this second of four parts about XSS, you will learn how the attack works against your ASP.NET applications. If you are unsure what XSS is, go back and read the first post on it.

So now you know what it is, but you wonder how it works against you. The attack works against any opening where you could get data from a user or from a database and that data ends up being script that executes in your user's browser.

In its simplest form, it is a script tag that executes some inline script directly. Imagine someone typing this sort of script into a blog post comment (on a site that does not stop XSS):

Great post! <script type="text/javascript">alert('Your virus defs are out of date. Please go to badsite.com for an update');</script>

The post "Great post!" would show as you expect, but then there is a script that will run too, showing an alert box and telling you to go to a bad site. What if the javascript just took you there in a new window without an alert box? What if they did it in a hidden iframe right in that post? It would just run and take you there automatically!

Anything people can do using javascript can be used against you -- take your cookies and send them to a site in Russia (man, I hope you aren't doing online banking at that moment!)...go to a site to download malware onto your machine...give you a popup saying virus defs are out of date so they can install malware on you...

Besides script tags, can you think of other tags they could use? Yes, I mentioned iframes. What else? What about img tags? Huh? Did you know you can put a link to a 3rd party script in the src attribute and it will execute?

<img src=http://ha.ckers.org/xss.js />

What I want you to know is that XSS is often not about hitting you right now, or defacing your site right now. Sure, that is possible and does happen. But the big thing is that XSS is used to set you up for either further (and bigger) attacks, or to use you to be part of a bigger more damaging attack on either your company or another company. Imagine XSS used to drop attack malware on 1000 computers...the XSS doesn't hurt you per se...but it drops off part of a bomb to be used against some big name site in a concerted attack. Your machine simply becomes one of the drones. XSS can also open the door to CSRF attacks, and other unfun stuff by letting the attacker drop links used in CSRF attacks onto your forum. We'll talk about CSRF in future posts.

Think you are safe because you sanitize all your webform input? Not so fast, pretty boy. What if your database admin put (or updated) a post in the database by hand, putting script in there? You can't possibly cover every way data gets touched, but you can handle all the output since it is funneled through the single point at the browser. Winform, webform, manual input, generated/calculated data...they all gotta go to the browser. Don't think any of it is safe and scrubbed.

jQuery is some cool stuff, is it not!? It can manipulate the DOM on the fly, swapping images, colors, text, etc. It's just javascript. What if that complimenting post tucked some jQuery in there and changed your banner ads to point to sites that dropped malware off on you? You wouldn't know, your customers wouldn't know...well until someone gets burned and complains to you and you say "What? We don't have banner ads that go to badsite.com!" and you have to shut down your site for a day to clean up the mess.

Your fault.

Stopping XSS is so easy in ASP.NET. You have to be detail oriented, but it isn't hard. I'll show you in the next post. In the meantime, check out http://ha.ckers.org/xss.html and get familiar with some of the other ways XSS can be done on your site. Try a few out on your webforms! Oh, but alert your Info Sec folks before you do that to make sure you don't get in trouble. We need you on the front lines!!

XSS Part 1 - What it is

In this first of four post about XSS, we'll define what it is. The following posts will talk about how the attack is executed, how you can stop it and what resources are available for you. By the end, you will not have any excuses that make any sense as to why security isn't part of what you do.

First, let's define XSS. XSS stands for "Cross-Site Scripting" which means a script on one site is executing at another site, in your browser. OWASP (Open Web Application Security Project)1 has listed XSS as the #2 web attack risk for 20102.

From their document outlining the top risks for 2010, they define XSS as:
"XSS flaws occur whenever an application takes untrusted data and sends it to a web browser without proper validation and escaping. XSS allows attackers to execute script in the victim’s browser which can hijack user sessions, deface web sites, or redirect the user to malicious sites."

Ouch! Sounds nasty, and it is.

So what does this mean to you as a developer? You have a big problem if you take untrusted data and send it to a browser without validation/escaping. So let's define this a little closer.

"Untrusted Data"

-- how do you know what data to trust? Are you trusting your database since it is behind the firewall and is only accessible by system admins? You are? Really?? How does your data get into the database? What if your admins are corrupt and decide to modify the data by hand? Don't ever trust database input. You don't know how it got there. Don't trust user supplied input from form fields. Don't trust URL querystrings. Don't trust anything outside of your app.

Paranoid mentality? Perhaps...but will your CEO care if you say "We felt we were being too paranoid so we trusted that data and didn't realize it would bite us." You can't be too paranoid. Get over the stigma and protect your data.

"Validation/escaping"

-- this simply means you have tested that the data is what you expect to receive, and that you are outputing what you expect to output to the screen by revalidating it and making sure special characters are escaped to render them harmless. Escaping means taking a ">" symbol and making it into "&gt;" for example. If you expect a date for input, make sure it is a date and not some script that will run in the browser. Think people won't use your app like that? Wrong. We're talking about cash here. People will do all sorts of things for some green. If they find your app easy prey, they will use it and tell their friends what the hole is.

Why is this an issue?

-- well, let's assume you leave a field on your web form that accepts 100 characters and you don't validate it. If the user puts a script tag in there instead and it calls a script from a bad site, that runs on your machine and takes your cookies and sends them to Russia, let's say...you won't be happy if the cookie is to your online banking site and someone just used it to transfer money to themselves in your name.

"So if I don't trust any user input and I validate all input/output plus escape output, am I safe from XSS?" Great question. See Part 3 of this series to know for sure. But first, to help you answer the question yourself, let's take a look at how an XSS exploit happens. That is coming up in the next post.

1 http://www.owasp.org
2 http://www.owasp.org/images/0/0f/OWASP_T10_-_2010_rc1.pdf