Let’s all take a breath for a moment, shall we?



There. Now let’s take a look at the recent activity we saw on Twitter over the weekend into Monday. There were two distinct, very likely related events.


The Phish

On Saturday, Twitter was hit with a phishing attack. While the events surrounding that have been widely documented, there was an undercurrent of discussion from developers of third-party Twitter applications claiming that this was exactly why Twitter needed to implement OAuth. With the sale of a Twitter application that had been around for one day and accumulated approximately 1,000 accounts, speculation was high that this phishing attack was a direct result of developers being “forced” to request user credentials to build their Twitter apps.

There are a couple things to address here. First is that OAuth is most definitely not a web application silver bullet and would not have prevented the phishing attack that occurred.


Plain and simple.


OAuth provides a secure manner for interacting with an application’s API. Phishing is an attempt to retrieve valid user credentials by spoofing or forging the target site. While Twitter users are admittedly lackadaisical with their account credentials (as seen with a test I performed earlier this year on a site called TwitterAwesomeness), the fact is that this attack occurred because somebody created a legitimate looking Twitter login page and some users fell susceptible to the spoof.

For those looking for more details, there was some good discussion on the Twitter Development mailing list if you can wade through the various misconceptions. Chris Messina actually has a fantastic blog post on password usage and Twitter. Unfortunately, there is still the misconception that OAuth would have fixed this and prevented the worm from propagating. To address that - any application can spoof the Twitter home page. Once those credentials have been obtained, the attackers can automate the Twitter website in a variety of ways.

While I agree that the pattern of password usage needs to change on Twitter, restricting application access is a different battle from educating users on preventing themselves from being victims of phishing attacks. Not to mention that chances are high that a web application vulnerability such as SQL Injection exists within the numerous third-party web applications that accept Twitter usernames and passwords. Ultimately, however, OAuth will be beneficial in locking down Twitter from an API and third-party application perspective.


The Hack

On Monday morning, there was a post indicating Twitter had been “hacked” and several high-profile accounts had been compromised and used to post fake updates. This is more of an operational issue, but may have been indirectly related to the ongoing phishing attacks if a staff member had been phished. Based on the Twitter blog post, it would appear as if the admin tools utilized by Twitter support staff are available externally and may even share Twitter account information. From a security operations point of view, this is a recipe for disaster. If possible, administrative functions should be logically separated from user activity. Twitter is rather fortunate this happened at the same time and that the attackers didn’t have more malicious or damaging ideas in mind.

This prank is simply the tip of the iceberg. While Twitter may be able to secure the admin tools, the site will continue to grow and the phishing attacks will continue to advance to take advantage of how Twitter is used. How so? Well many Twitter-folk utilize automatic-follow techniques so they don’t have to manage it. This means immediate acceptance into a larger network, even more so if you have somebody reply to you. Further, “re-tweeting” is a popular concept on Twitter to share links. Finally, any URL over 30 characters is automatically shortened by Twitter and many users do so manually or utilize client applications further obfuscating the destination site.


A Little Perspective

I urge those people pushing so hard for strong account controls on Twitter, to also direct their resources and energy towards more critical assets. With the estimated Internet population at nearly 1.5 billion people, Twitter’s population accounts for a minuscule fraction of that. Wells Fargo has 48 million customers. Bank of America employed 206,587 people in 2008. Based on my Twitter stats service that records analysis of every update on Twitter, there were 358,691 distinct users that posted tweets on January 5 of this year. I would love to see more critical assets such as banks implement more secure authentication methods as well, and those user populations are even larger and more critical than our favorite micro-blogging site.


Update: Seems it was an unrelated brute-force attempt that compromised Twitter’s Admin tools. Interestingly enough, I’ve seen this functionality other places and noticed when I had a support ticket that the username was the same. It seems my hope that the systems were somehow logically separated was not to be realized. Oh, Twitter.

There were two failings here, which is why layered security is beneficial.

  1. A weak password was being used for a highly-privileged account
  2. The administrative tools were exposed in such a way that an external attacker could continually attempt passwords and not be automatically locked out or noticed

Yes. It is just a micro-blogging site. But when the President-elect is relying on it to get his message out and people are staking their reputations and businesses on it…it suddenly becomes more.

