ubercart and XSS

Posts: 2
Joined: 06/30/2008

I'm putting together a presentation about Drupal and XSS. I would like to use Ubercart as an example of what we developers need to know.

Between 1.2 and 1.3 Ubercart went through some growing pains that all developers need to know about; if we want our apps to mature.

My basic outline:

* what is XSS
* how to do a XSS
* how to protect from XSS in PHP
* how to protect from XSS in Drupal
* comparison of code from Ubercart 1.2 and 1.3
* lessons learned from Ubercart

some of the resources will include; wikipedia.com, ha.ckers.org, xssed.com

I could use some feed-back from the development team or anybodies else's ideas as to what I should cover.

A writeup on my notes is attached.

AttachmentSize
uc_security_writeup.txt3.33 KB
Posts: 5378
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

Hey Dave, sounds like a good presentation. A lot of the earlier common mistakes are probably there because we needed to attend a couple sessions like yours. Sticking out tongue In any case, I'm glad we've cleaned up a lot since then. That does make me think you should include instructions in the presentation for the correct action to take when you think you've discovered a security vulnerability.

Anyways, responding directly to your points, I did want to advise based on what I read in the code without being too touchy. I understand you're not crying wolf since you're examining code that has changed, but at the same time I think a statement like this - Most of the mistakes opened the system up to Cross-Site-Scripting. - is misleading given the things I'll note below.

Also, I'm not really sure what code you're looking at when you say 1.2 and 1.3. There hasn't been a 1.2 or 1.3 release yet, though we did clean up a lot of the issues you mentioned at various points in the alphas, betas, and maybe release candidates. Are you being intentionally vague for the purpose of users of the older versions? If so, no sweat, I just had to work a little harder to find the original code. Eye-wink

So... "technical review":

  1. Agreed, but you might also check for validation elsewhere. For example, in that case arg(3) is being tested in hook_menu() with is_numeric(). This means you'd have to be able to make an XSS attack out of a number... which as far as I know isn't possible. I'm sure there are other examples where this was actually a security vulnerability.
  2. This is the biggie... even when we knew to be conscious of this, it still slipped through. I think this goes along w/ the watch out for things you're too familiar with advice you had. A second set of eyes always helps. Also, one tip we picked up was to simply test all your forms w/ some HTML in there, like entering First name and seeing if it showed up in italics anywhere.
  3. This is a good general rule, but examining the function in question will show that that variable was NULL... it may have been used to display debug info while testing, but as far as I can see we removed the debug code and simply forgot to remove this variable until a later revision. So... safe. Eye-wink
  4. I can't even find that example, but it would be worth explaining when to use this function instead of just defaulting to check_plain() along with an example for Drupal core.
  5. Agree with the point, but again the example is misleading. In this case, $arg1 is an order object, and we're not printing that... we're printing instead the formatted results of uc_payment_balance() which returns a numeric string w/ a currency code. The data being outputted is quite controlled and never affected by user input.
  6. Agreed. Might be worth mentioning that even literal values in queries should use placeholders to be forward thinking. I'll point out here again that there was other validation in the menu item for this function, too, such that the $uid value passed to the function must match the current user's uid which will always be an integer. Still should use placeholders, though.
  7. Guilty as charged... I actually don't get why the name isn't just passed in as an argument on that URL.

I'm not sure what else you should cover... the kinds of attacks you're on the lookout for are great. You might just make a mention that proper use of the Forms API will protect a site from XSS over forms and $_POSTed information... Also, I'd make it explicit that we're filtering user input when it gets displayed and not when it's being stored. i.e. you don't check_plain a string you're storing in the DB.

Hope that helps, and sorry if I sound overprotective. Just wanna make sure Ubercart gets blamed for actual faults. Smiling I think the main thing is just checking for other types of validation on data that's printed (i.e. type checking, restrictions on input, etc.). In most of the cases you pointed out, I still think the changes and compliance with general security standards were a very good thing, but they weren't the security holes that they were pointed out to be.

Lastly... thanks so much for taking the time to do this write up. I know it took a lot of time to compile, and I don't want to dissuade you with my comments. Let me know if you have any follow up questions and I'll be happy to answer. Cool

Posts: 2
Joined: 06/30/2008

Ryan, Thanks for the reply.

I don't know how the version numbers 1.2 and 1.3 got into my notes. Looking back at the tarballs, I got 1.0 beta6 and 1.0 rc1. The .info files show:

Information added by drupal.org packaging script on 2008-02-25 version = "5.x-1.0-beta6"

and

Information added by drupal.org packaging script on 2008-03-31 version = "5.x-1.0-rc1"

My goal here was to show examples of security flaws so I didn't feel the need to be anile about exactness. I even cut code out when it got in the way of making a clear example. But I was conscious of not exposing any flaws that hadn't been fixed or could be used against up-to-date Ubercart users. Truth be told, I didn't think about installations that weren't up to date and the vagueness wasn't intentional.

Also I didn't want it to look like I'm dissing Ubercart for fixing those flaws. At first I didn't intend this to be anything other than a personal study. I chose Ubercart because it has a big name in the community and I was composing examples of security flaws when I saw the alert.

My sloppy methodology did cause a problem. When I saw the security alert I grabbed a "before and after", ran a DIFF, organized the changes by apparent vulnerability type, and choose the lines where it was easiest to see both the vulnerability and how it was fixed. Only changed lines were looked at, the code was completely out of context, I didn't do any checking for other security measures, and I didn't verify that the changes were really security related. It was not comprehensive to say the least but showing a live example of a flaw was more important than the flawed code itself. I'm sure many little "discrepancies" crept into the result.

Here's the diff output on what I think #4 was:

diff -iwBar ubercart_vuln/payment/uc_payment/uc_payment.module ubercart_not_vuln/payment/uc_payment/uc_payment.module

616c623
< '#value' => ($payment->comment == '') ? '-' : $payment->comment,
> '#value' => ($payment->comment == '') ? '-' : filter_xss_admin($payment->comment),

I was afraid this might sound like I'm trying to blame you or Ubercart for the mistakes. That is why I contacted you first. After putting this together, the LA Drupal users group asked me to do a presentation on secure code and not getting your input in a possibly touchy situation like this didn't sit right. What would you think if you heard about this after I did it?

It's not like I was sitting on a 0-day that an internationally known vendor has been ignoring for several months. It's not like you exposed several Linux distributions to have weak encryption keys for several years. My decision might be different in both of those situations.

As far as I'm concerned, fixing coding errors is like getting a haircut; just because you got one done doesn't mean you were sloppy before. It is a sign of maturing and the rest of us could learn from what your code went through.

Posts: 89
Joined: 09/08/2007
Bug Finder

Dave, Ryan,

I think this write up is great. IMO it should be published after some spelling corrections in Drupal Planet not only in Ubercart. Being able to point at our mistakes isn't something bad, quite the opposite it shows the maturity of the product/ developers.

Posts: 5378
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

Hey Dave, no sweat. I didn't feel like you were dissing Ubercart... we do that enough ourselves. Eye-wink I just thought the points are misleading that point to code that wasn't a security hole and call it one. Providing the disclaimer that code was modified and/or used to illustrate a point but might have been covered elsewhere for security (like in the menus) might be sufficient... but I understand your intentions and don't feel bad about what you're doing.

I'm eager for more code review... word is that there's a code comparison article underway that should expose many of our internal API inconsistencies. It should go a long way toward making our Drupal 6 versions even better and easier to work with. Smiling