<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Programming Like It&#8217;s 1999</title>
	<atom:link href="http://perlhacks.com/2011/11/programming-like-its-1999/feed/" rel="self" type="application/rss+xml" />
	<link>http://perlhacks.com/2011/11/programming-like-its-1999/</link>
	<description>Just another Perl Hacker&#039;s blog</description>
	<lastBuildDate>Sun, 25 Mar 2012 07:54:25 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>By: mike</title>
		<link>http://perlhacks.com/2011/11/programming-like-its-1999/#comment-3159</link>
		<dc:creator>mike</dc:creator>
		<pubDate>Sat, 11 Feb 2012 10:44:13 +0000</pubDate>
		<guid isPermaLink="false">http://perlhacks.com/?p=370#comment-3159</guid>
		<description>I&#039;d love to see an example of how this looks on a site/page php/html
anyone have a link?</description>
		<content:encoded><![CDATA[<p>I&#8217;d love to see an example of how this looks on a site/page php/html<br />
anyone have a link?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Name</title>
		<link>http://perlhacks.com/2011/11/programming-like-its-1999/#comment-3058</link>
		<dc:creator>Name</dc:creator>
		<pubDate>Mon, 19 Dec 2011 02:30:08 +0000</pubDate>
		<guid isPermaLink="false">http://perlhacks.com/?p=370#comment-3058</guid>
		<description>Bobby Tables!  I don&#039;t even have to click the link</description>
		<content:encoded><![CDATA[<p>Bobby Tables!  I don&#8217;t even have to click the link</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ed Avis</title>
		<link>http://perlhacks.com/2011/11/programming-like-its-1999/#comment-3001</link>
		<dc:creator>Ed Avis</dc:creator>
		<pubDate>Thu, 24 Nov 2011 19:59:41 +0000</pubDate>
		<guid isPermaLink="false">http://perlhacks.com/?p=370#comment-3001</guid>
		<description>Zefram gave an example of a case that your code misses.  The point is that by &#039;enumerating badness&#039;, you make sure that if you&#039;ve overlooked something it will be a vulnerability.  Better to fail safe by rejecting anything not in a list of characters you know to be okay.  Both solutions (yours and mine) need extending to handle additional characters: yours does not handle backslash correctly, and mine doesn&#039;t do accented characters.  But the consequences of that omission are different.  You need to write the test so that even if you have missed something out (which will inevitably happen), it won&#039;t leave you with SQL injection bugs.  Losing some accented characters is a much more benign failure mode IMHO.</description>
		<content:encoded><![CDATA[<p>Zefram gave an example of a case that your code misses.  The point is that by &#8216;enumerating badness&#8217;, you make sure that if you&#8217;ve overlooked something it will be a vulnerability.  Better to fail safe by rejecting anything not in a list of characters you know to be okay.  Both solutions (yours and mine) need extending to handle additional characters: yours does not handle backslash correctly, and mine doesn&#8217;t do accented characters.  But the consequences of that omission are different.  You need to write the test so that even if you have missed something out (which will inevitably happen), it won&#8217;t leave you with SQL injection bugs.  Losing some accented characters is a much more benign failure mode IMHO.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Cross</title>
		<link>http://perlhacks.com/2011/11/programming-like-its-1999/#comment-3000</link>
		<dc:creator>Dave Cross</dc:creator>
		<pubDate>Thu, 24 Nov 2011 14:20:04 +0000</pubDate>
		<guid isPermaLink="false">http://perlhacks.com/?p=370#comment-3000</guid>
		<description>Good idea. &lt;a href=&quot;http://perlhacks.com/code/getMovieData&quot; rel=&quot;nofollow&quot;&gt;See here&lt;/a&gt;.</description>
		<content:encoded><![CDATA[<p>Good idea. <a href="http://perlhacks.com/code/getMovieData" rel="nofollow">See here</a>.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Alex</title>
		<link>http://perlhacks.com/2011/11/programming-like-its-1999/#comment-2999</link>
		<dc:creator>Alex</dc:creator>
		<pubDate>Thu, 24 Nov 2011 14:12:05 +0000</pubDate>
		<guid isPermaLink="false">http://perlhacks.com/?p=370#comment-2999</guid>
		<description>This is a good example for newbies how things should happen in modern perl. I am going to show it to my students. But can you make a copy of original script, because it can dissappear.</description>
		<content:encoded><![CDATA[<p>This is a good example for newbies how things should happen in modern perl. I am going to show it to my students. But can you make a copy of original script, because it can dissappear.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Toby Inkster</title>
		<link>http://perlhacks.com/2011/11/programming-like-its-1999/#comment-2997</link>
		<dc:creator>Toby Inkster</dc:creator>
		<pubDate>Wed, 23 Nov 2011 17:07:08 +0000</pubDate>
		<guid isPermaLink="false">http://perlhacks.com/?p=370#comment-2997</guid>
		<description>The SQL standard way of escaping single quotes is not to backslash them, but to double them up. That is:

s{&#039;}{&#039;&#039;}g

Of course, many SQL databases support backslash escaping instead of or as well as the SQL standard method.</description>
		<content:encoded><![CDATA[<p>The SQL standard way of escaping single quotes is not to backslash them, but to double them up. That is:</p>
<p>s{&#8216;}{&#8221;}g</p>
<p>Of course, many SQL databases support backslash escaping instead of or as well as the SQL standard method.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Zefram</title>
		<link>http://perlhacks.com/2011/11/programming-like-its-1999/#comment-2995</link>
		<dc:creator>Zefram</dc:creator>
		<pubDate>Wed, 23 Nov 2011 12:05:02 +0000</pubDate>
		<guid isPermaLink="false">http://perlhacks.com/?p=370#comment-2995</guid>
		<description>Your single-quote escaping is *not* sufficient to avoid SQL injection.  Most obviously, backslashes also need to be escaped.  Specific exploit: I give you the string &lt;code&gt;q{\&#039;);drop database imdb;-- }&lt;/code&gt;.  You escape the single quote yielding &lt;code&gt;q{\\&#039;);drop database imdb;-- }&lt;/code&gt;, and then stick it into quotes yielding &lt;code&gt;q{insert into movie (...) values (&#039;\\&#039;);drop database imdb;-- &#039;, ...);}&lt;/code&gt;.  The &lt;code&gt;q{&#039;\\&#039;}&lt;/code&gt; parses as a complete string literal, representing a string containing a single backslash.  You lose.

The right way to embed data in SQL is to have a function whose input is a data object (in whatever form you&#039;re dealing with in Perl space) and whose output is a string of SQL source constituting an expression that will evaluate to the in-database representation of the same data.  If you&#039;re dealing with a string (or anything that you represent as a string in SQL space) then you&#039;d expect that output expression to be in the form of an SQL string literal.  The concept generalises to all SQL data types, including ones that don&#039;t have a literal syntax, and to all types of object that you deal with in Perl space.

Here&#039;s the specific logic that I developed at $ork to represent a Perl octet string as an SQL octet string:
&lt;pre&gt;
my %char_escape = ( &quot;\0&quot; =&gt; &quot;\\0&quot;, &quot;&#039;&quot; =&gt; &quot;\\&#039;&quot;, &quot;\\&quot; =&gt; &quot;\\\\&quot; );
sub sql_octetstring($) {
    my($value) = @_;
    die &quot;not an octet string&quot;
      unless Params::Classify::is_string($value)
      &amp;&amp; $value =~ /\A[\x00-\xff]*\z/;
    $value =~ s(([\0\&#039;\\]))($char_escape{$1})eg;
    return &quot;&#039;$value&#039;&quot;;
}
&lt;/pre&gt;
This is specifically for MySQL; you need to experiment to write the correct equivalent for your particular database.  Also, obviously, if you&#039;re dealing with general Unicode then you&#039;ll need an encoding layer on top of this.

You use it like &quot;&lt;code&gt;where title=@{[sql_octetstring($title)]}&lt;/code&gt;&quot; or &quot;&lt;code&gt;values (@{[join(q(, ), map { sql_octetstring($film{$_}) } @fields)]})&lt;/code&gt;&quot;.  The babycart operator is brilliant for this sort of thing, because it gives you all the right cues about the nesting that is logically occurring.</description>
		<content:encoded><![CDATA[<p>Your single-quote escaping is *not* sufficient to avoid SQL injection.  Most obviously, backslashes also need to be escaped.  Specific exploit: I give you the string <code>q{\');drop database imdb;-- }</code>.  You escape the single quote yielding <code>q{\\');drop database imdb;-- }</code>, and then stick it into quotes yielding <code>q{insert into movie (...) values ('\\');drop database imdb;-- ', ...);}</code>.  The <code>q{'\\'}</code> parses as a complete string literal, representing a string containing a single backslash.  You lose.</p>
<p>The right way to embed data in SQL is to have a function whose input is a data object (in whatever form you&#8217;re dealing with in Perl space) and whose output is a string of SQL source constituting an expression that will evaluate to the in-database representation of the same data.  If you&#8217;re dealing with a string (or anything that you represent as a string in SQL space) then you&#8217;d expect that output expression to be in the form of an SQL string literal.  The concept generalises to all SQL data types, including ones that don&#8217;t have a literal syntax, and to all types of object that you deal with in Perl space.</p>
<p>Here&#8217;s the specific logic that I developed at $ork to represent a Perl octet string as an SQL octet string:</p>
<pre>
my %char_escape = ( "\0" =&gt; "\\0", "'" =&gt; "\\'", "\\" =&gt; "\\\\" );
sub sql_octetstring($) {
    my($value) = @_;
    die "not an octet string"
      unless Params::Classify::is_string($value)
      &amp;&amp; $value =~ /\A[\x00-\xff]*\z/;
    $value =~ s(([\0\'\\]))($char_escape{$1})eg;
    return "'$value'";
}
</pre>
<p>This is specifically for MySQL; you need to experiment to write the correct equivalent for your particular database.  Also, obviously, if you&#8217;re dealing with general Unicode then you&#8217;ll need an encoding layer on top of this.</p>
<p>You use it like &#8220;<code>where title=@{[sql_octetstring($title)]}</code>&#8221; or &#8220;<code>values (@{[join(q(, ), map { sql_octetstring($film{$_}) } @fields)]})</code>&#8220;.  The babycart operator is brilliant for this sort of thing, because it gives you all the right cues about the nesting that is logically occurring.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Cross</title>
		<link>http://perlhacks.com/2011/11/programming-like-its-1999/#comment-2994</link>
		<dc:creator>Dave Cross</dc:creator>
		<pubDate>Wed, 23 Nov 2011 11:41:01 +0000</pubDate>
		<guid isPermaLink="false">http://perlhacks.com/?p=370#comment-2994</guid>
		<description>I can be confident that your version will break a lot of the data I get back from the API :) See &lt;a href=&quot;http://www.imdbapi.com/?r=XML&amp;t=tintin&quot; rel=&quot;nofollow&quot;&gt;an example&lt;/a&gt;. See how much non-alphanumeric data it includes?

I&#039;m becoming more confident in my solution. The argument goes like this. You can only do nasty things to me if you can close my SQL statement and open a new one. All of my interpolated data is within single-quoted strings. Therefore, to start a new statement you need to close my string. But by escaping any single quotes in the data I&#039;m preventing you from doing that.

What am I missing?</description>
		<content:encoded><![CDATA[<p>I can be confident that your version will break a lot of the data I get back from the API <img src='http://perlhacks.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  See <a href="http://www.imdbapi.com/?r=XML&#038;t=tintin" rel="nofollow">an example</a>. See how much non-alphanumeric data it includes?</p>
<p>I&#8217;m becoming more confident in my solution. The argument goes like this. You can only do nasty things to me if you can close my SQL statement and open a new one. All of my interpolated data is within single-quoted strings. Therefore, to start a new statement you need to close my string. But by escaping any single quotes in the data I&#8217;m preventing you from doing that.</p>
<p>What am I missing?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ed Avis</title>
		<link>http://perlhacks.com/2011/11/programming-like-its-1999/#comment-2993</link>
		<dc:creator>Ed Avis</dc:creator>
		<pubDate>Wed, 23 Nov 2011 11:30:24 +0000</pubDate>
		<guid isPermaLink="false">http://perlhacks.com/?p=370#comment-2993</guid>
		<description>Escaping single quotes *might* be enough to avoid SQL injection attacks, or it might not be.  Are you comfortable relying on it?  I would prefer something more paranoid like
&lt;pre&gt;
foreach (@fields) {
    $film{$_} = tr/A-Za-z0-9 /_/cs;
}
&lt;/pre&gt;
OK that might be a bit extreme, but you can be confident it is safe.</description>
		<content:encoded><![CDATA[<p>Escaping single quotes *might* be enough to avoid SQL injection attacks, or it might not be.  Are you comfortable relying on it?  I would prefer something more paranoid like</p>
<pre>
foreach (@fields) {
    $film{$_} = tr/A-Za-z0-9 /_/cs;
}
</pre>
<p>OK that might be a bit extreme, but you can be confident it is safe.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Stefan</title>
		<link>http://perlhacks.com/2011/11/programming-like-its-1999/#comment-2991</link>
		<dc:creator>Stefan</dc:creator>
		<pubDate>Tue, 22 Nov 2011 21:05:27 +0000</pubDate>
		<guid isPermaLink="false">http://perlhacks.com/?p=370#comment-2991</guid>
		<description>http://xkcd.com/327/ 
no more comments needed.</description>
		<content:encoded><![CDATA[<p><a href="http://xkcd.com/327/" rel="nofollow">http://xkcd.com/327/</a><br />
no more comments needed.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

<!-- Dynamic page generated in 0.177 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-03-26 21:26:12 -->
<!-- Compression = gzip -->