ホームページ  >  記事  >  Java  >  Java で SQL インジェクションを回避する方法の詳細な紹介

Java で SQL インジェクションを回避する方法の詳細な紹介

黄舟
黄舟オリジナル
2017-08-22 10:29:291962ブラウズ

この記事では、SQL インジェクションを回避する方法を主に紹介します。編集者が非常に優れていると考えたので、参考として共有します。編集者をフォローして見てみましょう

1. 一般ユーザーとシステム管理者ユーザーの権限は厳密に区別されなければなりません。

一般ユーザーが別の Drop Table ステートメントをクエリ ステートメントに埋め込んだ場合、そのステートメントの実行は許可されますか? Drop ステートメントはデータベースの基本オブジェクトに関連しているため、ユーザーはこのステートメントを操作するための関連権限を持っている必要があります。権限設計では、エンド ユーザー、つまりアプリケーション ソフトウェアのユーザーに対して、データベース オブジェクトの作成と削除の権限を与える必要はありません。したがって、使用する SQL ステートメントに悪意のあるコードが埋め込まれている場合でも、ユーザー権限の制限により、これらのコードは実行されません。したがって、アプリケーションを設計するときは、システム管理者ユーザーと一般ユーザーを区別することが最善です。これにより、データベースへのインジェクション攻撃による被害を最小限に抑えることができます。

2. パラメータ化されたステートメントの使用を強制します。

SQL ステートメントを作成するときに、ユーザーが入力した変数が SQL ステートメントに直接埋め込まれていない場合。この変数をパラメータを通じて渡すと、SQL インジェクション攻撃を効果的に防ぐことができます。つまり、ユーザー入力を SQL ステートメントに直接埋め込むことはできません。対照的に、ユーザー入力をフィルター処理するか、パラメーター化されたステートメントを使用してユーザー入力変数を渡す必要があります。パラメータ化されたステートメントは、ユーザー入力変数を SQL ステートメントに埋め込む代わりにパラメータを使用します。この手段を使用すると、ほとんどの SQL インジェクション攻撃を排除できます。残念ながら、パラメータ化されたステートメントをサポートするデータベース エンジンは多くありません。ただし、データベース エンジニアは、製品を開発するときにパラメータ化されたステートメントを使用するように努める必要があります。

3. ユーザー入力の検証を強化します。

一般に、SQL インジェクション攻撃を防ぐには 2 つの方法が使用できます。1 つはユーザー入力コンテンツの検査と検証を強化する方法で、もう 1 つはユーザー入力コンテンツを渡すためにパラメーター化されたステートメントの使用を強制する方法です。 SQLServer データベースには、管理者が SQL インジェクション攻撃に対処するのに役立つユーザー入力コンテンツ検証ツールが多数あります。文字列変数の内容をテストし、必要な値のみを受け入れます。バイナリ データ、エスケープ シーケンス、コメント文字を含む入力を拒否します。これは、スクリプト インジェクションを防ぎ、特定のバッファ オーバーフロー攻撃を防ぐのに役立ちます。ユーザー入力のサイズとデータ型をテストし、適切な制限と変換を適用します。これは意図的なバッファ オーバーフローの防止に役立ち、インジェクション攻撃の防止に大きな効果があります。

4. SQL Server データベースに付属のセキュリティ パラメーターを使用します。

SQL Server データベースに対するインジェクション攻撃の悪影響を軽減するために、SQL Server データベースでは比較的安全な SQL パラメーターが特別に設計されています。データベース設計プロセス中、エンジニアはこれらのパラメータを使用して、悪意のある SQL インジェクション攻撃を防ぐように努める必要があります。

5. 多層環境で SQL インジェクション攻撃を防ぐ方法

多層アプリケーション環境では、ユーザーが入力したすべてのデータは、信頼できる領域へのアクセスを許可される前に検証される必要があります。検証プロセスに失敗したデータはデータベースによって拒否され、エラー メッセージが次のレベルに返されます。多層検証を実装します。目的のない悪意のあるユーザーに対して講じられた予防措置は、決意の強い攻撃者に対しては効果的ではない可能性があります。より良いアプローチは、ユーザー インターフェイスとその後の信頼境界を越えたすべてのポイントで入力を検証することです。たとえば、クライアント アプリケーションでデータを検証すると、単純なスクリプト インジェクションを防ぐことができます。ただし、次の層がその入力が検証されたと考える場合、クライアントをバイパスできる悪意のあるユーザーはシステムに無制限にアクセスできる可能性があります。したがって、マルチレイヤー アプリケーション環境では、インジェクション攻撃を防ぐ場合、すべてのレイヤーが連携して機能する必要があり、SQL ステートメント インジェクション攻撃を防ぐためにクライアント側とデータベース側で対応する措置を講じる必要があります。

6. 必要に応じて、専門的な脆弱性スキャン ツールを使用して、攻撃の可能性のあるポイントを見つけます。

