<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Tom Moertel's Weblog: Tag problem</title>
    <link>http://blog.moertel.com/articles/tag/problem?tag=problem</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Quality rants on programming theory and stuff geeks like</description>
    <item>
      <title>If unit testing can't keep Rails safe from string-escaping problems, what makes you think it will keep your projects safe?</title>
      <description>&lt;p&gt;Recently I wrote about &lt;a href="http://blog.moertel.com/articles/2006/10/10/unit-testing-is-a-tool-not-a-goal"&gt;unit testing being a tool, not a goal in
itself&lt;/a&gt;.
I argued that unit testing was not a reliable way to fight
certain kinds of common coding errors and, therefore, that unit testing
ought to be supplemented with other tools.&lt;/p&gt;


	&lt;p&gt;To support my argument, I gave an example of a common, important
coding error that unit testing does a bad job of helping programmers
control.  That error is failing to manage and escape strings
properly: the &amp;#8220;strings problem.&amp;#8221;  It is the mother of &lt;span class="caps"&gt;XSS&lt;/span&gt; and
&lt;span class="caps"&gt;SQL&lt;/span&gt;-injection security vulnerabilities, not to mention the cause of
legions of broken links and bad &lt;span class="caps"&gt;HTML&lt;/span&gt; on the web.&lt;/p&gt;


	&lt;p&gt;If you think I&amp;#8217;m overstating the problem, or if you think that unit
testing is a good way of solving it, let me show you how easy it is
for even smart developers to get it wrong.&lt;/p&gt;


	&lt;p&gt;Consider &lt;a href="http://rubyonrails.com/"&gt;Ruby on
Rails&lt;/a&gt;, a great framework
for developing web applications.
Rails has an extensive suite of unit tests, and the &lt;a href="http://dev.rubyonrails.org/"&gt;Rails development guidelines&lt;/a&gt; require that changes to Rails be accompanied by unit tests that &amp;#8220;prove [the] change works.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Now consider that one of Rails&amp;#8217;s most-used and &lt;a href="http://blog.moertel.com/articles/2005/05/08/taking-the-unsafe-gets-out-of-rails"&gt;most-scrutinized&lt;/a&gt; methods &amp;#8211; the venerable &lt;code&gt;link_to&lt;/code&gt; helper &amp;#8211; contains a fundamental string-escaping error:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;require 'rubygems'
require_gem 'rails'
include ActionView::Helpers::UrlHelper

url = "http://example.com?ohms_law?volt=1&amp;#38;amp=3" 
puts link_to("TEST", url)
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The code, when executed, prints the following &lt;span class="caps"&gt;HTML&lt;/span&gt; snippet:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;&amp;lt;a href="http://example.com?ohms_law?volt=1&amp;#38;amp=3"&amp;gt;TEST&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The &lt;span class="caps"&gt;HTML&lt;/span&gt; snippet represents a hypertext link.  The link should point
to the &lt;span class="caps"&gt;URL&lt;/span&gt; given in the code, but because the &lt;span class="caps"&gt;URL&lt;/span&gt; was not properly
escaped when it was converted into &lt;span class="caps"&gt;HTML&lt;/span&gt; by the &lt;code&gt;link_to&lt;/code&gt; helper, the
link is broken:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;CORRECT:  http://example.com?ohms_law?volt=1&amp;#38;amp=3
LINK_TO:  http://example.com?ohms_law?volt=1&amp;#38;=3
                                             ^ oops
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Here&amp;#8217;s what&amp;#8217;s going on.  Because the &lt;span class="caps"&gt;URL&lt;/span&gt; was not escaped, web browsers
misinterpret its &amp;#8220;amp&amp;#8221; parameter as a character-entity reference,
which gets gobbled up when the link&amp;#8217;s &lt;code&gt;href&lt;/code&gt; attribute is parsed.
(To see this for yourself, save the output of the Ruby code into an
&lt;span class="caps"&gt;HTML&lt;/span&gt; file, open the file with your favorite web browser, and see where
the link points.)&lt;/p&gt;


	&lt;p&gt;Now, how come the unit tests didn&amp;#8217;t catch this problem?
It turns out, the tests got it wrong, too, by expecting
broken output:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;# in url_helper_test.rb

def test_link_tag_with_query
  assert_dom_equal \
    "&amp;lt;a href=\"http://www.example.com?q1=v1&amp;amp;amp;q2=v2\"&amp;gt;Hello&amp;lt;/a&amp;gt;",
    link_to("Hello", "http://www.example.com?q1=v1&amp;amp;amp;q2=v2")
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The point isn&amp;#8217;t that the Rails developers are dumb.  The point is that
the Rails developers are smart.  If &lt;em&gt;they&lt;/em&gt; can&amp;#8217;t get the strings
problem right, even with all their brains and all their unit testing,
what reason does &lt;em&gt;any&lt;/em&gt; programmer have to think that unit testing is going
to solve this problem reliably?&lt;/p&gt;


	&lt;p&gt;If, then, you want to solve the strings problem &amp;#8211; and you really,
seriously &lt;em&gt;ought&lt;/em&gt; to want to solve the strings problem &amp;#8211; you should
consider options beyond unit testing.&lt;/p&gt;


&lt;div class="update"&gt;

	&lt;p&gt;&lt;strong&gt;Update 2007-09-04:&lt;/strong&gt; I just noticed that the documentation for
&lt;em&gt;link_to&lt;/em&gt; has been revised to state that if you pass a
string as its &lt;em&gt;options&lt;/em&gt; parameter, the string will be interpreted not
as a &lt;span class="caps"&gt;URL&lt;/span&gt; but as an &lt;span class="caps"&gt;HTML&lt;/span&gt; &lt;em&gt;href&lt;/em&gt; attribute value, that is, an
&lt;span class="caps"&gt;HTML&lt;/span&gt;-encoded &lt;span class="caps"&gt;URL&lt;/span&gt;.  The old documentation:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt; &lt;code&gt;def link_to(name, options = {}, html_options = nil, *parms)&lt;/code&gt;&lt;br/&gt;Creates a link tag of
the given &lt;em&gt;name&lt;/em&gt; using an &lt;span class="caps"&gt;URL&lt;/span&gt; created by the set of &lt;em&gt;options&lt;/em&gt;.... It&amp;#8217;s
also possible to pass a string instead of an options hash to get a
link tag that just points without consideration.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;The relevant part of the revised documentation:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;It&amp;#8217;s also possible to pass a string instead of an options hash to
get a link tag that uses the value of the string as the href for the
link.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;So, according to the updated documentation, the test I described in my
article is actually correct.  Does this mean that string-handling code
is Rails is worry free?  The existence of helper methods like &lt;a href="http://dev.rubyonrails.org/changeset/5321"&gt;&lt;em&gt;fix_double_escape&lt;/em&gt;&lt;/a&gt;
suggests the answer is no.&lt;/p&gt;


&lt;/div&gt;</description>
      <pubDate>Thu, 12 Oct 2006 16:06:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:03f6d26c-1207-4022-a970-b80231721ea6</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2006/10/12/if-unit-testing-cant-keep-rails-safe-from-string-escaping-problems-what-makes-you-think-it-will-keep-your-projects-safe</link>
      <category>programming</category>
      <category>testing</category>
      <category>rails</category>
      <category>rails</category>
      <category>testing</category>
      <category>strings</category>
      <category>problem</category>
      <category>escaping</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/184</trackback:ping>
    </item>
  </channel>
</rss>
