cgi.rb vulnerability hotfix

I’ve constructed a hotfix for the cgi.rb vulnerability of yesterday.

what’s fixed?

Fixes an exploitable bug in CGI multipart parsing which affects Ruby <= 1.8.5 when multipart boundary attribute contains a non-halting regular expression string. The boundary searcher in the CGI module does not properly escape the user-supplied parameter and will execute arbitrary regular expressions. The fix adds escaping for the user data.

See the included test to see how the vulnerability works.

This is fix is cumulative with previous CGI multipart vulnerability fixes; see version 1.0.0 of the gem by Zed Shaw.

scope

  • Affected: standalone CGI, Mongrel, WEBrick
  • Unaffected: FastCGI
  • Unknown: mod_ruby

resources

Official vulnerability announcement, my original post, and this post.

license

Licensed under the same license as Ruby itself. Software contains the work of others.

rails affected by new cgi.rb vulnerability

Another denial-of-service vulnerability has been discovered in cgi.rb’s multipart mime parsing. You can read Zed’s message about it here. The diff is here.

update

I have an exploit, and will disclose it tomorrow. Basically, the multipart boundary attribute is inserted directly into the regular expression that parses the message contents. This means you can use a regular expression sequence that will cause an infinite loop, via a POST request.

Regular expressions in practice do not always halt, because of look-behinds and other features like that.

scope of the problem

As far as I can tell, this does not affect mongrel itself unless you specifically use cgi.rb’s multipart mime parsing in your mongrel handler. Camping does not use cgi.rb at all.

Rails, however, uses it. Rails on mongrel can be bogged down by a series of malicious requests, and Rails on webrick can be completely halted by a single one. Tests suggest that fastcgi is not affected.

You can read more about the multipart boundary parameter in RFC 2388.

polymorphs 19

Third time’s the charm. Thanks to Xardion and Agile’s efforts, more bugs were discovered in double polymorphism. But new tests that failed now work, so I think it is safe to say that the feature is complete.

api change

There is a tiny API change if you use the :rename_individual_collections option. For example:

class Dog < ActiveRecord::Base
  has_many_polymorphs :bones,
      :from => [:real, :rawhide, :rubber],
      :rename_individual_collections => true
end 

The parents (dogs) can now be accessed from the children (bones) via .dogs_of_bones. This is to avoid a conflict with .bones_dogs, which is the default name for the join records themselves.

new debugging facility

If you glance at the beginning of the lib/has_many_polymorphs.rb source, you will see instructions for making the plugin generate real Ruby code explaining all of the ActiveRecord relationships set up. This is for debugging purposes.

You can’t use the code directly because it doesn’t include any of the special methods defined here and there. But it’s great for understanding what has_many_polymorphs is doing to your model relationships.

Or, you can use it just to see what a ridiculous number of associations have to get set up to make everything work. The test fixtures generate 68 ActiveRecord associations (as well as 16 plugin associations).

has_many_polymorphs bugfix release

Get version 18 from the usual place.

update

Now also fixed a bug where doubly polymorphic parents weren’t being strict about which children they returned (thanks to Xardion and Agile for the discovery).

what’s changed

  • now supports legacy primary key names (thanks Paul Wright)
  • fixes a bug related to instantiating attributes of namespaced models
  • fixes a bug that prevented doubly-polymorphic children from accessing their parents sometimes
  • fixes a very obscure bug when running on sqlite3 (specifically, this)

Now it has no more bugs. You may uncross your fingers. Thanks goes to Hildolfur for putting the plugin through the wringer and revealing the last three problems.

inline rescue vs. respond_to? cage fight

Which is faster? Inline rescue, or classic branching based on the respond_to? method? Let’s face them off.

ding

Download this, then run like so:

$ ruby test_rescue.rb success respond_to
0.947819 seconds
$ ruby test_rescue.rb success rescue
0.575646 seconds
$ ruby test_rescue.rb failure respond_to
0.789487 seconds
$ ruby test_rescue.rb failure rescue
16.1751 seconds

