Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:87346 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 22310 invoked from network); 28 Jul 2015 17:33:37 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 28 Jul 2015 17:33:37 -0000 Authentication-Results: pb1.pair.com header.from=matt.tait@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=matt.tait@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.160.182 as permitted sender) X-PHP-List-Original-Sender: matt.tait@gmail.com X-Host-Fingerprint: 209.85.160.182 mail-yk0-f182.google.com Received: from [209.85.160.182] ([209.85.160.182:36244] helo=mail-yk0-f182.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 22/00-22108-EECB7B55 for ; Tue, 28 Jul 2015 13:33:34 -0400 Received: by ykay190 with SMTP id y190so101548751yka.3 for ; Tue, 28 Jul 2015 10:33:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=Ad394zr6bAN7FeiMlNImIDwRVcSTg6FybTNmS6uHPGU=; b=snusGH31Ngno1D5IWMobJJ8vB9Rapo6WPO6CgmUfQI3VTxgpM68JL9iUdbuT7A0Ih/ HIl+Kn7l1oeKJ4QJKS5pEw4hzTj19N0JPmRLjtVajZzmgaCAgoEFIC/kkyrgChR+zf5f XfFcvXiruhKqimqvOcwxPhFlj5FQlECgnoYYDZnhGLhiF1UOOAJwMdy32hzLqbFVykjO +lvdXuNgMyPeSBULekigA6L8Tj6jAGQta0gYyqv4TUKg+KZfurCMORIrJdS+TmhVgJf7 Dkfs88ozwDjitWpxGNK2V0jRtHqFrR5/Ze0pfEftBD2j4BGBmN9IQNmp91BKXWUy6mOC hXTA== MIME-Version: 1.0 X-Received: by 10.170.153.85 with SMTP id u82mr26841825ykc.53.1438104811428; Tue, 28 Jul 2015 10:33:31 -0700 (PDT) Received: by 10.37.98.203 with HTTP; Tue, 28 Jul 2015 10:33:31 -0700 (PDT) Date: Tue, 28 Jul 2015 18:33:31 +0100 Message-ID: To: internals@lists.php.net Content-Type: multipart/alternative; boundary=001a113b396e6f6315051bf2dea8 Subject: [RFC] Block requests to builtin SQL functions where PHP can prove the call is vulnerable to a potential SQL-injection attack From: matt.tait@gmail.com (Matt Tait) --001a113b396e6f6315051bf2dea8 Content-Type: text/plain; charset=UTF-8 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 --001a113b396e6f6315051bf2dea8--