Security Patches and Rails 2.3.11/3.0.4

The release of Rails 2.3.11 and 3.0.4 included a critical security fix for a CSRF protection bypass vulnerability. It's great that this was caught and, other than a couple things which I'll explain in a moment, I think it's being handled very well.

This release, however, highlights a flaw in the release process with regard to security fixes, one which I think it fairly easy to fix. The release that seemed like merely a security fix to many also possibly includes some bugs. This could prevent those on 3.0.3 (or earlier) from upgrading to 3.0.4:

http://groups.google.com/group/rubyonrails-core/browse_thread/thread/f013d01fa561abe5

Other issues arise, however, if you're on a version well before the latest release. We have an application on Rails 2.3.5 still and we were tasked with figuring out how to apply this security fix to the application without the pain of upgrading to 2.3.11. Other than this security fix, we don't have a reason to upgrade just yet.

"Just apply the patch," you might say. While this patch is handy, it assumes a vendored rails that you are comfortable with modifying in this. For example, suppose you need to upgrade from 2.3.5 to 2.3.7 and you re-vendor. Make sure you apply that patch again! And suppose you avoid vendoring rails as I, and likely many others, am in the practice of doing, how are you to apply this patch? It's obvious, right? Just monkey-patch the appropriate methods in rails.

Except, since the code to monkey-patch isn't provided in a centralized way (like, oh, say the REXML vulnerability in 2008:

), the labor of this task has been multiplied to everyone in a similar situation to the one I find myself in.

So, I submit this code to you. The tests work on Rails 2.3.5 - 2.3.10:

https://gist.github.com/818691

I'd encourage anyone who's using rails 3 and is in a similar situation to provide the same.

All that and I forgot to mention that the flaw in the release process was that this wasn't provided along with the patches. I propose that security releases in the future include a file to monkey-patch the fix into a reasonable number of previous patch releases. Maybe for releases back to patch 0 of the current minor release?

1) I agree with the commented flaw in this release. Next time, we should do a security release from the previous tag, this is even easier because we won't need to release a RC.

2) In any case, we have released an RC that reduces the changes of having regressions. The e-mail you pointed is not really a regression, but the result of fixing an html safety issue in Rails.

3) I disagree that Rails Core should provide monkey patches for security releases, except the cases it is the only option. Rails provides the ability to be vendored exactly so you can apply important patches, like the ones in security releases. If someone wishes for a reason completely external to Rails to not vendor it, we cannot and should not be responsible to support it. This also applies for those who decidedly do not upgrade their Rails versions when tiny versions are released. We cannot and should not support all Rails versions released.

As you already said, there is *a lot* of effort in doing a Rails Security Release. We provide patches not only for 3.0.x, but also 2.1.x, 2.2.x and 2.3.x. Asking for monkey patches because a small niche prefers to not vendor or update their Rails versions is missing the big picture and the amount of effort that is already put into a security release.

Finally, I appreciate your effort on proposing suggestions to the release process. I also want to thank Koz for doing those extremely important security releases.

1) I have a hard time believing that the majority of shops upgrade every when every patch release comes out despite not being affected by a bug, not getting a desirable feature, or not having a security issue. I do not think we're a niche at all. Certainly if there's a compelling reason to upgrade, I upgrade.

2) The patch provided by rails core doesn't work on 2.3.2-2.3.4 due to form_authenticity_param being missing and doesn't work on 2.3.5 due to the lack of the html_safe method. Applying the patch to vendored rails, in this case, would have resulted in a broken app (which even if fixed may not work as expected).

Which versions of rails are considered supported with regard to security fixes, then? That's a compelling reason to upgrade with every patch release.

Also, it would be great to include which versions are supported on the security page: Ruby on Rails — Security

The tags on 3-0-stable, 2-3-stable, 2-2-stable and 2-1-stable are currently patched when there is a security release. This means the latest tiny versions of these branches are the ones supported when there is a security release. It is always recommended to stay up-to- date to the latest tiny version in your minor release.

It is likely that when 3.1 is released, we will drop support to 2.2.x and 2.1.x versions.

  1. The patch provided by rails core doesn’t work on 2.3.2-2.3.4 due to

form_authenticity_param being missing and doesn’t work on 2.3.5 due to

the lack of the html_safe method. Applying the patch to vendored

rails, in this case, would have resulted in a broken app (which even

if fixed may not work as expected).

I think you’re misunderstanding what the last number in 2.3.2, 2.3.4 etc. means. And everyone is using the word “version” to mean two different things here.