専門的な脆弱性スキャン ツールを使用すると、管理者が SQL インジェクション攻撃の可能性のあるポイントを見つけるのに役立ちます。ただし、脆弱性スキャン ツールは攻撃ポイントを発見することしかできず、SQL インジェクション攻撃を積極的に防御することはできません。もちろん、このツールは攻撃者によってよく使用されます。たとえば、攻撃者はこのツールを使用して、攻撃対象を自動的に検索し、攻撃を実行できます。このため、企業は必要に応じて、専門的な脆弱性スキャン ツールに投資する必要があります。完全な脆弱性スキャナーは、データベース内の SQL インジェクションの脆弱性を特に検索するという点でネットワーク スキャナーとは異なります。最新の脆弱性スキャナーは、最近発見された脆弱性を探します。したがって、専門的なツールは、管理者が SQL インジェクションの脆弱性を発見し、SQL インジェクション攻撃を防ぐための積極的な措置を講じるよう管理者に通知するのに役立ちます。データベース管理者が攻撃者が発見できる SQL インジェクションの脆弱性を発見し、その脆弱性をブロックするための積極的な措置を講じた場合、攻撃者は手出しできなくなります。

上面主要是介绍了在web应用程序中对sql注入的大体解决思路,下面我们就根据java web应用程序的特征来具体说明一下如何解决在java web应用程序中的sql注入问题。

1.采用预编译语句集,它内置了处理SQL注入的能力,只要使用它的setXXX方法传值即可。

使用好处:

(1).代码的可读性和可维护性.

(2).PreparedStatement尽最大可能提高性能.

(3).最重要的一点是极大地提高了安全性.


String sql= "select * from users where username=? and password=?; 
     PreparedStatement preState = conn.prepareStatement(sql); 
     preState.setString(1, userName); 
     preState.setString(2, password); 
     ResultSet rs = preState.executeQuery();

原理:sql注入只对sql语句的准备(编译)过程有破坏作用,而PreparedStatement已经准备好了,执行阶段只是把输入串作为数据处理,而不再对sql语句进行解析,准备,因此也就避免了sql注入问题.

2.使用正则表达式过滤传入的参数

正则表达式:


private String CHECKSQL = “^(.+)\\sand\\s(.+)|(.+)\\sor(.+)\\s$”;

判断是否匹配:


Pattern.matches(CHECKSQL,targerStr);

下面是具体的正则表达式:

检测SQL meta-characters的正则表达式 :/(\%27)|(\')|(\-\-)|(\%23)|(#)/ix

修正检测SQL meta-characters的正则表达式 :/((\%3D)|(=))[^\n]*((\%27)|(\')|(\-\-)|(\%3B)|(:))/i

典型的SQL 注入攻击的正则表达式 :/\w*((\%27)|(\'))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix

检测SQL注入,UNION查询关键字的正则表达式 :/((\%27)|(\'))union/ix(\%27)|(\')

检测MS SQL Server SQL注入攻击的正则表达式:/exec(\s|\+)+(s|x)p\w+/ix

等等…..

其实可以简单的使用replace方法也可以实现上诉功能:


 public static String TransactSQLInjection(String str)
     {
        return str.replaceAll(".*([';]+|(--)+).*", " ");
     }

3.字符串过滤

比较通用的一个方法:(||之间的参数可以根据自己程序的需要添加)


public static boolean sql_inj(String str) 
{ 
String inj_str = "'|and|exec|insert|select|delete|update| 
count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,"; 
String inj_stra[] = split(inj_str,"|"); 
for (int i=0 ; i < inj_stralength ; i++ ) 
{ 
if (str.indexOf(inj_stra[i])>=0) 
{ 
return true; 
} 
} 
return false; 
}

4.jsp中调用该函数检查是否包函非法字符

防止SQL从URL注入:

sql_inj.java代码:


package sql_inj; 
import java.net.*; 
import java.io.*; 
import java.sql.*; 
import java.text.*; 
import java.lang.String; 
public class sql_inj{ 
public static boolean sql_inj(String str) 
{ 
String inj_str = "&#39;|and|exec|insert|select|delete|update| 
count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,"; 
//这里的东西还可以自己添加 
String[] inj_stra=inj_strsplit("\\|"); 
for (int i=0 ; i < inj_stra.length ; i++ ) 
{ 
if (str.indexOf(inj_stra[i])>=0) 
{ 
return true; 
} 
} 
return false; 
} 
}

 5.JSP页面添加客户端判断代码:

使用JavaScript在客户端进行不安全字符屏蔽

功能介绍:检查是否含有”‘”,”\\”,”/”

参数说明:要检查的字符串

返回值:0:是1:不是

函数名是


function check(a) 
{ 
return 1; 
fibdn = new Array (”‘” ,”\\”,”/”); 
i=fibdn.length; 
j=a.length; 
for (ii=0; ii<i; ii++) 
{ for (jj=0; jj<j; jj++) 
{ temp1=a.charAt(jj); 
temp2=fibdn[ii]; 
if (tem&#39;; p1==temp2) 
{ return 0; } 
} 
} 
return 1; 
}

 关于安全性,本文可总结出一下几点:

1.要对用户输入的内容保持警惕。

2.只在客户端进行输入验证等于没有验证。

3.永远不要把服务器错误信息暴露给用户。

以上がJava で SQL インジェクションを回避する方法の詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。