>> This may have been true at one point in time, but my own experience
>> and the statistics collected by Dan Kaminsky of White Hat Security
>> indicates that Cross-Site Scripting vulnerabilities are much more
>> prevalent in 2015 than SQL Injection, especially in business
>> applications. If Google has information that indicates that SQLi is
>> still more prevalent than XSS, I'd love to see this data.

Thanks Scott!

You are absolutely correct. SQL injection is a solved problem using
parameterized SQL. In fact, parameterizing queries to avoid SQL injection
is so uncontroversially accepted security advice, that this RFC *enforces* the
advice at the language level (unless the website administrator explicitly
disables the protection across the website via PHP.INI).

Examples of SQL queries that *would* and *would not *be blocked by this
tool are given in the RFC. In your case, "ORDER BY {$column} ASC" would not
be blocked by this tool if $column came from within the PHP application,
but would be blocked if it came from, say, $_GET["column"].

Sadly, although SQL injection is a "solved problem" by using prepared
statements, not everyone follows the advice. Prior to working at Google, I
worked with a company called iSEC Partners who do application review for
various companies. From my experience, between a third and a half of all
the often-huge PHP websites I security-reviewed were vulnerable to SQL
injection somewhere. It wasn't uncommon for the company to have ~5000 or so
SQL queries in their PHP code, only 2-3 of which were vulnerable to
injection. But attackers only need one to ruin your company and steal your
users' data.

To take apart some of the other valid comments on this thread:

== SQL injection is dead ==
This is objectively not the case
https://www.exploit-db.com/search/?action=search&description=SQL+injection

== Won't this break every website? ==
No. In its initial release, this feature will be released in "disabled"
mode. Website owners with heightened security requirements will be able to
upgrade this to "logging" or "blocking" mode. This means this feature will
have zero impact on websites that do not explicitly enable it.

== We should be looking at XSS instead ==
Solving SQL injection with parameterized SQL queries is uncontroversial and
universally accepted security advice. Lots of different (some working, some
not) advice for solving XSS exist, but this makes it harder to standardize
one of those ideas into the language without significant controversy.

For example, one website may choose to store HTML content in their
database. This should be printed out to HTML verbatim. Other websites may
accidentally store HTML content in their database, leading to stored-XSS.
The language will not be able to distinguish these two use-cases.

In contrast, taking content out of a database and gluing it into a SQL
statement is /always/ an error, as it can lead to second-order and
blind-SQL injection vulnerabilities. For this reason, this RFC will
initially only be looking at securing websites against SQL-injections,
although perhaps there is scope to also look at XSS-injection
vulnerabilities in a different RFC using similar tools at a later date.

== This breaks applications that use OOP or other complicated ways of
sending data to a database ==
This is not the case. This RFC doesn't use taint analysis to find SQL
injections; it uses reverse-taint analysis to avoid blocking provably safe
non-parameterized queries (so we don't block queries that are safely built
dynamically out of static strings and variables). Many examples of this are
given in the RFC.

