SQLインジェクションとその防止、マイベイトの基本的な役割について
SQLインジェクション
SQLインジェクションとは、SQLの構文を利用して、文字列に悪意のあるコードを追加し、不正なデータを取得することです。
例えば、あるユーザーがログインした場合(ユーザー名はadmin、パスワードは123456とする)、通常、次のような文が判断材料になります。
select * from user where username='admin' and password='123456'
レコードが検索された場合はログインが許可され、そうでない場合は "ユーザー名が存在しないか、パスワードが正しくありません" と表示されます。ユーザーのパスワードがわからない、ユーザー名は"admin"であることがわかっている、ユーザー名を入力すると、ユーザー名をadmin'--に変更する、と追加すると、sql文は、次のようになります。
select * from user where username='admin'-- and password='123456'
すると、ログインに成功する。パスワードは以下のようにランダムに入力され、SQLインジェクションを防ぐために何もしなければ、ログインは完全に成功します。
としたらどうでしょう。ユーザー名に "admin; drop table user; -" と入力したら、どうなりますか?
SQLインジェクションを防止する方法
JDBCはSQLインジェクションを防ぐためにPreparedStatementを提供しています。PreparedStatementがSQLをプリコンパイルした後、SQL文のパラメータを代わりに?に置き換えることが必要です。その後、setXX()メソッドを呼び出して、sql文のパラメータを設定します。このようにすれば、特殊な値を渡しても、SQLインジェクションの問題は発生しません。
String sql="select * from user where username='? "+" and password='? ";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1,"admin");
pstmt.setString(2,"123456");
//5. Execute the statement
ResultSet rs=pstmt.executeQuery(sql);
ストアドプロシージャにSQL文を記述し、ストアドプロシージャを介してクエリを完成させる方法もあり、この場合もSQLインジェクションを防止することができます。
マイベットでの${}と#{}の使用について
また、ユーザ名がadmin、パラメータ変数がsnameのような変数の場合は、引用符で囲みません。
select * from user where username='${sname}'
-- In this case, the SQL statement that the high-level language gives to the database is
select * from user where username='admin'
この場合、SQLインジェクションを防ぐ方法はありません。
#はプレースホルダーです。データベース管理システムでのみ "#{}" を使用し、#{} 内のパラメータを
select * from user where username=#{sname}
-- In this case, the SQL is first pre-compiled as follows, and then the parameters are brought in, with single quotes around the values
select * from user where username=?
このケースはSQLインジェクションに対して保護されています
もし#{}がSQLインジェクションを防ぎ、"$ {}"が防げないなら、なぜmybaitsはそのようなシンボルを提供するのでしょうか?SQL文中のデータベースオブジェクトをパラメータとして渡す必要がある場合、** ${}**を使うmyBatisなりの理由があることは確かです。例えば、userテーブル(user)にパラメータ変数tableName='user'を指定して問い合わせる場合、コードは以下のようにしかなりません。
select * from ${tableName}
// Convert to SQL as
select * from user
myBatisでは変数はwhere句のパラメータとして使用され、すべて#{}を使用し、"の使用を禁止する;"SQLインジェクションを防ぐために、データベースオブジェクト(テーブル、ビューなど)を含むSQLステートメントは"のみ使用できます;{} " SQL注入を防ぐために、データベースオブジェクト(テーブル、ビューなど)を含むSQLステートメントは。 SQLインジェクションを防ぐために、""の前にSQL文は、データベースオブジェクト(テーブル、ビューなど)が含まれています"{}"が使用できるため、#{}、自動的に上記の例のように、変数にクォートを入れてください。
select * from #{tableName}
// Convert to SQL statement as
select * from 'user'
<リンク
関連
-
Spark SQL 2.4.8 データフレームを操作するための2つの方法
-
SQL Server 2017がサーバーに接続できない問題解決
-
Filestreamの簡単な使い方まとめ
-
mybatis動的SQLの共通シナリオのまとめ
-
NavicatはSQL Serverのデータに接続します。エラー08001に対する完璧な解決策 - Named Pipeline Provider
-
SQL Server のフィルタードインデックスによるクエリ文の改善に関するパフォーマンス分析
-
SqlServerデータベースリモート接続ケースチュートリアル
-
SQL SERVERのコミット・トランザクションのロールバック機構
-
SQLServerのエラーです。15404, unable to get information about Windows NT group/user WIN-8IVSNAQS8T7Administrator
-
SQL クエリ結果カラムのカンマ区切り文字列へのステッチング法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
あるユーザーの連続ログイン日数を求めるSQLクエリ
-
SQL Server2017では、IPをサーバー名としてサーバーに接続します。
-
SQL Server一括挿入データ事例詳細
-
SQL ServerのSELECT INTOとINSERT INTOのSELECTのケースを説明する
-
SQLの書き方--行ごとの比較
-
SQL Serverでの判定文(IF ELSE/CASE WHEN)の使用例
-
SQLServerにおけるJSONドキュメント型データのクエリ問題を解決する。
-
SQLサーバーのデータベースで、SAユーザーがロックされている問題を解決する
-
sql serverで最初の1000行のデータを削除する方法の例
-
Spark SQLの全体的な実装ロジックの説明