web-dev-qa-db-ja.com

Knex.jsはSQLインジェクションを防ぎますか?

私はMySqlデータベースを使用していて、tedious.js(SQLサーバーのパラメーター化されたクエリビルダー)のMySQLの代替を見つけようとしていました。バックエンドにNode.jsを使用しています。

Knex.jsの.raw()コマンドは、バインディングで使用しないと、SQLインジェクションの影響を受けやすいと読みました。しかし、SQLインジェクションを防ぐために使用する他のコマンドとknex.js全体は安全ですか?それとも間違った木をbarえていますか?

11
Harsh Saudagar

Knex raw( http://knexjs.org/#Raw )に値を渡す方法をknexのドキュメントから注意深くお読みください。

次のようなrawにパラメーターバインディングとして値を渡す場合:

knex.raw('select * from foo where id = ?', [1])

その場合、パラメーターとクエリ文字列は、SQLインジェクションからクエリを保護するデータベースドライバーに個別に渡されます。

他のクエリビルダメソッドは、内部で常にバインド形式を使用するため、安全です。

特定のクエリがデータベースドライバにどのように渡されるかを確認するには、次のようにします。

knex('foo').where('id', 1).toSQL().toNative()

クエリを実行するためにドライバーに与えられるSQL文字列とバインディングを出力します( https://runkit.com/embed/2yhqebv6pte6 )。

Knex rawクエリでできる最大の間違いは、javascriptテンプレート文字列を使用して、変数を次のようなSQL文字列形式に直接補間することです。

knex.raw(`select * from foo where id = ${id}`) // NEVER DO THIS 

注意すべきことの1つは、knexテーブル/識別子名をバインディングとしてドライバーに渡すことができないことです。そのため、ユーザーからテーブル/列名を読み取らず、それらを適切に検証せずに使用しないように特に注意する必要があります。

編集:

識別子名をバインディングとして渡すことはできないと言うことで、?? knex-識別子名のバインディング。データベースドライバに渡されるときにSQL文字列の一部としてレンダリングされます。

31
Mikael Lepistö