First, mass assignment.
The answer to mass-assignment bugs is "attr_accessible". Accessible attributes can be set via update/build/new; nothing else can. Every Rails AR model should have an "attr_accessible" line in it.
I've met smart dev teams working under the misconception that attr_accessible means "these are the attributes that can be changed based on user requests", and so virtually everything is made accessible. No! If something's not attr_accessible, you just set it manually (user.foo = params[:user][:foo]). It's not painful and the extra line expresses something important ("this is a sensitive attribute"). Attributes are inaccessible until they prove themselves mass-assignment-worthy.
Second, the string interpolation in the regex.
Real quick: don't ever let users interpolate arbitrary strings into regular expressions. Regular expression libraries are terribly complicated and not very well tested. To illustrate (but not fully explain) the danger here, run this line of code:
ruby -e "'=XX===============================' =~
Oh, one more thing: I appreciate Patrick's take on systems failures breaking Rails apps before underlying crypto flaws will, but even if they had protected their keys, their crypto wouldn't have worked. Don't build things that require crypto. You aren't going to get it right.
I'd do you one better: use an initializer to monkeypatch ActiveRecord::Base and fire "attr_accessible nil", which will cause mass assignment to fail on any object you create from a class which doesn't make the assignment explicit.
 Obviously large companies with massive Ruby code bases can't really do this. Not sure what to say there.
For your companies' code reopening a class should be a huge flag in code review (something like gerrit should be in place at every large company), but it's not sustainable to police the dependencies of the libraries you use, especially when the default in the Rails community is spray and pray.
@question.safe_update(%w[title body language tags], params[:question])
"Don't let users interpolate, ever" is close to truth. It isn't quite truth, but it's a lot shorter than the truth.
Why does that hang in Ruby? In Perl it's fine...
anchored "X" at 0 floating "X" at 2..2147483647 (checking floating) minlen 3
Guessing start of match in sv for REx "X(.+)+X" against "=XX==============================="
Found floating substr "X" at offset 2...
Contradicts anchored substr "X", trying floating at offset 3...
Did not find floating substr "X"...
Match rejected by optimizer
I wrote an article a while back about the differences between PCRE and Perl's engine: http://use.perl.org/~avar/journal/33585
Regexp engines are subtle beasts, and there's a couple different ways to implement them (DFAs vs NFAs, simple engines vs lots of clever special cases, etc.). See O'Reilly's "Mastering Regular Expressions" for an exhaustive discussion.
You should use a regex engine that's explicitly designed to take potentially hostile input. Like the Plan9 engine, or Google's re2 engine which powers Google Code Search.
You can also just use Ruby's dangerous PCRE engine if you do something like forking off another process with strict ulimits which executes the regex for you. Then you can just kill it if it starts running away with your resources. Look into how e.g. evaluation bots that work on the popular IRC channels on FreeNode are implemented. POE::Component::IRC::Plugin::Eval on the CPAN is a good example.
I'd just scrub the hell out of strings before passing them to a regex engine.