So I'd like to pull this back to a few salient points. Weirdly,<br>some folks seem quick to dismiss the paper with a<br>didactic shot of "folks shouldn't code that way anyway"<br>which has nothing to do with the subject.<br>
<br>1. I think everyone on SC-L gets the idea of strong<br>patterns and implementations, and why parameterized<br>SQL is a good thing, and why cached queries are also<br>a good thing (for performance, at least, and security if<br>
by doing so you enforce avoidance of EXEC())<br><br>2. David's paper is interesting, because out in the real<br>world people do not, and sometimes cannot, follow<br>ideal patterns, command patterns, and or implementations<br>
that are safe. (e.g. delegation of privilege on Windows<br>accessing the DB for security inheritance vs. the negative<br>impact to thread pooling and process safety -- it is<br>a real tradeoff, and *never* made on the side of security)<br>
<br>David's paper is interesting because out in the real<br>world people still follow many borderline unsafe practices<br>and understanding new attack vectors is essential to<br>assessing risk, and understanding whether refactoring,<br>
or hofixing, vs. logging, filtering, or *ignoring* the code,<br>is the right business choice to make.<br><br>David's example is more CVE instance than CWE class.<br><br>--<br><br>Steven, I like the grouping of your two main abstractions<br>
below; for purpose of discussion & education I like to put<br>these together a little differently into Semantic and Syntax<br>software security-defect buckets. I'm curious what your<br>thoughts are (and take this offline if the response is too tangential)<br>
<br><br>1. Semantic -- I place message structure, delimiting,<br>and all entailments of semantic conversation, including<br>implications of use-case and business rules here, where<br>the latter relate to enforcing specific semantic user/caller-<br>
dialogues with the application.<br><br>I place callee requirement to enforce workflow, order,<br>message structure, state and sequence, and *privilege* here.<br><br>2. Syntax -- at heart we have a data/function boundary<br>
problem, right? And most modern implementation level<br>languages do not give us constructs to address/enforce<br>this, so all our cluged workarounds, from stack canaries<br>to crappy \ escaping in SQL to attempts to use of HTML<br>
named entities to encode output, fall into this grouping.<br><br>I place in callee requirements everything to do with<br>message encoding, canonicalization, buffer and<br>case e.g.- all syntax issues, into this grouping.<br>
<br>Now, arguably you could call a buffer or heap overflow<br>semantic, if you argue it's privilege related, but I<br>would say that is a result of language defects (or<br>realities) and it still starts syntactically.<br>
<br>Where would you put the recent URI-handler issues<br>in this structure?<br><br>Why did you specify privilege burden on the caller?<br><br>I tend to leave out/ignore the caller responsiblities<br>when I am thinking of software. This could be a<br>
bias of predominantly web-centric (and db client/server<br>where I don't control the client) programming and<br>design over the years.<br><br>While it makes sense to enforce some syntax<br>structure upon the caller, in general I tend to<br>
put all semantic responsibilities upon the callee,<br>and even assume the callee should enforce<br>some notion of syntax requirements upon<br>the caller, and feed said back to caller.<br><br>-- <br>-- <br>Arian J. Evans.<br>
<br>I spend most of my money on motorcycles, mistresses, and martinis. The rest of it I squander.<br><br><br><br><div class="gmail_quote">On Tue, Apr 29, 2008 at 9:10 AM, Steven M. Christey <<a href="mailto:coley@linus.mitre.org">coley@linus.mitre.org</a>> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="Ih2E3d"><br>
On Tue, 29 Apr 2008, Joe Teff wrote:<br>
<br>
> > If I use Parameterized queries w/ binding of all variables, I'm 100%<br>
> > immune to SQL Injection.<br>
><br>
> Sure. You've protected one app and transferred risk to any other<br>
> process/app that uses the data. If they use that data to create dynamic<br>
> sql, then what?<br>
<br>
</div>Let's call these "using apps" for clarity of the rest of this post.<br>
<br>
I think it's the fault of the "using apps" for not validating their own<br>
data.<br>
<br>
Here's a pathological and hopefully humorous example.<br>
<br>
Suppose you want to protect those "using apps" against all forms of<br>
attack.<br>
<br>
How can you protect every "using app" against SQL injection, XSS, *and* OS<br>
command injection? Protecting against XSS (say, by setting "<" to "&gt;"<br>
and other things) suddenly creates an OS command injection scenario<br>
because "&" and ";" typically have special meaning in Unix system() calls.<br>
Quoting against SQL injection "\'" will probably fool some XSS protection<br>
mechanisms and/or insert quotes after they'd already been stripped.<br>
<br>
As a result, the only safe data would be alphanumeric without any spaces -<br>
after all, you want to protect your "user apps" against whitespace,<br>
because that's what's used to introduce new arguments.<br>
<br>
But wait - buffer overflows happen all the time with long alphanumeric<br>
strings, and Metasploit is chock full of alpha-only shellcode, so<br>
arbitrary code execution is still a major risk. So we'll have to trim the<br>
alphanumeric strings to... hmmm... one character long.<br>
<br>
But, a one-character string will probably be too short for some "using<br>
apps" and will trigger null pointer dereferences due to failed error<br>
checking. Worse, maybe there's a buffer underflow if the using app does<br>
some negative offset calculations assuming a minimum buffer size.<br>
<br>
And what if we're providing a numeric string that the using app might<br>
treat as an array index? So, anything that looks like an ID should be<br>
scrubbed to a safe value, say, 1, since presumably the programmer doesn't<br>
allocate 0-size arrays. But wait, a user ID of "1" is often used to<br>
identify the admin in a using apps, so this would be tantamount to giving<br>
everyone admin privileges! We shouldn't accept any numbers at all.<br>
<br>
And, we periodically see issues where an attacker can bypass a<br>
lowercase-only protection mechanism by using uppercase, so we'd best set<br>
the characters to all-upper or all-lower.<br>
<br>
So, maybe the best way to be sure we're protecting "using apps" is to send<br>
them no data at all (which will still trigger crashes in apps that assume<br>
they'll be hearing from someone eventually).<br>
<br>
Or, barring that, you pass along some meta-data that explicitly states<br>
what protections have or have not been applied to the data you're sending<br>
- along with an integrity check of your claims.<br>
<br>
Of course, some "using apps" won't check that integrity and will accept<br>
bad data from anywhere, not just you, so they'll be vulnerable again,<br>
despite your best intentions.<br>
<br>
The alternate approach is to pick and choose which vulns you'll protect<br>
using apps against. But then, if you've protected a using app against SQL<br>
injection, but it moves to a non-database model instead, you've just<br>
broken your legitimate functionality. So, you're stuck with modeling<br>
which using apps are using which technologies and might be subject to<br>
which vulns. You will also need a complete model of what the using app's<br>
behaviors are, and you'll need to keep different models for each different<br>
version and operating environment. This will become brittle and quickly<br>
unmaintainable, and eventually introduce unrelated security issues as a<br>
result of that brittleness.<br>
<br>
To my current way of thinking, the two main areas of responsibility are:<br>
<br>
- for the caller to make sure that the request/message is perfectly<br>
structured and delimited, and semantically correct for what the caller is<br>
asking the callee to do. The current browser URI handler vulnerabilities,<br>
and argument injection in general, are examples of violations of this<br>
responsibility.<br>
<br>
- for the caller, given any arbitrary message/request, to prove (or<br>
enforce) that it is well-formed, to make sure that the caller has the<br>
appropriate privileges to make that message/request in the first place,<br>
and to protect itself against SQL injection when interacting with a DB,<br>
against XSS when printing out to a web page, etc.<br>
<br>
<br>
I recognize that you might not have a choice with stovepipe or legacy<br>
applications, or in proxy/firewall code that resides between two<br>
components. I feel for anyone wrestling with those problems. But,<br>
"protect using apps against themselves" as general advice seems fraught<br>
with peril.<br>
<br>
- Steve<br>
<div><div></div><div class="Wj3C7c">_______________________________________________<br>
Secure Coding mailing list (SC-L) <a href="mailto:SC-L@securecoding.org">SC-L@securecoding.org</a><br>
List information, subscriptions, etc - <a href="http://krvw.com/mailman/listinfo/sc-l" target="_blank">http://krvw.com/mailman/listinfo/sc-l</a><br>
List charter available at - <a href="http://www.securecoding.org/list/charter.php" target="_blank">http://www.securecoding.org/list/charter.php</a><br>
SC-L is hosted and moderated by KRvW Associates, LLC (<a href="http://www.KRvW.com" target="_blank">http://www.KRvW.com</a>)<br>
as a free, non-commercial service to the software security community.<br>
_______________________________________________<br>
</div></div></blockquote></div><br><br>