I fully believe that Twitter does realize this and we know they are working to address some of the more pressing issues. Yes it’s taking a “long time” and we can criticize all we want, but who’s really at fault here - Twitter for not prioritizing the security of what was originally conceived to be an offline AIM status service, or the developers for propagating what they knew was an inherently insecure method of authentication with only the dollar signs of success in their eyes. In my opinion, why bother throwing blame. Let’s work together towards building a more secure web 3.0.


</soapbox>

I want to briefly touch again on PCI and payment applications, as I keep getting scared out of my security hat. There’s a fantastic tech startup group in Seattle and somebody recently asked about processing credit cards on the mailing list. One of the commenters pointed to the Rails ActiveMerchant plugin, which can be used to access payment gateways such as Authorize.NET, Paypal, and over 30 others. The following piece of code, found on the ActiveMerchant page, is what rang some bells in my head when I saw it.

# Create a new credit card object
credit_card = ActiveMerchant::Billing::CreditCard.new(
  :number     => '4111111111111111',
  :month      => '8',
  :year       => '2009',
  :first_name => 'Tobias',
  :last_name  => 'Luetke',
  :verification_value  => '123'
)

if credit_card.valid?

  # Create a gateway object to the TrustCommerce service
  gateway = ActiveMerchant::Billing::TrustCommerceGateway.new(
    :login    => 'TestMerchant',
    :password => 'password'
  )

  # Authorize for $10 dollars (1000 cents)
  response = gateway.authorize(1000, credit_card)

While ActiveMerchant itself is not a risk, I simply want to reiterate how you use the library is very important when it comes to handling credit cards. This code, if used in the manner above, puts your web server in scope for PCI compliance even if you are never writing the credit card number to disk. While you should be doing nearly everything in the PCI standard anyway in order to properly protect your assets, PCI can be a tricky field to navigate. I’ve said it before and I’ll say it again: if you want to avoid the complexity of introducing PCI compliance into your environment, do not store, process, or transmit a credit card number and use an offsite payment gateway instead.

If you have further questions about this, feel free to leave a comment, contact me (damon at startupsecurity.info), or visit PCI Answers for anything and everything related to PCI including contact information for one of the most knowledgeable PCI resources around, Mike Dahn.

Writing Good Code

What is good code?

One of the challenges for any developer, security notwithstanding, is writing good code. Although “good code” is a bit of a nebulous term, it can consist of proper documentation, a lack of duplication, clean code and code that does exactly what it is intended to do, and nothing else. Failing to achieve that last item is what tends to lead to so many security bugs.


What is bad code?

Writing good code is also essential when it comes to security. As a part-time coder myself, I know it’s difficult to stay in a security mindset when you’re solely focused on getting a certain piece of functionality to work. Often times you might hear yourself uttering things like “well I’ll just do this for now” or “this is such a hack, it will probably never work”. This is exactly the point at which the slippery slope to sloppy coding begins, and commonly ends with code that was not necessarily intended for production…but will probably make it there anyway.


What should I watch out for?

As a developer with the paranoid security hat on, I have the following couple tips. If you find yourself going down this path, make a note to add a #TODO security task for yourself to go back and review the code that you’re writing. Further, don’t forget security when you’re wandering down the path of hacky code. While it may be the slickest thing you’ve written in the past week, hacks are exactly that - and breaks in logic may be a trade-off in security. These type of bugs fall into the “design flaw” category, which are becoming more and more common as issues like SQL Injection are becoming easier to deal with. And it’s not just SQL Injection and XSS to think about. There are other concerns such as authorization, session fixation, replay attacks and cross-site request forgery.

Second, if you do find yourself charting unknown territories and writing some wicked code…get somebody to look over your shoulder. Have a peer review your code both for logic flaws, as well as potential security issues. I’ve been in many situations myself where my mental effort has been focused on the functionality of a specific piece of code and security was the definition of an after-thought. Having somebody else take a look at the code is beneficial both from the “good code” as well as the security perspective.


Are there any tools I can use?

If you’re working on your own, there are a couple sites I know of that allow collaborative peer review. Use those at your own risk, of course and try not to paste intellectual property. ;)

For larger teams where the development environment may not have a built-in code review tool, I saw an impressive presentation at DjangoCon 2008 on an open-source code-review tool called Review Board. It’s built in Django with an MIT license and can be installed on an internal server.

