前回の記事で、プログラマーによる不適切なコーディングによって引き起こされる SQL インジェクション攻撃の脆弱性の本質について説明しました。今回は、その前に、SQL インジェクションの攻撃を受けないように正しくコーディングする方法について説明します。問題 まずコードの一部を見てみましょう。
次のようにコードをコピーします。
dim sql_injdata,SQL_inj,SQL_Get,SQL_Data,Sql_Post
SQL_injdata = '|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare
SQL_inj = split(SQL_Injdata,|)
If Request.QueryString<> then
各 SQL_Get In Request.QueryString
SQL_Data=0 の場合、Ubound(SQL_inj) へ
if instr(Request.QueryString(SQL_Get),Sql_Inj(Sql_DATA))>0 then
Response.Write <Script Language=javascript>alert('SQL アンチインジェクション システム プロンプトが表示されます。再度インジェクトしないでください!');
応答.終了
終了する場合
次
次
終了の場合
If Request.Form<> then
Request.Form の各 Sql_Post について
SQL_Data=0 の場合、Ubound(SQL_inj) へ
if instr(Request.Form(Sql_Post),Sql_Inj(Sql_DATA))>0 then
Response.Write <Script Language=javascript>alert('SQL アンチインジェクション システム プロンプトが表示されます。再度インジェクトしないでください!');
応答.終了
終了する場合
次
次
終了する場合
これは、インターネット上で広く普及している ASP アンチインジェクション コードの一部で、Post メソッドと Get メソッドによって送信されたデータをチェックし、Insert、Update、And などの機密文字をフィルタリングすることで SQL インジェクションを防止するというものです。 , など。理論的には、十分な文字をフィルタリングすれば、SQL インジェクションの攻撃を受けないことは確実に保証できますが、注意してください。このコードを読んで、instr 関数によってどのように判断されるかに注目してください。つまり、and という文字をフィルタリングしたい場合、And という単語だけでなくすべての単語がフィルタリングされます。 and を含む次の文字の組み合わせを含むすべての単語が除外されました (island、mainland、hand など)。これらの文字が除外されたとしても、まだ使用したいと思う人はいるでしょうか。したがって、センシティブな文字をフィルタリングするこの方法はまったく意味がありません。驚くべきことは、このようなゴミが実際に古典としてインターネット上に投稿されていることです。
SQL インジェクション攻撃は SQL クエリ文字列の結合によって引き起こされるため、SQL クエリ文字列を結合せずにストアド プロシージャを使用すると SQL インジェクション攻撃から保護できるという人もいます。これは本当ですか?必ずしもそうとは限りませんが、ストアド プロシージャ インジェクション攻撃の例を見てみましょう。
ストアド プロシージャ dt_GetNews のコードは次のとおりです。
プロシージャの作成 dt_GetNews
@newstype int
として
select * from news where newstype=@newstype
行く
呼び出しコード:
<%
薄暗い接続
set adoconnection=server.createobject(adodb.connection)
'....データベース接続を確立するための関連コードはここでは省略されています
adoconnection.execute exec dt_GetNews +request(ニュースタイプ)
adoconnection.close
%>
request(newstype) の値が 1 の場合、操作の結果は、ニュース テーブルの newstype フィールドが 1 であるすべてのレコードを返します。ただし、request(newstype) の値が 1 の場合、テーブル ニュースは削除されます。 、返された結果は、ニュース テーブルが削除されたことです。
この例から、ストアド プロシージャを使用しても依然として攻撃を受けることがわかります。さらに、newstype=@newstype がスプライシングされていない場合、select * from news は SQL クエリ文字列のスプライシングと SQL インジェクション攻撃の間に必然的な関係はありません。ストアド プロシージャはインジェクション攻撃から保護できない可能性があります。
では、SQL インジェクションの攻撃を受けずに記述するにはどうすればよいでしょうか? 以下に究極の方法を紹介します。それは、単刀直入に言うと、データ型の検証とシングルクォーテーションの置換です。 Oracle、SQL Server、mySql、Access、その他のリレーショナル データベースのいずれであっても、フィールド タイプは、数値タイプ (int、float など) と文字タイプ (char、varchar など) の 2 つのカテゴリに大別できます。 ) 対応する SQL ステートメントは、次のようにフィールドの種類に応じて若干異なります。
「Select * from news where newstype=1」の newstype フィールドは数値フィールドである必要があります。
select * from news where newstype='social news' ニュースタイプ フィールドは文字フィールドである必要があります。
数値フィールドの場合、パラメータのデータ型を確認する必要があります。たとえば、select * from news where newstype=+v_newstype を使用してクエリ ステートメントを構築する場合、v_newstype 変数のデータ型を確認する必要があります。少なくとも数値である必要があり、整数または浮動小数点数にすることができます。このようなチェックが行われる場合、select * from news where newstype=+v_newstype は、select * from news where newstype=1 と同様のものを構築することはありません。 ;落とすテーブルニュースのような発言。 ASP が ASP.Net や JSP などに比べて攻撃を受けやすい理由は、ASP では変数を宣言する必要がなく、変数の型が不明瞭であるためです。
文字フィールドの場合、一重引用符 (') を処理する必要があります。処理方法は、1 つの一重引用符を 2 つの一重引用符 ('') に置き換えることです。たとえば、 select * from news where を使用します。 newstype='+v_newstype+' を使用してクエリ ステートメントを作成する場合、v_newstype の一重引用符は 2 つの一重引用符で置き換える必要があります。これは、SQL では 2 つの一重引用符で囲まれた部分が文字列を表し、2 つの連続する単一引用符で囲まれた部分が表されるためです。 quote は単一引用符文字を表します。このような処理の後、v_newstype の値が次の場合の select * from news where newstype='+v_newstype+' の構築方法を見ていきます。
ソーシャル ニュース';ドロップ テーブル ニュース--
1 つの一重引用符を 2 つの一重引用符に置き換えると、v_newstype の値は次のようになります。
ソーシャル ニュース'';ドロップ テーブル ニュース--
構築された SQL ステートメントは次のようになります。
select * from news where newstype='social news'';drop table news—'
クエリの結果は、以前のようにニュース テーブルを削除せずに、ニュース テーブルのニュースタイプ フィールドの値がソーシャル ニュース';ドロップ テーブル ニュース-- であるレコードを返します。
さらに、処理する必要があるのは、Insert、Update、Delete、Exec などの Select ステートメントだけではなく、次の注入メソッドも確認できます。
構造内で news(title) の値 ('+v_title+') に挿入します。
v_title=123';テーブル ニュースをドロップ--'; の場合
v_title=123'-- または v_id=1;drop table news-- のときにニュース セット /> を更新するとき、これは Select ステートメントだけの問題ではなく、他のステートメントにも問題がある可能性があります。Select だけに焦点を当てないでください。
つまり、データ型を検証し、シングルクォーテーション文字を処理した後、たとえすべての能力を備えていたとしても、私の如来の掌から飛び出すことはできません。