[cap-talk] solve CSRF by making references unforgeable, not unshareable

David-Sarah Hopwood david.hopwood at industrial-designers.co.uk
Thu Mar 26 15:35:53 EDT 2009

John Carlson wrote:
> On Mar 25, 2009, at 9:41 AM, David-Sarah Hopwood wrote:
>> John Carlson wrote:
>>> zooko wrote:
>>>> This insight leads us to propose the following aphorism: Solve CSRF
>>>> attacks by making references unforgeable, not by making them
>>>> unshareable.
>>> Wouldn't making SQL queries unforgeable solve the SQL injection  
>>> problems?
>> References are made unforgeable by making valid representations of  
>> them either opaque or sparse (unguessable). Representations of SQL
>> queries cannot be made opaque nor sparse.
>> SQL injection (and injection attacks in general for any language) can
>> be solved by ensuring that the structure of the query as parsed is the
>> structure intended by the programmer. The easiest and simplest way to
>> do this is for the query API to represent a query as an abstract  
>> syntax tree, not a string.
>> If you want a pithy aphorism:
>> Strings are tricky. Don't rely on applications to say what they mean  
>> as a string.

Note that by "string" I mean either a binary or text string.

> I am assuming that you would send the AST across the network  
> (databases are on different machines than applications these days),  
> thus it would be bytes.

Sorry, but this is missing the point.

The reason why injection vulnerabilities are so common, is that it's
common for application programmers to believe that correctly emitting
strings in a particular language, such as SQL, is easy. So they do it
on an ad-hoc basis every time they want to emit a string.

In fact, emitting strings correctly is hard (harder for some languages
than others, but never easy). It requires careful attention to quoting
issues, especially in cases involving nested languages, which are
common in practice.

If a particular software component represents the queries (or other
structured data) that it creates as an AST, on the other hand, then
*that component* will not make any quoting errors, because quoting
is not needed in ASTs. At least in memory-safe languages that support
algebraic data types or equivalent, emitting an AST correctly *is*

Yes, for an AST to be transmitted over a network it needs to be
*represented* as bytes. But:

 - it is being serialized by a library that is hopefully written by
   someone who knows that emitting strings correctly is hard.

 - the library could potentially use the same serialization format
   independent of how the language represented by the AST is
   normally written; the serialization format can be designed sanely
   no matter how f'd-up the original language is.

> I would use asymmetric encryption to make the AST SQL unforgeable.

Why? Any attack that this would be preventing would not be an
injection attack.

David-Sarah Hopwood ⚥

More information about the cap-talk mailing list