彼らは次のようなことをするよりもSQLインジェクションに対して脆弱ではありませmysql_query("SELECT important_data FROM users WHERE password = $password")
んか?
5 に答える
彼らはあなたがしていることよりも安全です。クエリは生のSQLをdbに送信しています。これは、パラメータがsqlパラメータとしてではなく、単純な古いsqlとして扱われることを意味します。
これが私の言いたいことです。
保存されたプロシージャでは、パスワード変数をsqlにすることはできません。これは、システムが探している情報の一部である必要があります。あなたの例では、実際にデータベースに送信されるのは
SELECT * FROM User where password =('your password here'-$ Password variable).....誰かが次のようなことを行うことができます
SELECT * FROM user WHERE Password =('your password here'; SELECT * FROM User-$ password variable)。
またはさらに悪いことに:
SELECT * FROM user WHERE Password =('your password here'; DROP Database Database_Name-$ password variable)。
非動的SQLストアドプロシージャでは、入力パラメータが追加のSQLとして実行されないため、これは許可されません。
パラメータ化されたSQLはこれを処理しますが、テーブル内の情報にアクセスするユーザーは読み取りアクセスを必要としないため、技術的にストアドプロシージャはさらに安全です。ストアドプロシージャを実行できる必要があるだけです。必要に応じて、これが機能する場合と機能しない場合があります。
必ずしもそうとは限りませんが、その内部で文字列の連結を行うことができ、露出は同じになります。パラメータ変数を使用して動的SQLを使用する場合(SQLを生成するための文字列連結なし)、かなり十分に保護されます。
パラメータを使用し、ユーザーが入力した値に文字列連結を使用しない限り、SQLインジェクションのリスクはありません。ストアドプロシージャは、パラメータの使用を推奨するため、この点では少し「安全」です。しかし、手順であなたが次のようなことをした場合
EXECUTE 'SELECT important_data FROM users WHERE password = ' + @password
その後、正方形1に戻り、SQLインジェクションに対して非常に脆弱になります。
また、ストアドプロシージャではなく、パラメータを使用できる「プリペアドステートメント」などもあります。したがって、SQLインジェクションを回避するためにも使用できます。
安全な技術はありません。テクノロジーは、安全または危険な方法でのみ使用できます。
とは言うものの、ストアドプロシージャは、SQLインジェクションを許可するために、少しクリエイティブなコーディングを必要としますが、それでも発生します。私が知っているSQLデータベースエンジンでは、文字列を連結することを妨げるものは何もありません。
それらが正しくパラメーター化されていて、動的SQLを実行していない場合、それらはより安全であり、実行プランの再利用の恩恵も受けます。