先週、他の人のために Web サイトを作成したのですが、その作品に多くの抜け穴があることに偶然気づき、SQL インジェクションを使用してそれを修正しました。そこで、SQL インジェクションに関する情報をいくつか調べて、初心者と共有できればと思います。専門家は笑ってるよ!
SQL インジェクション攻撃の一般的な考え方:
SQL インジェクションの場所を検出します。
サーバーの種類とバックグラウンド データベースの種類を決定します。
実行可能性を判断するために
、一部の攻撃者は通常 SQL インジェクションを使用します。次にSQLインジェクション手法について私なりの知見もお話します。
注入方法:
理論的には、認証 Web ページは次のようになります。
Select * from admin where username='XXX' and passwd='YYY' ステートメント。このステートメントを正式に実行する前に必要な文字フィルタリングが実行されない場合、SQL インジェクションを実装するのは簡単です。
たとえば、ユーザー名テキスト ボックスに「abc」または 1=1-- パスワード ボックスに「123」と入力すると、SQL ステートメントは次のようになります。
select * from admin where username='abc' or 1=1 and passwd='123' ユーザーが入力したユーザー名とパスワードに関係なく、このステートメントは常に正しく実行され、ユーザーはシステムを簡単に欺いて合法的なパスワードを取得できます。身元。
解決策を推測してください:
基本的な考え方は、すべてのデータベース名を推測し、データベース内のすべてのテーブル名を推測し、ユーザー名とパスワードを保存する可能性のあるテーブル名を分析し、テーブル内のすべてのフィールド名を推測し、テーブルのコンテンツ内のすべてのレコードを推測することです。
データベース名と各テーブルの名前を取得する方法もあります。
http://www .cn/news?id=10' の形式でエラーを報告して、データベース名とテーブル名を取得するだけです。
jsp の場合、通常、次の戦略を採用してこれに対処します。
1.PreparedStatement
すでに中程度の上級開発者である場合は、常に Statement の代わりに PreparedStatement を使用する必要があります。
理由は次のとおりです
1. コードの可読性と保守性。
2. PreparedStatement によりパフォーマンスが可能な限り向上します。
3. 最も重要な点は、セキュリティが大幅に向上していることです。
これまでのところ、(私を含めて) 基本的な悪い SQL 構文さえ知らない人もいます。
String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";
名前として [' または '1' = '1] を渡すと、パスワードはどうなるか見てみましょう。 ネットワーク管理 network bitsCN.com
select * from tb_name = 'or '1' = '1' およびpasswd = 'カジュアル' ;
「1」=「1」は間違いなく true であるため、どのような検証にも合格できます。
['; テーブル tb_name ] を varpasswd として渡します。
select * from tb_name = 'any' and passwd = ''; drop table tb_name; 一部のデータベースでは成功しませんが、これらのステートメントを実行できるデータベースも多数あります。
また、プリコンパイルされたステートメントを使用する場合、渡したコンテンツは元のステートメントと一致する関係がありません (データベース自体がプリコンパイルをサポートしていることが前提ですが、コンパイルをサポートしていないサーバー側データベースは存在しない可能性があります)。少数のデスクトップ データベース、つまりファイルに直接アクセスできるデータベースは、すべてプリコンパイルされたステートメントを使用する限り、受信データに対してフィルタリングを行う必要はありません。通常のステートメントを使用する場合は、費用がかかる場合があります。ドロップに多くの時間を費やす、など。計画的な判断と考えすぎ。
2. 正規表現
2.1. SQL メタ文字を検出するための正規表現/(%27)|(')|(--)|(%23)|(#)/ix
2.2. SQL メタ文字を検出するための正規表現 /((%3D)|(=))[^n]*((%27)|(')|(--) 54ne を修正します。 com
|(%3B)|(:))/i
2.3. 典型的な SQL インジェクション攻撃の正規表現/w*((%27)|('))((%6F)|o|(%4F))((%72)|r |(中国ネットワーク管理同盟www.bitscn.com
%52))/ix
2.4. SQL インジェクションの検出、UNION クエリ キーワードの正規表現 /((%27)|('))union/ix(%27)|(') - single
引用符とそれに相当する 16 進数の共用体 - Union キーワード。
2.5. MS SQL Server SQL インジェクション攻撃を検出するための正規表現/exec(s|+)+(s|x)pw+/ix
3. 文字列フィルタリング
public static String filterContent(String content){
文字列 flt="'|and|exec|insert|select|delete|update|count|*|%
|chr|mid|master|truncate|char|declare| |または|-|+|、";
Stringfilter[] = flt.split("|");
for(int i=0; i {
content.replace(filter[i], "");
}
コンテンツを返す。
}
4. 安全でない文字のマスキング
この部分では js を使用してブロックしますが、これは非常に小さな役割を果たしますが、キーワードをブロックする方法には一定の効果がありますが、実際のアプリケーションでは、これらの SQL キーワードも実際のクエリ キーワードになり、ブロックされることになります。ユーザーは正常に使用できなくなります。 コーディング標準に少し力を入れてください。
実行される SQL に変数がある場合は、JDBC (または他のデータ永続層) が提供する PreparedStatement を使用してください。文字列を結合する方法は使用しないでください。
機能紹介:「'」、「 \」、「/ 」が含まれていないかチェック
パラメータ説明: チェック対象の文字列 戻り値: 0: Yes 1: Not 関数名 Yes
機能チェック(a)
{
1を返します。
fibdn = 新しい配列 ("'" ," \","/ ");
i=fibdn.長さ;
j=a.長さ;
for (ii=0; ii { for (jj=0; jj
{ temp1=a.charAt(jj);
temp2=fibdn[ii];
if (tem'; p1==temp2)
{ 0 を返す }
}
}
1 を返します
。