Which versions of rails are considered supported with regard to

security fixes, then? That’s a compelling reason to upgrade with every

patch release.

Yes it is.

The versions of Rails supported are 2.3 and 3.0 (although José says 2.1 and 2.2 as well) - which is why both had a patch release with the security patches. In the proper sense of the word, “upper-case V” Version if you like, 2.3.5 is not a version of Rails, it’s patch release 5 of version 2.3.

2 = Major version

  1. = Minor version

5 = Patch number

Cheers,

Jason

Jason, you are actually right. 2-2-stable and 2-1-stable are not supported anymore even though we provided patches for the CSRF fix:

"Please note that only the 2.3.x and 3.0.x series are supported at present. Users of earlier unsupported releases are advised to upgrade as soon as possible as we cannot guarantee continued security fixes indefinitely."

http://groups.google.com/group/rubyonrails-security/browse_thread/thread/2d95a3cc23e03665

So it is likely that we will drop 2-3-stable support once 3.1 is out.

I screwed up and did "Reply to author" instead of "Reply". I fully admit it, I'm a google groups noob. Perhaps Jason will be kind enough to return my post or post it for me? :slight_smile:

Nathan’s message…

From: fowlduck nathan.sutton@gmail.com

Date: Thu, Feb 10, 2011 at 10:55 AM Subject: Re: Security Patches and Rails 2.3.11/3.0.4 To: Jason King jk@handle.it

I think you’re misunderstanding what the last number in 2.3.2, 2.3.4 etc.

means. And everyone is using the word “version” to mean two different

things here.

The versions of Rails supported are 2.3 and 3.0 (although José says 2.1

and 2.2 as well) - which is why both had a patch release with the security

patches. In the proper sense of the word, “upper-case V” Version if you

like, 2.3.5 is not a version of Rails, it’s patch release 5 of version

2.3.

2 = Major version

  1. = Minor version

5 = Patch number

  1. Semantic Versioning calls them versions and it’s part of the

version number.

  1. The post on the new releases disagrees with your usage of the term:

http://weblog.rubyonrails.org/2011/2/8/new-releases-2-3-11-and-3-0-4

  1. http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails

calls what you’re calling “versions,” the 2.3 and 3.0 "release

series." This makes it unclear which patches are supported.

All of that is what I meant when I said “everyone is using the word “version” to mean two different things here”.

  1. On top of it all, rails patch versions often introduce backwards

incompatible changes, so they’re closer to minor versions than

patches.

Agreed, the Rails project doesn’t always attain perfection. The aim though is to make patch releases backwardly compatible.

So if you want to get into semantics, I think it’s clear that they’re

versions or at least called versions. The treatment of them as simple

patches that are trivial to upgrade (meaning no changes to your app)

is unfounded.

For the most part, and (more importantly) barring unintentional bugs, this is precisely the intention of patch releases.

Anyway, what are you suggesting? To maintain a security patch release on top of each of the releases? That will just shift the problem to the next level - ie. there’ll still be people who want the 2.3.5.2 patch but don’t want 2.3.5.1 because it breaks something they rely on (less likely than now, yes, but impossible to eliminate altogether). People will still need to resort to just pulling the patch and applying it to a vendored Rails.

Rather than getting mired in some semantic argument about versions versus patches, I'll just outline the security policy (and update the website once I figure out how to log in).

We support the current release branch (3-0-stable) for bugfixes and the release branch before that (2-3-stable) for severe bug fixes and security issues. *all other branches* are unsupported.

Now in reality it's often quite straightforward for us to backport security fixes to 2-2-stable and 2-1-stable so depending on the severity and the work involved, I'll usually do that. However that's a 'best effort' thing, there's absolutely no promises there. Once 3.1 ships officially we wouldn't be supporting 2-3-stable, however given the magnitude of the upgrade I'll personally commit to keeping 2-3-stable support throughout the 3.1 lifetime. If I'm hit by a bus though, that may not be something the others can do.

What this means is that you should always be running the latest point release of your release series, for 2.3 users that means you should be on 2.3.11. I realise that sometimes we fuck up a release or ... 4... and it can be a bit of a rough ride, however 2.3.11 should have finally resolved all the backwards incompatible changes we were notified about.

I don't want to sound like a matyr but to put things in perspective, those two security releases took about 60 hours of my time. backporting the patches, verifying the fixes, making sure other versions weren't affected etc. Doing that for every point release in a support series is infeasible.

