Brendan Enrick

Daily Software Development

Cookies - Code Audits #2

This is the second post in what I hope to make as a 30 post series of blogs about things I’ve seen in different code bases over my years as a software consultant. I will not be mentioning any client’s names or giving any easy way for people to identify the client whose code base has or did have any of these issues.

My team and I are often brought in on existing projects where the original development team failed to complete the code, created a big ball of mud that made bugs common and features slow to create, or simply where the previous team has completed the work and the customer just wants to know the quality of the code base.

Cookies

Cookies are a great way for developers to keep track of which client is communicating with them. They can store information in the browser. That sounds great doesn’t it?

The cookie gets an expiration date and is accessible from ASP.NET when the user visits your site. This gives you a chance to look at the cookie and get the information that has been stored in the cookie.

The cookie is able to expire when you want it to and will allow the user to close their browser, come back later, and still have the cookie being identified by your site.

These are most often used a means of identifying a user. When you log in to a site, you will get a cookie, which has a unique identifier allowing the site to identify you during that session.

What should be stored in a cookie?

  • Temporary GUIDs
  • Unimportant information
  • Tracking information that in no way identifies the user

Interesting things found in cookies

You can find all kinds of things getting stored in cookies. Now might be a good time to go looking through your own browser’s cookies to see what things sites have stored there.

Full Address Information

One site had an interesting way of making sure it always had access to your relevant information. It kept it all stored in a cookie. Yes, it had your name, address, phone number, email address, etc. stored in a cookie. I bet you’re really happy to know that the information is being stored in a cookie where pretty much any interested party can access it.

This means that anyone sniffing your traffic would see these values being passed when you navigate around the site. Also, it keeps everything nicely packaged up for consumption by spyware or other malware.

Username and Password Information

Ever wonder how a site lets you “Stay logged in for 30 days”? Well I hope the site you’re using doesn’t do it the same way as this one. One application used a cookie to keep your username and password… Where anyone can get it… and it wasn’t encrypted or anything… Clear text…

I think this one explains itself.

You account number and access rights

When you log in to a site, you get access to your stuff and not other people’s stuff. One site whose codebase I’ve seen kept track of this information by storing the account number in the cookie. (At least it wasn’t in the address bar.) Yes, that’s correct. If you just change the account in your cookie, you can see someone else’s account.

One might expect at least a GUID, so it would be hard to guess the other account number, but one would be wrong. These account numbers were integers starting at the number… 1. Each was incremented sequentially by one.

More Code Audit Nuggets

Keep watching for more interesting nuggets of stuff that I’ve seen in codebases.

URL Parameters - Code Audits #1

This is the first post in a series that I am writing that focuses on some interesting finds from different code bases I’ve seen over my years looking at lots of different software projects. Code Audits are one place where lots of interesting bits of code can be found, since you're combing through an entire software system. I will be explaining what I’ve seen, why it’s wrong, and usually the better approach if it’s not obvious.

URL Parameters

URLs let you control the navigation as your user navigates around your site. Users may not know what URLs mean or how they work, but most people browsing the web know that URLs exist. A good number of them know that modifying that URL will take them to different pages. Even my mother knows that much about URLs.

It’s not just a tech savvy computer programmer or hacker who can figure out that changing the URL might get them to a page they’re trying to see. This is sometimes useful on site’s whose navigation is somewhat lacking. It’s also often possible to guess the page you’re looking for by adding “/login” or some other common word to find a page whose link you’re not seeing.

The Bad

On web sites that have user accounts associated with multiple accounts, it’s quite common for the current account that the user is viewing to be specified in the address bar using a query string parameter. Normally, this means that there will be something along the lines of “?AccountId=123456” on the end of the URL. It’s also very common for those to be built in as “subfolders” like this “/Account/123456/”. Either way, it’s easily visible, modifiable information presented directly to the user.

As I am sure most of you can predict, I am going to point out that I’ve seen some code that didn’t do the proper protection to make sure that only an allowed user can access any given AccountId. The site will only display the links to the allowed accounts, but the site itself does not protect against a user changing that AccountId.

If you want to get to another user’s account, you can just type in another AccountId into the URL and the site will take you there…

The circumstances where these mostly come up is when 1 user account is allowed to have access to more than one account. It’s on these sites that the user will need to be able to change accounts, and sometimes users keep multiple accounts open at the same time, so the URL is needed to keep both open at the same time. It’s important, however, that we maintain at least some level of security here.

The Better

When we build sites, it’s extremely important that we validate inputs given by users to make sure that they’re valid. It’s also important to make sure that users have access to the information they’re requesting.

The first thing you do when you receive user input is to validate that input. Obviously if you consider a URL to be user input, you would validate that immediately as well. This means that either directly or through some layer of abstraction, your code should be verifying a user has access to any information being requested.

Citigroup

There was a big fiasco last year related to Citigroup. (http://www.nytimes.com/2011/06/14/technology/14security.html) The rumor is that they had a security breach based on this type of issue. I have no real, credible information about this, but it makes for a good example even if it’s only rumor.

From the New York Times article we get these:

Once inside, they leapfrogged between the accounts of different Citi customers by inserting vari-ous account numbers into a string of text located in the browser’s address bar.

That sure sounds to me like what I just described. If it is what I described, then this security expert stretched the truth quite a bit based on what is in that same article.

One security expert familiar with the investigation wondered how the hackers could have known to breach security by focusing on the vulnerability in the browser. “It would have been hard to prepare for this type of vulnerability,” he said. The security expert insisted on anonymity because the inquiry was at an early stage.

It’s not hard to prepare for that kind of vulnerability. I guess if you have it, it’s hard to track and log the issue. What’s easy is not having the issue to begin with. It’s a simple policy of making sure that all inputs are validated for permissions before being executed. Also, that is not a “vulnerability in the browser”.

More Code Audit Nuggets

Keep watching for more interesting nuggets of stuff that I’ve seen in codebases.