From 47ec016b43a6976d9fe12dc9c7b58b154247ef89 Mon Sep 17 00:00:00 2001 From: ndm2 Date: Wed, 26 Apr 2017 16:19:02 +0200 Subject: [PATCH] Enhance SQL injection prevention section. --- en/orm/database-basics.rst | 2 ++ en/orm/query-builder.rst | 40 ++++++++++++++++++++++++++++++++++++++ fr/orm/database-basics.rst | 2 ++ ja/orm/database-basics.rst | 2 ++ 4 files changed, 46 insertions(+) diff --git a/en/orm/database-basics.rst b/en/orm/database-basics.rst index 5dcfb49953..453f2b8d51 100644 --- a/en/orm/database-basics.rst +++ b/en/orm/database-basics.rst @@ -712,6 +712,8 @@ While ``prepare()`` returns an incomplete statement:: Once you've prepared a statement you can bind additional data and execute it. +.. _database-basics-binding-values: + Binding Values -------------- diff --git a/en/orm/query-builder.rst b/en/orm/query-builder.rst index 01808c04ff..6473e714e2 100644 --- a/en/orm/query-builder.rst +++ b/en/orm/query-builder.rst @@ -1298,6 +1298,22 @@ SQL Injection Prevention While the ORM and database abstraction layers prevent most SQL injections issues, it is still possible to leave yourself vulnerable through improper use. + +When using condition arrays, the key/left-hand side as well as single value +entries must not contain user data:: + + $query->where([ + // Data on the key/left-hand side is unsafe, as it will be + // inserted into the generated query as-is + $userData => $value, + + // The same applies to single value entries, they are not + // safe to use with user data in any form + $userData, + "MATCH (comment) AGAINST ($userData)", + 'created < NOW() - ' . $userData + ]); + When using the expression builder, column names must not contain user data:: $query->where(function ($exp) use ($userData, $values) { @@ -1320,6 +1336,30 @@ Raw expressions are never safe:: $expr = $query->newExpr()->add($userData); $query->select(['two' => $expr]); +Binding values +-------------- + +It is possible to protect against many unsafe situations by using bindings. +Similar to :ref:`binding values to prepared statements `, +values can be bound to queries using the :php:meth:`Cake\\Database\\Query::bind()` +method. + +The following example would be a safe variant of the unsafe, SQL injection prone +example given above:: + + $query + ->where([ + 'MATCH (comment) AGAINST (:userData)', + 'created < NOW() - :moreUserData' + ]) + ->bind(':userData', $userData, 'string') + ->bind(':moreUserData', $moreUserData, 'datetime'); + +.. note:: + + Unlike :php:meth:`Cake\\Database\\StatementInterface::bindValue()`, + ``Query::bind()`` requires to pass the named placeholders including the + colon! More Complex Queries ==================== diff --git a/fr/orm/database-basics.rst b/fr/orm/database-basics.rst index 0c79811f5f..f09adaa02b 100644 --- a/fr/orm/database-basics.rst +++ b/fr/orm/database-basics.rst @@ -762,6 +762,8 @@ incomplète:: Une fois que vous avez préparé une requête, vous pouvez lier les données supplémentaires et l'exécuter. +.. _database-basics-binding-values: + Lier les Valeurs ---------------- diff --git a/ja/orm/database-basics.rst b/ja/orm/database-basics.rst index bd78fe87fb..978552c549 100644 --- a/ja/orm/database-basics.rst +++ b/ja/orm/database-basics.rst @@ -702,6 +702,8 @@ CakePHP のデータベース抽象化レイヤは、PDO とネイティブド SQL 文を準備したら、あなたは追加のデータをバインドし、それを実行することができます。 +.. _database-basics-binding-values: + 値をバインドする ----------------