2016-12-20 8 views
-1

背景:Symfony2でSQLExを保護するには、DoctrineではなくDBALとPDO_MySQLだけを使用しますか?

私は元のコードは、MySQLiをデータベースと対話するCI」クエリビルダの、多くのいくつかを使用しますが、ないここで、Symfony2の、V2.8にexsiting CodeIgniterのプロジェクトを変換しています。

新しいSymfony2バージョンでは、MySQLiからPDO_MySQLに移行する必要があります.PDO_MySQLの上にいくつかの優れた機能が追加されているため、DBALを使用することにしました。 CodeIgniterのバージョンが完全で、私はデータベースを含む元のコードをそれほど変更したくないので、私はDoctrineをフル実装できません。

DBALの準備が整った文はSQLi(SQL Injection)の「SAFE」(1)と見なされていますが、Doctrine DBALのドキュメントの第4節の4. Data Retrieval And Manipulationでは、 DBALは、SQL文を強化し、彼らはやSQLIから「安全」であってもなくてもよいことを示していると思われる:。

「デフォルトではDoctrine DBALは一切エスケープしませんエスケープは、自動的に行うには非常に トリッキーなビジネスですORMは現在のコンテキストに関して利用可能なメタデータの数が であるため、すべての値を内部的にエスケープします。 Doctrine DBALをスタンドアローンとして使用すると、自分でこれを処理する必要があります。

(1)私が聞いたことから、Anti-SQLiテクニックは100%安全ではありませんが、どのツールを使用しているかは私ができるほど良いので、SAFEという言葉を引用しています。

質問:次の文は安全であるか、私は唯一のプリペアドステートメントを使用する必要がない場合

誰かが明確に教えてくださいますか? 「安全」です

1)プリペアドステートメント -

$conn = $this->get('database_connection'); 
$sql = "SELECT * FROM users WHERE id = ? AND activation_code = ? AND active = 1"; 
$stmt = $conn->prepare($sql); 
$stmt->bindValue(1, $id); 
$stmt->bindValue(2, $code); 
$stmt->execute(); 

用意し、結合したクエリを実行するために、私はまた、型情報の配列を追加したい場合、私はまた、次のステートメントを使用することができると信じて明示的なbindValueステートメントを削除します。

$conn->executeQuery($sql, [ $id, $code ], $types); 

私はタイプ情報は、必要に応じて同様に、各bindValue文で添加することができることを知っているが、のexecuteQuery文で、配列オプションであり、位置的または連想整理種類がありますか?

同様に、私は、INSERT、UPDATE、およびDELETE SQLステートメントでも、executeステートメントまたはexecuteUpdateステートメントを使用して同じことを行うことができます。DBALの強化文の上に今

、:

私は実際には、明示的な準備/ bindValue方法で行く上で示したが、その代わりにこれらの短い状態、EMTSと一緒に行きましたしませんでした:SELECTの

$data = $conn->fetchAssoc('SELECT * FROM users WHERE username = ?', [ $username ]); 

$data = $conn->fetchColumn('SELECT username FROM users WHERE email = ?', [ $email ], 0); 

$data = $conn->fetchAll('SELECT `groups`.id, `groups`.name ' . 
          'FROM `users_groups` LEFT JOIN `groups` ' . 
          'ON `users_groups`.group_id = `groups`.id ' . 
          'WHERE `users_groups`.user_id = ?', [ $user_id ]); 

および更新のために:

$conn = $this->get('database_connection'); 
$where = [ 'id' => $user_id ]; 

if($code !== FALSE) 
    $where[ 'forgotten_password_code' ] = $code; 

$data = array(
    'password'    => $this->hash_password($password), 
    'forgotten_password_code' => NULL, 
    'forgotten_password_time' => NULL); 

$result = ($conn->update('users', $data, $where) === 1); 

I H削除は実行されませんが、delete文は同じパターンに従います。

これらの拡張ステートメントはSQLi 'SAFE'ですか、それとも明示的に引用またはエスケープする必要がありますか?

$ conn-quote($ var)を追加しようとしました。データ配列要素の値の代入と拡張SQL文の中のステートメントを示していますが、挿入の場合は実際にはデータベースに挿入された各値の最初と最後に一重引用符が追加されます私はすでにCodeIgniterのデータベースを持っているので、引用符はありません。つまり、引用されたデータを使用した新しいSELECT文が見つかりませんでした。

私はオプションのデータ型引数を使用しませんでした。それでシングルクォートが新しいインサートに保存されたのはなぜですか?そうでなければ、$ conn-> quote()文をDBAL拡張SQL文とともに使用する必要があるかどうかを本当に知る必要があります。なぜなら、quote文を使用する必要があれば、単一引用符を追加する必要があるからですすべての文字列データに適用されます。この場合、文字列以外のデータ列はどうですか?

私はエスケープについて話をしましたが、DBALステートメントが動作するかどうかは不明です。ドキュメントではそのことについて話していないためです。

ありがとうございます。

+0

「SQLi」は、ウィキペディアがそうでないと思われる場合でも、この種の一般的な略語ではありません。 SQLインジェクションは、XSSなどの一般的なエスケープ/インジェクションのバグの特別なケースです。 – tadman

+0

SQLiについての説明をもう一度ありがとうございます。どうやら、この誤った省略形はWikipediaよりも広がっています。なぜなら、ここではStackOverflowやその他の場所で使用されているのを見てきたからです。実際には正しいとは言えませんが、使用はそこにあるようです。 –

+0

ええ、それは伝染病のようなものです。私たちは "注射"のような短い言葉に頭文字を必要としません。 – tadman

答えて

0

プレースホルダ値を持つプリペアドステートメント、またはこの場合は同様の機能を提供するORMレイヤを使用することについて訓練を受けている場合は、インジェクションバグから保護されます。

生データを入力してクエリに入力すると、すべてのベットがオフになります。以下の点を考慮してください。

// This is safe 
$conn->fetchAssoc('SELECT * FROM users WHERE username = ?', $user); 

// This is DANGEROUSLY unsafe 
$conn->fetchAssoc("SELECT * FROM users WHERE username = '$user'"); 

これらの2つの方法は視覚的に似ていますが、1つは大きな穴です。このため、私は、この種のクエリを作成するときに一重引用符を使用することを強く推奨しています。偶然、文字列補間を取得しません。あなたはこの種のミスを見つけることがより良いことができます単一引用符を使用するのが習慣に取得した場合

// Syntax error, easy to spot 
$conn->fetchAssoc('SELECT * FROM users WHERE username = '$user''); 

// Tests against the literal string "$user" 
$conn->fetchAssoc('SELECT * FROM users WHERE username = "$user"'); 

:その場合、あなたはこの壊れたが、無害なコードを取得します。

+0

ありがとうございます。なぜ私の質問は、マークダウンを取得したのですか? –

+0

一重引用符についてのあなたのコメントに関して、それは指摘するのは良いことです。良いニュース私はすでにそれをしています。 –

+0

ステートメントは安全で何が何であるかに関しては、私が尋ねたそれぞれについて明確な回答が必要です。しかし、fetchAssocを使用しているので、明示的なbindValueステートメントを使用する最初の2つは安全であると推測しています。 –

関連する問題