URL エンコードといえば、N 年前の URL エンコードの脆弱性を思い出すかもしれません。私がインターネットに触れたとき、その抜け穴はとっくに消えていました。
もっと身近な話ですが、URL エンコードとは何でしょうか?インターネットからコピーした定義を見てください。
引用: URL エンコーディングは、ブラウザーがフォーム入力をパッケージ化するために使用する形式です。ブラウザはフォームからすべての名前と値を取得し、名前/値パラメーターのエンコード (送信できない文字の削除、データの並べ替えなど) を使用して、URL の一部として、または個別にサーバーに送信します。いずれの場合も、サーバー側のフォーム入力形式は次のようになります。
theName=Ichabod+Crane&gender=male&status=missing&headless=yes
URL エンコードは次の規則に従います。各名前と値のペアはアンパサンドで区切られます。 = 文字で区切られた形式から来ています。ユーザーが名前の値を入力しない場合でも、名前は表示されますが、値は表示されません。特殊文字 (つまり、漢字などの単純な 7 ビット ASCII ではない文字) は、パーセント記号 % を使用して 16 進数でエンコードされます。これには、=、&、% などの特殊文字も含まれます。
はは、実際、URL エンコーディングは文字の 16 進数の ASCII コードであることがわかりました。ただし、先頭に「%」を追加する必要があります。たとえば、「」の ASCII コードは 92、92 の 16 進値は 5c であるため、「」の URL エンコードは になります。では、中国語の文字の URL エンコードはどうなるのでしょうか?これは非常に簡単です。例を見てください。「Hu」の ASCII コードは -17670、16 進数は BAFA、URL エンコードは「%BA%FA」です。ははは、変換方法はわかりますね。
IE はアドレス バーに入力した数字以外の文字を自動的に URL エンコードに変換するため、通常は URL エンコードを使用しません。したがって、ブラウザーの場合、 http://blog.csdn.net/l%61ke2はhttp://blog.csdn.net/lake2と同等です (最初の URL の a を %61 に置き換えていることに注意してください)。あはは、誰かがデータベース名に「#」を追加して、ダウンロードされないようにすることを提案したことを覚えているかもしれません。なぜなら、IE は # に遭遇すると後続の文字を無視するからです。クラッキング方法は非常に簡単です。 # を URL エンコード # に置き換えます。当初、注入チェックを回避するために URL エンコードを使用しようとしましたが、サーバーが URL エンコードを文字に変換するため失敗しました。
待って、話が逸れたようです、はは、ごめんなさい :)
SQL インジェクションは現在非常に人気があるため、アンチインジェクション スクリプトを作成している人もいます。もちろん、考え方が違えば結果も大きく異なります。読者の皆様、以下の xxSQL ユニバーサル アンチインジェクション ASP バージョンのコードの一部をご覧ください。
Fy_Url=Request.ServerVariables("QUERY_STRING")
Fy_a=split(Fy_Url,"&")
redim Fy_Cs(ubound(Fy_a))
エラー時は次へ再開
Fy_x=0 から ubound(Fy_a) の場合
Fy_Cs(Fy_x) = left(Fy_a(Fy_x),instr(Fy_a(Fy_x),"=")-1)
次
Fy_x=0 の場合は ubound(Fy_Cs)
If Fy_Cs(Fy_x)<>"" then
If Instr(LCase(Request(Fy_Cs(Fy_x))),"and")<>0 then
Response.「エラーが発生しました!」と書き込みます。
応答.終了
終了の場合
終了の場合
次
このアイデアは、まず送信されたデータを取得し、境界として「&」を使用して名前と値のグループを取得して処理し、次に値に定義されたキーワードが含まれているかどうかを判断することです (ここでは簡単にするために「and」のみを残します)。そうなったら注射ですね。
一見、値を確認すると問題ないようです。ははは、価値的には問題ありませんが、名前はどうでしょうか?
その名前/値グループの値は、Request.ServerVariables("QUERY_STRING") から取得されます。ははは、申し訳ありませんが、ここで問題が発生しました。 Request.ServerVariables("QUERY_STRING") は、クライアントによって送信された文字列を取得するためのものです。ここでは、URL エンコードは自動的に変換されません。笑、名前を URL エンコードしてから送信すると、チェックをバイパスできます。たとえば、パラメータが ph4nt0m=lake2 および lis0 の場合、プログラムはこの時点でそれを検出できます。%50h4nt0m=lake2 および lis0 (URL エンコーディング p) を送信すると、プログラムは %50h4nt0m および %50h4nt0m の値を判断します。は ph4nt0m に変換されるため、 %50h4nt0m の値は空になり、検出がバイパスされます。
ちょっと待ってください。名前はデコードされていないのに、値はバイパスできないのに、なぜチェックはバイパスできるのでしょうか? value の値は Request(Fy_Cs(Fy_x)) から取得されるため、サーバーはそれをデコードします。
プログラムをどのように改善できるでしょうか?クライアントによって送信されたデコードされたデータを取得できる限り、名前を取得するステートメントを For Each SubmitName In Request.QueryString に変更するだけです。
笑、私の記事を辛抱強く読んでいただきありがとうございます^_^
lake2