This suggests that a clean rescue path is about twice as fast as a successful respond_to? condition. But a raised rescue is 20 times slower than a failed respond_to?.

a champion! sort of

Excusing my slipshod math and neglect of all other relevant factors, this means that in time-critical code paths we should use respond_to? unless the path is predicted to fail less than 2.5% of the time. So it depends.

easily stop double posts

You have a comment form. Someone clicks twice. Oh noes! Double post!

think first

What’s the real problem with double posting? It’s not that the user clicked “submit” several times. The problem is that we have a duplicate record in our database. So instead of fixing this at the view level, we can solve it at the model level in a one-line validation:

class Comment < ActiveRecord::Base
  belongs_to :post
  validates_uniqueness_of :body, :scope => [:post_id, :name]
end

scope

The above validation acts exactly like a multicolumn database constraint. The order of the fields doesn’t matter, because what gets checked is the uniqueness of the combination of fields (:body, :post_id, and :name). So if someone wants to comment “cool!” on every post, they can do it, but they can’t comment “cool!” twice on the same post.

Scoping is all the rage right now. But uniqueness scoping is not really related.

show me show me

This solution is implemented here, on Snax. Also, we rolled it into Chow not too long ago. I work on Chow these days. It’s sweet.

directed double-polymorphic associations

In a frenzy of Bluetooth-enabled coding from the local diner, I have implemented double polymorphic associations in the has_many_polymorphs plugin. This lets you create a multi-class directed graph in ActiveRecord with great ease.

show, don’t tell

For example, say we wanted to model glue. We want to be able to glue PopsicleSticks and Leaves to themselves, but also to Paper. We will make a join model called Adhesion for this:

example
class Adhesion < ActiveRecord::Base
  belongs_to :glue_receiver, :polymorphic => true
  belongs_to :glue_applier, :polymorphic => true

  acts_as_double_polymorphic_join :glue_receivers =>
        [:popsicle_sticks, :leaves, :papers],
                                  :glue_appliers =>
        [:popsicle_sticks, :leaves]
end

This means that a PopsicleStick will have a glue_receivers polymorphic collection that can accept anything in the :glue_receivers list, above. A Paper, though, will not have a .glue_receivers method. It will have a .glue_appliers method, but it is not itself a :glue_applier. This is tricky. Just remember that the lists in the acts_as call are the types of children for that relationship, not the types of parents.