I recently presented at StartPad, a local co-working space in Seattle, on web application security. It was a great talk, mostly due to the great discussion generated by the crowd. StartPad was nice enough to record the presentation and you can find that, as well as my slides, below. Topics covered include: web application security, including the basics of SQL Injection and Cross-Site Scripting, Data Breach laws and even some discussion on PCI compliance. I also did some demos including a SQL Injectable Ruby on Rails app. :) Enjoy!

At my presentation last night on web application security, I demo’ed a SQL Injectable Ruby on Rails application.

One of the questions that resulted from that, somewhat in shock, was how long this bug had existed in a public open-source project. Referring back to the original discoverer, it seems this bug has persisted through the lifetime of the Rails project (i.e. Rails 1.2 and 2.0 were vulnerable as well).

Looking back in time, we can actually see the March 2005 commit where the limit functionality was added to the MySQL adapter. If you have javascript enabled, I’ve pulled out the relevant bits below. The interesting thing to notice is that some sanitization is performed if both a limit and offset parameter exist, but if only the limit parameter exists…no sanitization is done.

There is some good discussion about how to exploit this :limit bug on the Ruby on Rails Security Project blog.

Finally, we can see where this SQL Injection was fixed earlier this year. And if you’re curious, here’s what sanitize_limit does.

That being said, I suppose we could enter into the old argument of whether closed or open-source is a more secure model. But realistically, bugs exist in any project - it’s the process and integration of security into that specific project’s development that determine it’s resulting security and risk profile.

I’ve giving a talk tomorrow at a Seattle co-working space, StartPad, about startups and security. You can find more information and register for the event on the StartPad website: Hacking and Compliance in a Web 2.0 World.

If you’re in Seattle and want to learn about web application security, stop on by!

What: StartPad Countdown 2 — Startup Security: Hacking and Compliance in a Web 2.0 World
Who: Damon Cortesi
When: 6:00 pm, Tuesday November 25th, 2008
Where: StartPad offices — 811 First Avenue, Suite 480, Seattle, WA 98104
Cost: Free!

Pizza and drinks will be served.

One of the things any organization should be prepared for is a potential “incident”. The definition of incident can vary widely, but it can be anything from an unauthorized internal data access to a “hacker” breaking in.

Monitoring is a big part of detecting incidents and perhaps a post for another day. If you do suspect somebody has unauthorized access to one of your systems, though, there are certain steps that should be taken. I recently came across a good cheat sheet for server administrators that should be kept handy in the event of an incident. There’s also a cheatsheet for those responding to potential incidents.

I came across these cheatsheets over on the SANS Internet Storm Center blog, a good feed to have in your reader to keep up-to-date on the latest security incidents around the net.

Enjoy, and hopefully you won’t need to reach for these in the near future. But they are good to have on hand!

ZoneAlarm Pro, Free Today

ZoneAlarm Pro, a personal firewall, is free today. Details at zonealarm.com.

Personally, I’m a Mac guy and both OS X and XP/Vista have a firewall built in, but ZoneAlarm does offer some better granularity and access control. When I was a Windows guy, though, my personal favorite was Sunbelt Personal Firewall (formerly Kerio, formerly Tiny). Yes, I am anal retentive enough to restrict my browsers outbound access to ports 80 and 443…

On the Mac, I do like Little Snitch for outbound access control and monitoring.

There’s been quite a bit of discussion recently in the security community regarding partial disclosure due to that DNS bug and the zomg my camera is on bug. What I’d like to do briefly is take a step back and look at the startup community and reporting vulnerability issues to small companies that don’t have the resources and experience of large enterprise. Why? Because they may be the next enterprise, you never know. ;)

Over the course of the past few months, as I’ve been involved with my own startup, I’ve been paying a lot more attention to that industry. With a quick and dirty development model, it’s often easy for devs to overlook security. Although some frameworks address a lot of the usual concerns (SQL Injection, XSS), they are susceptible as well.

Let’s take a look at a couple examples that enterprises such as Microsoft and Google now understand, that small development teams might not.


1. Put an email address on your website.

Yes. I’m serious.

I’ve come across several issues on startup sites recently and being the responsible security researcher that I am, have wanted to report them. Spending a half-hour spidering the site trying to find a single contact email is a lose-lose situation. I’m either going to discard the bug and the site will remain vulnerable, or somebody else will publicly disclose it and the typical ‘hair on fire’ scenario will ensure.


