Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:87673 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 18287 invoked from network); 7 Aug 2015 01:29:58 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 7 Aug 2015 01:29:58 -0000 Authentication-Results: pb1.pair.com header.from=yohgaki@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=yohgaki@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.160.175 as permitted sender) X-PHP-List-Original-Sender: yohgaki@gmail.com X-Host-Fingerprint: 209.85.160.175 mail-yk0-f175.google.com Received: from [209.85.160.175] ([209.85.160.175:33158] helo=mail-yk0-f175.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 08/31-06855-31A04C55 for ; Thu, 06 Aug 2015 21:29:56 -0400 Received: by ykoo205 with SMTP id o205so77852644yko.0 for ; Thu, 06 Aug 2015 18:29:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=VBC7wR2g8QFVHRu5QNhkuACPz+fRPIX3dc2cXghqa68=; b=fw1EdiGvn2E9NaWDrtr1PLOhmu404eZ1Rr7amhhfjsnATbd48Mg3vEPAwuGjQCQbeA ACXcfurJKZx33VAON1NDvn2GpVD3K42M7gSdFGKss4R+XEVxVmXWVZIJ6r+VI/CfNDLu KOI4BQlZOSl3Gr/wN6+ku22F713cS5l9z7hBmUJDGBpL1HwbSnnOJeR571FICVaWHmw1 S/XTsPcNgIPawx80WEdRXzZ1b3+uIj/9E1AkI++wKgMN93BU2f5a5S3UOMWCtQV7i5Ky +qhGmMfoGulhtInzwmuQBK7BR/xn2leAOcX5NrG0E6WBaGkgkkme+pUdRParDRi0a479 /9Ow== X-Received: by 10.129.103.193 with SMTP id b184mr5073745ywc.55.1438910992089; Thu, 06 Aug 2015 18:29:52 -0700 (PDT) MIME-Version: 1.0 Sender: yohgaki@gmail.com Received: by 10.129.81.87 with HTTP; Thu, 6 Aug 2015 18:29:12 -0700 (PDT) In-Reply-To: References: Date: Fri, 7 Aug 2015 10:29:12 +0900 X-Google-Sender-Auth: 9QJbD2pX3Fmw-EdgHcjExcgRMpw Message-ID: To: Matt Tait Cc: Anthony Ferrara , Julien Pauli , PHP Internals Content-Type: multipart/alternative; boundary=001a114908848c0923051cae92eb Subject: Re: [PHP-DEV] [RFC] Block requests to builtin SQL functions where PHP can prove the call is vulnerable to a potential SQL-injection attack From: yohgaki@ohgaki.net (Yasuo Ohgaki) --001a114908848c0923051cae92eb Content-Type: text/plain; charset=UTF-8 Hi Matt, On Thu, Aug 6, 2015 at 12:46 PM, Matt Tait wrote: > I'll take a few of your points in turn. > > With regards to the fact that not all SQL queries are directly > parameterizable, this is true. Structural parts of a query, such as table > names, column names and complex conditions are hard to parameterize with > "vanilla" prepared statements, and many developers like to abstract some of > these structural parts of a SQL query into config files, and append > additional conditional constraints into the query at runtime based on user > input. > > This feature addresses this head on. So long as the structural parts of the > prepared statement -- that is, table names, database names and column names > -- are not themselves attacker-controlled (I can't think of a valid reason > whey they would be), this feature is happy for developers to concatenate > them into a query string. For example, the following is not detected by the > feature as dangerous, because the query (whilst dynamically constructed) is > the linear concatenation of string literals, and so is a safeconst. > > $query = "SELECT * from {$config['tablename']} WHERE id=?"; > if(isset($_GET["filterbycolor"])) > $query .= " AND color=?"; > do_prepared_statement($query, array("id" => $_GET["id"] "color" => > $_GET["color"])); > If you would like to prevent SQL injection via "Identifiers", how about extend prepared query like $query = "SELECT * from @ WHERE id=?"; if(isset($_GET["filterbycolor"])) $query .= " AND color=?"; do_prepared_statement($query, array("id" => $_GET["id"] "color" => $_GET["color"]), array($config['tablename'])); where @ indicates identifier placeholder. The char could be anything that will not violate SQL syntax. This could be implemented in user land as there is no standard/native API for identifier placeholder. Even if there is identifier placeholder, SQL keyword remains. So to be perfect, you'll need another place holder for SQL keywords. There is no escaping for SQL keywords and it has to be validation. e.g. ORDER BY {$_GET['order']} Regards, -- Yasuo Ohgaki yohgaki@ohgaki.net --001a114908848c0923051cae92eb--