
Escape Velocity - remi
https://github.com/blog/1475-escape-velocity
======
tmoertel
That Rails has an _escape_once_ method is a big part of the reason I stopped
using Rails. If you think "double escaping" is a problem to be solved by
creating a helper method that won't escape what's already escaped, now you
have two problems.

EDIT TO ELABORATE:

Problem 1 is the original problem, that parts of your code do not agree upon
what a particular string represents. This is the "strings problem," the mother
of XSS and injection vulnerabilities. [1]

Problem 2 is that the _escape_once_ method papers over these problems, making
them harder to detect, and preventing you from hunting down the logic errors
that cause them. (Since these errors often occur in upstream code, you need to
find them _before_ they execute to be safe, which is why compile-time methods
[2] work best.)

[1] [http://blog.moertel.com/posts/2007-08-15-a-bright-future-
sec...](http://blog.moertel.com/posts/2007-08-15-a-bright-future-security-and-
modern-type-systems.html)

[2] [http://blog.moertel.com/posts/2006-10-18-a-type-based-
soluti...](http://blog.moertel.com/posts/2006-10-18-a-type-based-solution-to-
the-strings-problem.html)

~~~
lobster_johnson
The article should have pointed out that Github is running Rails 2.3, and that
this is where the problem exists.

Rails 3.x has reworked the entire escaping situation and now avoids the re-
escaping trap (strings must be flagged as "HTML safe", otherwise they are
escaped on final injection into a document). It still has escape_once, but
it's not used by Rails itself.

You are of course right to blame 2.x for its flaws, but let's not blame entire
projects for problems that have been fixed. (Not that Rails 3.x does not have
other egregious inefficiencies, but that's another story.)

~~~
tmoertel
I stopped using Rails not so much because of the existence of the
_escape_once_ method but because of what its introduction in 2006, and its
continued use in mainstream Rails methods (until 2010 when Rails 3.0 was
released), said about the direction of the project.

~~~
lobster_johnson
What did it say about the direction of the project, in your opinion? I can see
how one might conclude that the developers are idiots based on that method,
but I have to say that what I get out of Rails vastly outweighs that
stupidity.

~~~
tmoertel
It made it hard to believe that the project wouldn't be plagued by security
problems. For me, that was enough.

------
rmckayfleming
And here I thought that Ambrosia just released the Escape Velocity source
code.

~~~
wsc981
Same here. Was an extremely funny space trade / exploration / shooting game.
PC users missed out on this great piece of classic Mac shareware.

Small "let's play" video: <https://www.youtube.com/watch?v=4VX6TZEfqf4>

~~~
gilgoomesh
Windows users only missed out on the first two games when they came out. EV
Nova (the third game) is available for Windows and the first two games are
available as free plugins for Nova.

------
lobster_johnson
To people horrified by the Rails code, keep in mind that Github is running
Rails 2.3, which is very old and near the end of LTS. Rails 3.x has reworked
the entire escaping situation and now avoids the re-escaping trap (strings
must be flagged as "HTML safe", otherwise they are escaped on final injection
into a document).

~~~
codewright
So, what's their upgrade path situation? Are they going to try to hold out
indefinitely on 2.3? Upgrade at the last possible moment? (Ick) Switch out of
Rails when the situation becomes intolerable?

~~~
lobster_johnson
I wouldn't know. I don't know anyone at Github who might answer this.

------
minimax
"Just by replacing the escaping function with a more optimized one, we've
reduced the average request time by 45ms, and we're allocating 20,000 less
Ruby objects per request. That was a lot of escaped HTML right there!"

I generally stay away from web development so forgive me if this one is
obvious, but why does so much text need to have HTML escaping performed in
order to render the page? Also is there a way to quantify how much text that
is? Like a few K per page or a few hundred K?

~~~
JangoSteve
My guess is that it has something to do with the fact that Github is made up
almost entirely of user generated content. Just load a Github project page.
From top to bottom, you have:

    
    
        * Username in the header (which is probably validated with a specific format,
          so probably doesn't need escaping).
        * Project summary entered when the project is created.
        * Drop-down with list of branch and tag names.
        * Latest commit message.
        * List of names for all folders and files tracked in git for the project.
        * Readme text.
    

That's just the homepage for a project, and each one of those things could
potentially contain malicious HTML or JS, meaning it should be escaped before
rendered on the page.

~~~
theycallmemorty
Not to mention the pages that display actual code.

------
Irishsteve
What a disappointing post. After the ambrosia software announcement the other
day I thought they had open sourced escape velocity.

------
purephase
Very cool. I'll have to check this out. That profile tool looks interesting
too. I've been using the rack-mini-profiler gem but it might be a good idea to
do a deeper dive.

As always GH, thanks for sharing.

------
jamesaguilar
I'm always amazed by these startups doing what _seems_ like really simple
optimizations and reaping these enormous benefits. If your tools support
profiling, you should at least give it a shot once in a while. The fruit are
hanging low indeed if Github can reap this kind of reward with this small a
tweak.

------
mbell
FTA: "273,006 objs avg/req"

Wow, that is...a lot...is that mostly rails or is that in user code?

~~~
drbawb
Seems kinda par for the course for a Rails app.

[http://meta.discourse.org/t/tuning-ruby-and-rails-for-
discou...](http://meta.discourse.org/t/tuning-ruby-and-rails-for-
discourse/4126)

Scroll down and you'll see that on an average request, Discourse eats up
230,000 strings [which are all objects in Ruby] per request.

The entire thread is about relaxing the garbage collector so that it won't run
until the request is over.

------
silasb
I love stories like this. Make me wish I could spend more time in Ruby land
creating/fixing slow code.

