php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74220 Special crafted SQL statement trips PDO
Submitted: 2017-03-07 22:34 UTC Modified: -
Votes:3
Avg. Score:4.0 ± 0.8
Reproduced:3 of 3 (100.0%)
Same Version:3 (100.0%)
Same OS:2 (66.7%)
From: mfischer@php.net Assigned:
Status: Open Package: PDO PgSQL
PHP Version: 7.1.2 OS: Ubuntu 14.04
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: mfischer@php.net
New email:
PHP Version: OS:

 

 [2017-03-07 22:34 UTC] mfischer@php.net
Description:
------------
I initially reported this at https://github.com/cakephp/cakephp/issues/10373 but was told "If you can reproduce this issue with raw PDO, then its not a CakePHP issue."

The provided SQL statement, as executed with PDO, does not insert the provided data correctly.

Prerequisites: create a db role / database table:

postgres=# create role username login password 'password';
CREATE ROLE
postgres=# create database db owner username;
CREATE DATABASE
postgres=# \c db
You are now connected to database "db" as user "postgres".
db=# set role username;
SET
db=> create table models(field varchar(12));
CREATE TABLE

The provided SQL statement (see test script) is valid Postgres syntax.

Test script:
---------------
<?php
$pdo = new PDO('pgsql:host=localhost;dbname=db', 'username', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = <<<SQL
INSERT INTO models (field) values('\'':1');
SQL;
$pdo->query($sql);

$result = $pdo->query('SELECT * FROM models');
var_dump($result->fetchAll());

Expected result:
----------------
array(1) {
  [0]=>
  array(2) {
    ["field"]=>
    string(4) "\':1"
    [0]=>
    string(4) "\':1"
  }
}


Actual result:
--------------
array(1) {
  [0]=>
  array(2) {
    ["field"]=>
    string(4) "\'$1"
    [0]=>
    string(4) "\'$1"
  }
}


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-03-08 12:14 UTC] mfischer@php.net
Not sure if I missed something obvious. For now I found multiple ways to
make it work:

1. use prepared statements (i.e. use :name or ? placeholder, etc.)
2. set the PDO flag PDO::ATTR_EMULATE_PREPARES to true
3. apply pgsql C-Style escape syntax [1], i.e. VALUES(E'\\'':1)


About 2): this worked for simple cases but failed in a large
application, didn't yet investigate why

About 3): haven't dug deeper whether this can cause more troubles or not

[1]
https://www.postgresql.org/docs/9.6/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Nov 23 07:01:29 2024 UTC