<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged static</title>
    <link href="https://passingcuriosity.com/tags/static/static.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/static/static.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2012-09-16T00:00:00Z</updated>
    <entry>
    <title>Injection avoidance in Haskell</title>
    <link href="https://passingcuriosity.com/2012/injection-avoidance-in-haskell/" />
    <id>https://passingcuriosity.com/2012/injection-avoidance-in-haskell/</id>
    <published>2012-09-16T00:00:00Z</published>
    <updated>2012-09-16T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>This post contains a short proof-of-concept for a technique which allows
library authors to implement injection-proof interfaces. It combines two
techniques used by Bryan O’Sullivan in the <a href="http://hackage.haskell.org/package/mysql-simple">mysql-simple</a> and <a href="http://hackage.haskell.org/package/text">text</a>
packages:</p>
<ul>
<li><p>Wrap injection-vulnerable string parameters in a new type with a restricted
API.</p></li>
<li><p>Use GHC’s rewriting facilities to modify the code generated for literal
values of string types.</p></li>
</ul>
<p>This technique (which probably isn’t new, but is new to me) works like this:</p>
<ol type="1">
<li><p>Create a new type which wraps your problematic strings.</p></li>
<li><p>Define an instance of <code>IsString</code> for this new type.</p></li>
<li><p>Implement a new “unsafe” version for the <code>fromString</code> method.</p></li>
<li><p>Use a rule to specialise <code>fromString</code> to your <code>fromStringUnsafe</code> function.</p></li>
<li><p>Define a “safe” version of the <code>fromString</code> method.</p></li>
<li><p>Use a rule to replace “safe” calls to <code>fromStringUnsafe</code> with your
<code>fromStringSafe</code> function.</p></li>
</ol>
<p>The first two steps result in an API in which writing unsafe code requires
explicit effort from the programmer. Rather than writing:</p>
<pre><code>result &lt;- query_ $ &quot;SELECT * FROM table WHERE id = &quot; ++ theId</code></pre>
<p>a programmer will need to write:</p>
<pre><code>result &lt;- query_ $ fromString $ &quot;SELECT * FROM table WHERE id = &quot; ++ theId</code></pre>
<p>This is certainly an improvement, but still allows unsafe operations to be
performed.</p>
<p>Steps three and four convince GHC to replace the <code>fromString</code> calls which
convert string values (be they literal as in the first example or dynamic as
in the second) into our custom type with calls to our own specialised
function. Functionally, this should have no impact on the program.</p>
<p>In steps five and six we use a technique from <em>text</em>, where we use knowledge
of GHC’s internals to rewrite the code which handles our string literals and
replace this code with something a little more specialised. In the <em>text</em>
package, this results in code which goes straight from <code>GHC.CString.Addr#</code> to
<code>Text</code> values rather than going via an intermediate <code>String</code>.</p>
<p>So far this seems like a little bit of security theatre with a little bit of
optimisation, but it becomes more powerful when we make our implementations of
<code>fromString</code> and <code>fromStringUnsafe</code> call <code>error</code> and only <code>fromStringSafe</code>
actually create a <code>Query</code> (or whatever your type is).</p>]]></summary>
</entry>

</feed>
