SQL ServerのSQLインジェクションでシングルクォートをエスケープするサニテーションはどのように破られるのでしょうか?
質問
まず始めに、パラメータ化されたクエリが最良の選択肢であることは十分承知していますが、私が以下に提示する戦略を脆弱にするものは何なのかを尋ねています。人々は以下のソリューションが機能しないと主張しているので、私はなぜそれが機能しないかの例を探しています。
動的 SQL が SQL サーバーに送信される前に以下のエスケープを使用してコードで構築されている場合、どのような種類のインジェクションがこれを打ち負かすことができますか?
string userInput= "N'" + userInput.Replace("'", "''") + "'"
同様の質問には ここで にも回答がありましたが、どの回答もここに当てはまるとは思えません。
シングルクォートを" \" でエスケープすることは、SQL Serverではできません。
私は SQLスマグリング をUnicodeで使用することができます(概要 ここで を使用した場合、生成される文字列がシングルクォートの前のNによってUnicodeとしてマークされるため、妨害されることになります。私の知る限り、SQL Serverが自動的にシングルクォートに変換するような他の文字セットは存在しません。エスケープされていない単一引用符がなければ、インジェクションが可能であるとは思えません。
私は
文字列の切り捨て
は実行可能なベクトルであると信じています。SQL Server は確かに切り捨てを行いません。
nvarchar
の最大サイズは 2GB です。
マイクロソフトによると
. 2GB の文字列はほとんどの状況で実現不可能であり、私の場合は不可能です。
二次射出 は可能かもしれないが、もし可能なら。
- データベースに入るすべてのデータは、上記の方法でサニタイズされます。
- データベースからの値は決して動的 SQL に追加されません (動的 SQL 文字列の静的部分でテーブルの値を参照できるのに、なぜそんなことをするのでしょうか?)。
私は、これがパラメーター化されたクエリを使用するより良い、または代替であると提案しているわけではありませんが、私が概説したものがどのように脆弱であるかを知りたいのです。何かアイデアはありますか?
どのように解決するのですか?
このエスケープ関数が失敗するケースがいくつかあります。 最も明白なのは、シングルクォートが使用されていない場合です。
string table= "\"" + table.Replace("'", "''") + "\""
string var= "`" + var.Replace("'", "''") + "`"
string index= " " + index.Replace("'", "''") + " "
string query = "select * from `"+table+"` where name=\""+var+"\" or id="+index
この場合、ダブルクオート、バックチックを使って、"break out"することができます。 最後のケースでは、quot;break out"するものがないので、次のように書くだけです。
1 union select password from users--
と書くか、攻撃者が望むどんなSQLペイロードでも書くことができます。
このエスケープ関数が失敗する次の条件は、文字列がエスケープされた後に部分文字列が取られる場合です(そして はい 私はこのような脆弱性を実際に発見しています)。
string userPassword= userPassword.Replace("'", "''")
string userName= userInput.Replace("'", "''")
userName = substr(userName,0,10)
string query = "select * from users where name='"+userName+"' and password='"+userPassword+"'";
この場合、ユーザー名は
abcdefgji'
は次のようになります。
abcdefgji''
に変換され、その後、エスケープ関数によって
abcdefgji'
に戻されます。 これを利用するには、任意のSQL文にパスワードの値を設定することで、この場合
or 1=1--
はSQLと解釈され、ユーザ名は
abcdefgji'' and password=
. 結果として、以下のようなクエリが生成されます。
select * from users where name='abcdefgji'' and password=' or 1=1--
T-SQLやその他の高度なSQLインジェクション技術については、すでに述べたとおりです。 SQL Serverアプリケーションにおける高度なSQLインジェクション は素晴らしい論文なので、まだ読んでいないのであれば読むべきです。
最後の問題は、ユニコード攻撃です。 このクラスの脆弱性は、エスケープ関数がマルチバイトのエンコードを認識しないために発生します。 を使用して、エスケープ文字を消費することができます。 . 文字列に "N" を追加しても、文字列内の後のマルチバイト文字の値には影響しないため、役に立ちません。 しかし、データベースが GBK ユニコード文字列を受け入れるように構成されていなければならないため、このタイプの攻撃は非常にまれです (そして MS-SQL がこれを実行できるかどうかはわかりません)。
二次コード注入はまだ可能です。この攻撃パターンは、攻撃者が制御するデータソースを信頼することによって作成されます。 エスケープは、制御文字をその文字リテラルとして表現するために使用されます。 から取得した値をエスケープするのを忘れた場合、開発者は、その値を文字リテラルとして表現することができます。
select
そして、この値を別のクエリで使用する場合
バム
とすると、攻撃者は文字リテラルであるシングルクォートを自由に使えるようになります。
すべてをテストし、何も信用しない。
関連
-
[解決済み] SQL ServerでSELECTからUPDATEする方法とは?
-
[解決済み] PHPでSQLインジェクションを防ぐにはどうしたらいいですか?
-
[解決済み] SQL Server で複数行のテキストを 1 つのテキスト文字列に連結する方法
-
[解決済み] SQL Server テーブルにカラムが存在するかどうかを確認する方法は?
-
[解決済み] SQL Server の DateTime データ型から日付だけを返す方法
-
[解決済み] SQL ServerでJOINを使用してUPDATE文を実行するにはどうすればよいですか?
-
[解決済み] SQL Serverでシングルクォートをエスケープするにはどうすればよいですか?
-
[解決済み] SQL ServerでINNER JOINを使用して削除するにはどうすればよいですか?
-
[解決済み】XKCDコミック「Bobby Tables」のSQLインジェクションはどのように動作するのでしょうか?
-
[解決済み] シングルクォートをエスケープし、ユーザー入力をシングルクォートで囲むことで、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 Server データベース復元エラー:指定されたキャストは有効ではありません。(SqlManagerUI)
-
[解決済み] FOREIGN KEY制約で参照されているため、テーブルを切り捨てることができないのですか?
-
[解決済み] sql文の角括弧[]の使い方を教えてください。
-
[解決済み] パーセント値を保持するための適切なデータ型?
-
[解決済み] SSIS - データ損失の可能性があるため、値を変換することはできません。
-
[解決済み] 階層テーブルの設計
-
[解決済み] SSISで新しいレコードを挿入する前に、宛先テーブルを空にするにはどうすればよいですか?
-
[解決済み] SQL ServerにおけるXOR
-
[解決済み] シングルクォートをエスケープし、ユーザー入力をシングルクォートで囲むことで、SQLインジェクションから保護することができますか?
-
SQL Serverに200万行をすばやく挿入する。