2. Respond to the email.

If you don’t respond, I have no clue if you’re addressing the issue. A timeline for a potential fix might also be nice, but not always necessary.

Additionally, security researchers generally like the cred associated with finding a bug (ego boost and resumé builder, you know?). So if you do make an update and have some release notes, why not thank the researcher for preventing your hair from catching on fire more than it already is?


3. Don’t write off the security guy.

6 years ago, there was a large back-and-forth on a Mozilla bug. This year, it was confirmed as a vulnerability known as clickjacking. That Mozilla thread is a pretty classic example of the security disclosure process. If a security researcher is writing to you to report a vulnerability, engage in conversation to understand the concern. Yes, we do sometimes get a little paranoid. But if we emailed you, we’re really just trying to help.


4. Don’t sue the security guy (aka have a disclosure policy).

One reason that I frequently hold off on reporting bugs I may come across is that I can’t find a disclosure policy on the site. As an example, both eBay and Microsoft allow for easy reporting of security vulnerabilities. Most sites, however, don’t and it has happened in the past where a security report has been misconstrued as “hacking”. Providing some assurance that this sort of action won’t be taken or an easy means to report vulnerabilities will open up the communication channel necessary.

Hopefully these short notes will help small companies become more open and willing to accept security bugs from external researchers. Occasionally, we come across issues in the course of our normal web activity and wish to report them. Having a published and easy means of doing this is important in allowing for this communication.

Far back in the days of GeoCities and Tripod, JavaScript was a cool little scripting language you could use to make some awesome rollovers on your links and take your site to the next level beyond the blink tag. Today, JavaScript drives what many call Web 2.0 - a user experience that has made it possible to put desktop applications (email, office) on the web.

The evolution of JavaScript and its place in security perfectly parallels the transition from server-side security to client-side security.

~History~

Before network firewalls were commonplace, the juiciest targets to go after were servers. In what is now unthinkable, it was common for systems to be deployed directly on the Internet with no firewall whatsoever. This is part of the reason that Code Red, Nimda, and Slammer were so successful. The opposite is true now. Network firewalls are commonplace, Windows XP has the firewall turned on by default, and Server 2008 will be the first Microsoft Server OS to be deployed with the firewall enabled by default. As such, attackers moved on to the next target - client workstations and the primary way users interact on them.

~/History~

So why should you, as a startup, care about all this? Two reasons.

  1. Protect your site from common attacks
  2. Protect yourself from being a victim

To address the first one, there’s a common attack known as Cross-Site Request Forgery. I’ll get into it in more detail in another post, but effectively it allows one site to take action on another if that target site has not put effective controls in place. A common mitigation is ensuring that all data modification methods occur via POST requests (per HTTP standard). However, if you don’t have tokens associated with those POST requests, another site could utilize javascript to craft and submit fake POST requests to take actions on a logged-in users behalf. Does your site have a “remember me” checkbox? Do user sessions not time out? This could be a problem for you. This issue has been widely known for at least four years (Chris Shiflett on CSRF), but it’s only recently been gaining a lot of attention. I’m surprised more frameworks don’t have protection for this enabled by default, but it could likely impact development testing. The general approach to fixing this is by utilizing some sort of server-generated token that’s inserted as a hidden form field and verified on user submittal.

To address the second, an example is necessary. JavaScript, for the most part, is fairly essential to a number of sites that you may visit on a regular basis. The danger however, is malicious JavaScript that may get executed without you even knowing it. That script could be on that site and trying to take action on a different site, or sourced from a remote site altogether. Take, for example, poor David Airey who lost his domain due to a GMail CSRF vulnerability. The basics behind the attack are as such: At one point, David visited a page that had a malicious JavaScript. That script posted back to his GMail account, reconfiguring it so the attacker could hijack emails. That reconfiguration including forwarding and deleting all domain-related emails. Once David went on vacation, the attacker went to work and David lost his domain.

So how can you protect against this second attack? I personally make use of the Firefox extension NoScript. This handy extension prevents JavaScript code from automatically executing when you visit a web page, unless you’ve previously whitelisted that site. While it can be a little annoying, it’s much better than unknown JavaScript executing in the context of my browsers…where I spend a good majority of my day.