As you can see from this proof-of-concept (
http://phpoops.cloudapp.net/oops.php?action=main&dbg_sql&limit=4%20uhoh),
all of the SQL statements are unparameterized, but only one unparameterized
SQL statement that includes attacker-controllable data is blocked, which,
as it turns out, is the only query vulnerable to SQL injection.

Dynamically construct SQL statements out of provably safe components are
not detected as a SQL-injectable error by this RFC.

== SQL injection is already solved! Why are you re-solving it? ==
This RFC doesn't solve SQL injection in a new way. It blocks dynamic SQL
queries that are not parameterized by default, but uses reverse-taint
analysis to reduce false positives where developers are building SQL query
string out of other constant strings (such as config variables, table
names, column names etc). This feature only takes action when tainted data
is concatenated into a SQL query string and that query string is issued
against the database, and even then, only if PHP.INI has been configured to
do so.

== We should log, rather than block exploit attempts ==
The feature has three modes, which is configurable via PHP.INI:
"Safe" mode causes the query to be aborted, and a SecurityError exception
thrown.
"Logging" mode causes the query to be run, and an E_WARNING raised
"Ignore" more causes the query to be run and no other action to be taken.

The default mode will be "ignore", i.e. PHP will simply continue as in
older versions. Developers who want to harden their code can run their
website in "logging" mode to find and improve dangerous code in their
codebase. Website administrators with heightened security awareness, or
developers writing new code from scratch will be able to run the feature in
"blocking" mode to prevent any possibility of SQL injection against their
website.

== What about applications that pass user-submitted SQL statements to the
database by design? ==
This is accounted for in the RFC. Developers will be able to explicitly
mark SQL queries as disabling the SQL-injection feature for the queries
that explicitly warrant this (PHPMyAdmin being a good example). Again, this
is only relevant if the website has been explicitly configured to use this
feature.

Matt

On 30 July 2015 at 14:43, Scott Arciszewski <sc...@paragonie.com> wrote:

> On Tue, Jul 28, 2015 at 1:33 PM, Matt Tait <matt.t...@gmail.com> wrote:
> > Hi all,
> >
> > I've written an RFC (and PoC) about automatic detection and blocking of
> SQL
> > injection vulnerabilities directly from inside PHP via automated taint
> > analysis.
> >
> > https://wiki.php.net/rfc/sql_injection_protection
> >
> > In short, we make zend_strings track where their value originated. If it
> > originated as a T_STRING, from a primitive (like int) promotion, or as a
> > concatenation of such strings, it's query that can't have been
> SQL-injected
> > by an attacker controlled string. If we can't prove that the query is
> safe,
> > that means that the query is either certainly vulnerable to a
> SQL-injection
> > vulnerability, or sufficiently complex that it should be parameterized
> > just-to-be-sure.
> >
> > There's also a working proof of concept over here:
> >
> > http://phpoops.cloudapp.net/oops.php
> >
> > You'll notice that the page makes a large number of SQL statements, most
> of
> > which are not vulnerable to SQL injection, but one is. The proof of
> concept
> > is smart enough to block that one vulnerable request, and leave all of
> the
> > others unchanged.
> >
> > In terms of performance, the cost here is negligible. This is just basic
> > variable taint analysis under the hood, (not an up-front intraprocedurale
> > static analysis or anything complex) so there's basically no slow down.
> >
> > PHP SQL injections are the #1 way PHP applications get hacked - and all
> SQL
> > injections are the result of a developer either not understanding how to
> > prevent SQL injection, or taking a shortcut because it's fewer keystrokes
> > to do it a "feels safe" rather than "is safe" way.
> >
> > What do you all think? There's obviously a bit more work to do; the PoC
> > currently only covers mysqli_query, but I thought this stage is an
> > interesting point to throw it open to comments before working to complete
> > it.
> >
> > Matt
>
> Hi Matt,
>
> > PHP SQL injections are the #1 way PHP applications get hacked - and all
> SQL
> > injections are the result of a developer either not understanding how to
> > prevent SQL injection, or taking a shortcut because it's fewer keystrokes
> > to do it a "feels safe" rather than "is safe" way.
>
> This may have been true at one point in time, but my own experience
> and the statistics collected by Dan Kaminsky of White Hat Security
> indicates that Cross-Site Scripting vulnerabilities are much more
> prevalent in 2015 than SQL Injection, especially in business
> applications. If Google has information that indicates that SQLi is
> still more prevalent than XSS, I'd love to see this data.
>
> In my opinion, SQL injection is almost a solved problem. Use prepared
> statements where you can, and strictly whitelist where you cannot
> (i.e. "ORDER BY {$column} ASC")
>
> Scott Arciszewski
> Chief Development Officer
> Paragon Initiative Enterprises <https://paragonie.com>
>

Reply via email to