If there's something blocking you from running 2.3.11 please make sure there's a lighthouse ticket describing it so we can fix it. Otherwise you'll be stuck backporting your own patches.

All of that is what I meant when I said "everyone is using the word "version" to mean two different things here".

Then you said I was using it wrong, which isn't the case.

Agreed, the Rails project doesn't always attain perfection. The aim though is to make patch releases backwardly compatible.

Sure, but that's not the problem, it's 1) treating patches as trivial to upgrade and 2) not being clear as to which version or patch is supported by security releases.

For the most part, and (more importantly) barring unintentional bugs, this is precisely the intention of patch releases.

Intention vs reality. Brian Cardarella's blog post is apt: http://bcardarella.com/post/628870702/a-cry-for-standardized-versioning-in-ruby-pretty

This is all an aside, of course.

Anyway, what are you suggesting? To maintain a security patch release on top of each of the releases? That will just shift the problem to the next level - ie. there'll *still* be people who want the 2.3.5.2 patch but don't want 2.3.5.1 because it breaks something they rely on (less likely than now, yes, but impossible to eliminate altogether). People will still need to resort to just pulling the patch and applying it to a vendored Rails.

Right now all I'm suggesting, if monkey-patches aren't provided for those who aren't at the latest patch level, is that the version that will be supported with security patches should be made clear.

Before this I didn't have a reason to upgrade patch versions unless a bug affected me. If only the latest patch is supported, then I do.

Before this I didn't have a reason to upgrade patch versions unless a bug affected me. If only the latest patch is supported, then I do.

This has always been the case. we have *never* released bug fixes for specific earlier versions. You should basically always upgrade unless you have a reason not to, and your reason had better be a good one :slight_smile:

Rather than getting mired in some semantic argument about versions versus patches, I'll just outline the security policy (and update the website once I figure out how to log in).

We support the current release branch (3-0-stable) for bugfixes and the release branch before that (2-3-stable) for severe bug fixes and security issues. *all other branches* are unsupported.

The current release branch maps to the latest tag? Or what?

Now in reality it's often quite straightforward for us to backport security fixes to 2-2-stable and 2-1-stable so depending on the severity and the work involved, I'll usually do that. However that's a 'best effort' thing, there's absolutely no promises there. Once 3.1 ships officially we wouldn't be supporting 2-3-stable, however given the magnitude of the upgrade I'll personally commit to keeping 2-3-stable support throughout the 3.1 lifetime. If I'm hit by a bus though, that may not be something the others can do.

That's awesome, I really appreciate it. Upgrading to 3 is on the list, but our app is huge. :slight_smile:

What this means is that you should always be running the latest point release of your release series, for 2.3 users that means you should be on 2.3.11. I realise that sometimes we fuck up a release or ... 4... and it can be a bit of a rough ride, however 2.3.11 should have finally resolved all the backwards incompatible changes we were notified about.

Cool, glad this is clear.

I don't want to sound like a matyr but to put things in perspective, those two security releases took about 60 hours of my time. backporting the patches, verifying the fixes, making sure other versions weren't affected etc. Doing that for every point release in a support series is infeasible.

I didn't realize it took that long, ouch.

If there's something blocking you from running 2.3.11 please make sure there's a lighthouse ticket describing it so we can fix it. Otherwise you'll be stuck backporting your own patches.

I started a branch and am working on it. I'll be sure to report anything I find.

This has always been the case. we have *never* released bug fixes for specific earlier versions. You should basically always upgrade unless you have a reason not to, and your reason had better be a good one :slight_smile:

The only one that was for earlier versions that jumped out at me at the time of writing this was the REXML bug, but I realized that this was actually a ruby bug, not a rails bug, so it's a bad example. Actually looking back through the releases, now, and I realize you're correct.

We'll definitely upgrade patch versions from now on....or wait a few days, and then upgrade. :wink:

The only one that was for earlier versions that jumped out at me at the time of writing this was the REXML bug, but I realized that this was actually a ruby bug, not a rails bug, so it's a bad example. Actually looking back through the releases, now, and I realize you're correct.

Right, in that case people needed to wait for upstream packagers etc, and the monkeypatch was like 5 lines :wink:

We'll definitely upgrade patch versions from now on....or wait a few days, and then upgrade. :wink:

Even better, track 2-3-stable and 3-0-stable with your app and let us know when we break something :slight_smile:

Even better, track 2-3-stable and 3-0-stable with your app and let us know when we break something :slight_smile:

Ha, well, I'm sure our users who depend on us would appreciate that. :wink: