Matt,

> To be clear: this feature does not track taint through escape functions,
> regular expression filters, ctype_filters and the like by design. Security
> best-practice and more than a decade of security consulting experience show
> that developers who rely on filters and escaping rarely manage to do so
> competently and systematically enough to prevent SQL-injection on
> non-trivial websites. Rather, this feature recognizes that SQL-injection is
> already a solved problem. It is uncontroversial and overwhelmingly accepted
> security best-practice to ensure that every dynamic SQL query is executed
> via a prepared statement rather than via string-escaping.

Except that not every part of a query is preparable. And many
non-trivial complexity websites use these portions of queries
extensively.

Hence a blanket **programming language level** blocking of it is not
really going to fly.

> This feature works best for big websites that are following (or in the
> process of migrating their code to follow) this security-best-practice, as
> it allows them to systematically verify during development that the query
> string to every SQL statement is guaranteed untainted by attackers.

Actually, this allows them to verify at runtime. Not during
development (codepaths that aren't hit at devtime can still cause
problems at runtime).

If this is your goal, I'd suggest doing static analysis to prove (or
not) it. I have a working proof-of-concept of one here:
https://github.com/ircmaxell/php-security-scanner

> In terms of whether this RFC is too coupled with SQL extensions, I am
> sensitive to these concerns, but I don't think they apply for three broad
> reasons:
>
> Firstly, the taint logic tracks "safeconstness" (i.e. whether a zend_string
> is a string literal or linear concatenation of string literals), and
> by-design does not attempt to interact with escaping functions because (as
> your example clearly shows), escaping functions only /sometimes/ prevent
> injections, whereas parameterized queries /always/ stop injections.

No they don't. They only stop injections when used correctly. For
example (an edge case, but an important one):
http://stackoverflow.com/questions/134099/are-pdo-prepared-statements-sufficient-to-prevent-sql-injection/12202218#12202218

And that doesn't even touch on the DB backends that don't support PS.
And it doesn't even touch on the fact that not every dynamic part of a
query is preparable.

> reason the taint feature can be trivially applied to any builltin function
> where one parameter is structural and should be constant. It could be
> deployed without modification to prevent injection into regular expression
> queries for example to prevent denial-of-service, or to prove that the
> parameter to shell_exec is constant.
>
> Secondly, this feature applies globally to all SQL extensions, not just
> mysqli. This feature encompasses protection of mysqli, PDO and Postgres. In
> future, I would like to build this feature out to include some of the other
> categories of injection later, but given that SQL-injections remain the
> single most commonly exploited vulnerability in PHP applications, I think
> starting with them is probably best. Tackling SQL-injection in PHP is a big
> enough task as it is, and is a good place to start.
>
> Thirdly, although SQL extensions are extensions, this is a technicality, in
> much the same way that Zend Core is not supposed to be coupled to PHP. In
> reality, /most/ non-trivial PHP websites use one SQL extension or another to
> interact with a database, and despite parameterized queries existing for
> over a decade, huge numbers of PHP websites remain vulnerable to them --
> with a devastating impact on the company and their users when the
> vulnerability is exploited.

Except that there are a number of DB extensions that don't ship with
PHP. And those that aren't shipped at all (they are custom propriatary
extensions). And those that aren't really SQL, but use similar
semantics (MongoDB).

> Understanding SQL injections is hard for many junior developers to
> understand, and hard for companies to apply systematically. The impact of
> them getting it wrong can be catastrophic to companies and is a major threat
> to users' online privacy when their data gets compromised. I think having
> PHP give developers a hand to write code that is unambiguously safe from
> hackers would be a good for whole PHP community.

It's hard, because tutorials make it hard. It's hard because we show
concatenation as the right way of doing things, and then tell them
it's wrong. It's hard, because we suck at teaching.

Kent Beck had an awesome passage in his book Test-Driven-Development
By Example. I'll paraphrase here, but he said that every engineer he
worked with found testing difficult. However, his daughter found it
easy and never even thought about it. It was because she was taught
TDD from the ground up. She was taught that you don't write code and
then test, you just test & write code. So she never had time to learn
bad practices because she just learned how to do it right.

And prepared statements are precisely like that. How many other
programming languages have such major problems with SQLi? Most do not.
Don't get me wrong, it exists in other languages (most definitely).
But Parameterized Queries are a big focus in other languages.

Our beginner tutorials all teach concatenation. Then escaping. Then
PS. You want to fix the problem, fix it with education. Tainting can
be a safeguard, but it's not a solution.

My $0.02

Anthony

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to