Also, using the individual typed collections (e.g. PopsicleStick#leaves) will always get you the children that belong to the record, instead of the parents that own the record. In this case it will fetch the Leaves from a PopsicleStick object’s .glue_receivers.

warning! class-reloading laser in use!

The API is a little different because there is no parent class that can act as a controller. Things are instead centralized in the join model.

This means that you have to reference the join class (either with load(), by evaluating its bare class name, or another way) before the associations will be injected into the “real” classes. Rails’ selective reloading in the development environment can lead to trouble—a modified class will get reloaded and forget its relationship to the join. Keep this in mind.

crazy clown collections

Combining this with the other plugin features leads to controlled chaos. Self-referential directed double-polymorphic namespaced STI associations are (at least according to my tests) fully supported.

Please try it out and let me know if you have trouble. I really appreciate the filing of bugs.

namespaced model support in has_many_polymorphs

Release 16 of the has_many_polymorphs plugin is out. It adds support for namespaced models (by special request), and fixes a Postgres bug.

example
class Scents::Bacon < ActiveRecord::Base
  has_many_polymorphs :sniffers,
                      :from => [:dogs, :"forest_animals/hedgehogs"],
                      :through => "actions/sniffings"
                      # (join model is Actions::Sniffing)
end

Please let me know if you have any problems. I am a great expert on namespaced models in Rails now. It’s not always pretty. However, it’s not as bad as they say.

mongrel denial of service vulnerability

There is a denial of service vulnerability for Ruby applications that either use cgi.rb, or run on Mongrel or Litespeed. This means that Rails is affected. The fix is described below.

problem

Zed Shaw makes a full report here, explaining that:

…there has been an exploitable bug in the Ruby CGI library named cgi.rb, which allows anyone on the internet to send a single HTTP request to any Ruby program (not just Mongrel) using cgi.rb multipart parsing with a malformed MIME body that causes the Ruby process to go into a 99% CPU infinite loop, killing it.

fix

The quickest fix is to update your mongrel version. You have to use --source, though, because 0.3.14 isn’t in the main repository yet:

sudo gem install mongrel --source=http://mongrel.rubyforge.org/releases

Be warned. This gem breaks relative paths in X-Sendfile headers with Apache 2.2 (and possibly others). Use File.expand_path() to convert to absolute before you set the header.

more information

See the mailing list message for alternative fixes if you don’t use mongrel or if upgrading the mongrel gem is not an option for you.

Thanks to cdcarter for the tip.

grand tour of the 13 railsday winners

Railsday 2006 results are out, at long last. The winning applications are impressive, and especially, very fun. There’s no universal demo server though so unless you go to quite a bit of work, you can’t see what the winning projects actually are like.

best solo project: rails wishlist

Rails Wishlist is a sort of a social feature-requester for Rails itself, by Hampton Catlin. It lets users vote up or down, Digg-style, on proposals for changes in Rails core.

front page

This entry is very interesting because it’s one of the few whose success wasn’t driven by the quality of its design; it was carried mainly by its features (I assume).

vote dropdown

request details

third prize, most useful: profilr

Profilr is a sort of account aggregator for your information-sharing sites, by Terence Haddock and Mark Chadwick. Unfortunately I couldn’t get it to work very well.

login

set up some of your accounts

get ready, go

loading… something

I never managed to get the application past this point. I don’t know if the accounts are disabled, or the sites are changed, or what. It tries to use Selenium to automate browsing and collect the relevant information.

second prize, most useful: regex tutor

Regex Tutor gives you a live environment in which to solve regular expression problems. Regex Tutor is by Ryan Bates.

Actually, this application was really fun and I wish there had been more fixtures. It has the constrained environment and instant gratification of a good puzzle game, while leading you lessons about different aspects regular expression.

get ready

level one

You have to make the input set on the left turn into the output set on the right. In the middle the results of your current attempt are updated automatically as you edit it.

whoops

if you need help

The application includes glossary and FAQ infrastructure so that it can be fleshed out into a comprehensive teaching tool.

This is my personal favorite of all the winners. Excellent functional use of Ajax.

first prize, most useful: heartbeat

Heartbeat is a server monitor. It combines an internal tool like Monit with an external uptime checker like Montastic. Heartbeat is by Charles Brian Quinn and Derek Haynes.

login

setup your servers

It connects via SSH to monitor process status.

keep an eye on your apps

third prize, best interface: c.umul.us

C.umul.us (make sure I got all the dots) generates a public view onto your iTunes collection. C.umul.us is written by Jae Hess. You upload your iTunes .xml library file. The interface is adorable and solid. Unfortunately when Railsday ended it didn’t do more than display a tag cloud of your genres and artists.

who? what?

The small cloud in the background floats around via sneaky Javascript breezes.

upload

glory in your unique and impeccable taste

Those are fixtures, not my real artists. I declined to try uploading my personal database of 25,000 songs.

But those little trees are so cute…

second prize, best interface: d20 online

D20 is a tool for keeping track of your card-based roll-playing games, by Tom Leiber, Jeff Mickey and Javier Cabrera. I don’t know anything about card-based roll-playing games so I have to keep quiet on this one. People can participate remotely in real time. Only having one of me, and not really knowing what I should be doing, I had a hard time testing that out.

ready to rumble?

create my character

participate in a game

The FAQ will help you out.

first prize, user interface: we rate stuff

We Rate Stuff is a product and service review database, although I guess you could review like your dog or something too if you wanted to. We Rate Stuff is by Frederico Oliveira, Tiago Macedo and Pedro Eduardo Lemos Freitas, who give it infinite stars (out of five).

We Rate Stuff includes full-text search via ferret, but I couldn’t get it to work.

home page

We Rate Stuff is full of beautiful fixtures and it really makes the application seem polished.

how was that latin concert, then?

or that “ruby tracks” thing

third prize, most creative: roomind.us

Roomind.us is an expense tracker and reminder sender for apartment mates. Hopefully it did not spring from a disagreement between Dominic Damian, Ben Myles and Chris Abad.

home page

pony’s gotta eat

let’s review

someone’s been slacking off

second prize, most creative: family book

Family Book is the little seed of a future comprehensive family networking site, by Lucas Carlson and John Butler. It lets you create a family-tree-like view onto your relatives, track their details, and spam your whole extended family whenever the annual reunion is coming up.

home page

The “lexical parser” bit refers to being able to type sentences like “My mother is Mom and her birthday is 10/3/1982” and have it add a node on the family tree for her. I typed “My daughter is a baby” and after that nothing showed up, so I stuck to the examples from then on. It was only one day, after all.

graph view

The graph is all in Flash. The suggestions at the bottom are slightly alarming, but do get the point across.

first prize, most creative: the awesome ninja game

The Awesome Ninja Game is a game, where you have this ninja, and he does ninja stuff. It was created by Tobias Lutke, Cody, and Daniel while they were standing in the sun. Seriously. Nobody saw it coming.

It seems like you can have your character fight with other people’s characters, just like Digg or Slashdot.

create our fierce ninja

choose moves

I don’t know the differences between them, but there are a lot to choose from.

good ninjas keep a schedule

Turns go by, and the ninjas fight, or study, or do whatever you set. Results are returned as text descriptions in the blank field to the left of the schedule, creating a little Zork-style history of your ninja’s activities.

oh, who’s the best, that’s right

This application was one of the really fun ones.

third prize overall: cuppin’

Cuppin’, which has become a real place, is a social site and review hub for coffee lovers. Peat Bakke and Raymond Brigleb are its highly-caffeinated creators. This really impressed me mainly because it’s something I would actually use, and all of the advertised features are fully implemented.

home page

i remember that one

what the faq

who’s been talking

coffee-related events

Mmmmmm. Catastrophy doesn’t sound good, though. Somebody probably ground the beans ahead of time, or maybe they were frozen (the horror!).

second prize overall: good to garden

Good to Garden is a garden simulator. Will Emigh and Rory Starks must have played a lot of Harvest Moon. I don’t think Good to Garden would be a good place to try out your growing strategies before hitting the dirt. It’s more like a vegetable Tamagotchi.

home page

i’m just testing, man; it’s really ok

the princess is in another castle?

I don’t know why this came up, but it did.

springtime

our little friend

harvest day

I’ll make some carrot cake to go with my coffee.

first prize overall: freckle

Freckle is a wedding planner, by Amy Hoy and Bryan Wood. I don’t know if they’re married or not; you’ll have to direct your inquiries elsewhere. Freckle leads you through the steps of orchestrating the big day. The app is solid although I did run into “Application error/Rails” here and there.

almost the most importantest

design your invitations? sort of

lots to do

hire people

guests

wrapping up

Many of the applications that won are basically CRUD (Cuppin’ and Freckle included). Good design seemed to carry the day. I didn’t see any really ugly apps with awesome ideas, or notice slick code tricks among the winners. This vaguely disappointed me. Ideas are hard to come by, though, and good code is certainly harder to evaluate than good design. Seriously, though, all the winners are more than worthy.

here, take this unsolicited advice

One thing all the winners did have in common was great migrations and (usually) good fixtures. I tried installing some of the non-winning applications randomly. I couldn’t get most of the ones I tried to even start properly due to bad migrations, database incompatibilities, or dependency issues. So here is what I will be keeping in mind for next year, if I compete:

  • Make it work out of the box. Consider sqlite3 for your database.
  • Have fun and interesting fixtures.
  • Think of your idea and sketch out a visual design on paper before hand.
  • Better to leave something out than expose an application error.
  • Have a good teammate with skills complimentary to your own. There’s a reason the winning apps were almost all by teams.
  • Go for plain old CRUD if in doubt. It’s the heart of Rails, after all.