On Tue, 29 Apr 2008, Joe Teff wrote:

> > If I use Parameterized queries w/ binding of all variables, I'm 100%
> > immune to SQL Injection.
>
> Sure. You've protected one app and transferred risk to any other
> process/app that uses the data. If they use that data to create dynamic
> sql, then what?

Let's call these "using apps" for clarity of the rest of this post.

I think it's the fault of the "using apps" for not validating their own
data.

Here's a pathological and hopefully humorous example.

Suppose you want to protect those "using apps" against all forms of
attack.

How can you protect every "using app" against SQL injection, XSS, *and* OS
command injection?  Protecting against XSS (say, by setting "<" to "&gt;"
and other things) suddenly creates an OS command injection scenario
because "&" and ";" typically have special meaning in Unix system() calls.
Quoting against SQL injection "\'" will probably fool some XSS protection
mechanisms and/or insert quotes after they'd already been stripped.

As a result, the only safe data would be alphanumeric without any spaces -
after all, you want to protect your "user apps" against whitespace,
because that's what's used to introduce new arguments.

But wait - buffer overflows happen all the time with long alphanumeric
strings, and Metasploit is chock full of alpha-only shellcode, so
arbitrary code execution is still a major risk.  So we'll have to trim the
alphanumeric strings to... hmmm... one character long.

But, a one-character string will probably be too short for some "using
apps" and will trigger null pointer dereferences due to failed error
checking.  Worse, maybe there's a buffer underflow if the using app does
some negative offset calculations assuming a minimum buffer size.

And what if we're providing a numeric string that the using app might
treat as an array index?  So, anything that looks like an ID should be
scrubbed to a safe value, say, 1, since presumably the programmer doesn't
allocate 0-size arrays.  But wait, a user ID of "1" is often used to
identify the admin in a using apps, so this would be tantamount to giving
everyone admin privileges!  We shouldn't accept any numbers at all.

And, we periodically see issues where an attacker can bypass a
lowercase-only protection mechanism by using uppercase, so we'd best set
the characters to all-upper or all-lower.

So, maybe the best way to be sure we're protecting "using apps" is to send
them no data at all (which will still trigger crashes in apps that assume
they'll be hearing from someone eventually).

Or, barring that, you pass along some meta-data that explicitly states
what protections have or have not been applied to the data you're sending
- along with an integrity check of your claims.

Of course, some "using apps" won't check that integrity and will accept
bad data from anywhere, not just you, so they'll be vulnerable again,
despite your best intentions.

The alternate approach is to pick and choose which vulns you'll protect
using apps against.  But then, if you've protected a using app against SQL
injection, but it moves to a non-database model instead, you've just
broken your legitimate functionality.  So, you're stuck with modeling
which using apps are using which technologies and might be subject to
which vulns.  You will also need a complete model of what the using app's
behaviors are, and you'll need to keep different models for each different
version and operating environment.  This will become brittle and quickly
unmaintainable, and eventually introduce unrelated security issues as a
result of that brittleness.

To my current way of thinking, the two main areas of responsibility are:

- for the caller to make sure that the request/message is perfectly
structured and delimited, and semantically correct for what the caller is
asking the callee to do.  The current browser URI handler vulnerabilities,
and argument injection in general, are examples of violations of this
responsibility.

- for the caller, given any arbitrary message/request, to prove (or
enforce) that it is well-formed, to make sure that the caller has the
appropriate privileges to make that message/request in the first place,
and to protect itself against SQL injection when interacting with a DB,
against XSS when printing out to a web page, etc.


I recognize that you might not have a choice with stovepipe or legacy
applications, or in proxy/firewall code that resides between two
components.  I feel for anyone wrestling with those problems.  But,
"protect using apps against themselves" as general advice seems fraught
with peril.

- Steve
_______________________________________________
Secure Coding mailing list (SC-L) SC-L@securecoding.org
List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l
List charter available at - http://www.securecoding.org/list/charter.php
SC-L is hosted and moderated by KRvW Associates, LLC (http://www.KRvW.com)
as a free, non-commercial service to the software security community.
_______________________________________________

Reply via email to