フィルタを使用してSQL注入とサイト間スクリプト作成を解決

27118 ワード

1 SQL注入、盲注
1.1 SQL注入、ブラインド注記の概要
Webアプリケーションは、通常、バックエンドでデータベースを使用して、エンタープライズ・データ・ウェアハウスと対話します.クエリー・データベースの実際の標準言語はSQLです(各データベース・ベンダーには独自のバージョンがあります).Webアプリケーションは、通常、ユーザー入力(HTTPリクエストから取得)を取得し、SQLクエリーに組み込み、バックエンド・データベースに送信します.次に、アプリケーションはクエリー結果を処理し、ユーザーに結果を表示することがあります.アプリケーションがユーザ(攻撃者)の入力処理に注意を払わない場合、攻撃者はこの操作方式を利用することができる.この場合、攻撃者は悪意のあるデータを注入することができ、そのデータがSQLクエリに組み込まれると、クエリの元の構文がまったく異なるように変更されます.たとえば、アプリケーションがユーザーの入力(ユーザー名やパスワードなど)を使用してユーザー・アカウントのデータベース・テーブルをクエリーしてユーザーを認証し、攻撃者が悪意のあるデータをクエリーのユーザー名部分(またはパスワード部分)に注入できる場合、クエリーはまったく異なるデータ・レプリケーション・クエリーに変更され、データベースのクエリーを変更する可能性があります.または、データベース・サーバ上でShellコマンドのクエリーを実行します.
1.2 安全リスク及び原因
 攻撃者がデータベース・エントリとテーブルを表示、変更、または削除するリスクの高い脆弱性
 理由:ユーザー入力に対して危険文字クリーンアップが正しく実行されていない
 固定値:危険文字注入の可能な解決策の表示
1.3 AppScanスキャンの推奨事項
いくつかの問題の救済方法は、ユーザー入力をクリーンアップすることです.ユーザー入力に危険文字が含まれていないことを確認することで、悪意のあるユーザーがアプリケーションに計画外のタスクを実行させることを防止できます.たとえば、任意のSQLクエリーの起動、クライアントで実行されるJavascriptコードの埋め込み、さまざまなオペレーティングシステムコマンドの実行などです.以下のすべての文字をフィルタすることを推奨します.
[1]|(縦線記号)
[2]&(&記号)
[3];(セミコロン)
[4]$(ドル記号)
[5%(パーセント記号)
[6]@(at記号)
[7]'(一重引用符)
[8]"(引用符)
[9]'(反スラッシュエスケープ一重引用符)
[10]"(反スラッシュ変換引用符)
[11]<>(括弧)
[12]()(括弧)
[13]+(プラス記号)
[14]CR(リターン記号、ASCII 0 x 0 d)
[15]LF(改行、ASCII 0 x 0 a)
[16](カンマ)
[17](スラッシュ)
次のセクションでは、さまざまな問題、問題の修正提案、およびこれらの問題をトリガーする可能性のある危険な文字について説明します.
SQL注入とSQL盲注:A.ユーザーが入力した値とタイプ(Integer、Dateなど)が有効で、アプリケーションの予想通りであることを確認します.B.ストレージプロセスを利用して、データアクセスを抽象化し、ユーザーが直接テーブルやビューにアクセスしないようにする.ストレージ・プロシージャを使用する場合は、ADOコマンド・オブジェクトを使用して変数タイプを強化します.C.入力を整理してコンテキスト変更記号を排除する.例えば:
[1]'(一重引用符)
[2]"(引用符)
[3]'(反斜線エスケープ一重引用符)
[4]"(反スラッシュ変換引用符)
[5])(括弧終了)
[6] ;(セミコロン)
サイト間スクリプト作成:A.ユーザー入力をクリーンアップし、JavaScriptコードをフィルタします.次の文字をフィルタすることをお勧めします.
[1]<>(括弧)
[2]"(引用符)
[3]'(一重引用符)
[4]%(パーセント記号)
[5];(セミコロン)
[6]()(括弧)
[7]&(&記号)
[8]+(プラス記号)
 
LDAP注入:A.正面認証を使用します.アルファベット数フィルタリング(A..Z,a.z,0..9)は、LDAPクエリの大部分に適しています.B.特殊なLDAP文字をフィルタまたは変換する必要があります.
[1]文字列の先頭にあるスペースまたは#文字
[2]文字列の末尾にあるスペース文字
[3],(カンマ)
[4]+(プラス記号)
[5]"(引用符)
[6](スラッシュ)
[7]<>(括弧)
[8] ;(セミコロン)
[9]()(括弧)
 
ORM注入:A.ユーザーが入力した値とタイプ(Integer、Dateなど)が有効で、アプリケーションの予想に合致していることを確認します.B.ストレージプロセスを利用して、データアクセスを抽象化し、ユーザーが直接テーブルやビューにアクセスしないようにする.C.パラメトリッククエリAPI D.を使用して入力をクリーンアップし、コンテキスト変更記号を除外する.例えば:(*):
[1]'(一重引用符)
[2]"(引用符)
[3]'(反斜線エスケープ一重引用符)
[4]"(反スラッシュ変換引用符)
[5])(括弧終了)
[6] ;(セミコロン)
1.4 アプリケーションソリューション
1、私达はデバッグの便利さのため、ページの上でデータベースの异常な情报を投げ出して、もし侵入ツールがこれらの情报を取得したら、システムのいくつかの配置の情报を取得することができて、例えばwebシステムのフレームワーク、采用するデータベースなど、それによってシステムの抜け穴を探し出します.だからページの上で異常の詳しい情報を投げ出さないでください、これらの情報は取引先に対して役に立たないで、ただ技術者のデバッグを便利にするだけで、処理方法は異常処理ページで印刷の異常コードを削除すればいいです;
2、新しいフィルタを作成し、フィルタによってSQLをフィルタして特殊文字を注入し、配置に成功した後、サービスを再起動し、Appsanツールでスキャンし、脆弱性を解決する.
フィルタによりSQL注入、サイト間スクリプト作成、フレームワークによる釣りなどの問題を解決できます.具体的な実現方法は以下の通りです.
1、web.xmlファイルにフィルタを配置する
 
<!--             SQL        -->
    
    <filter>
        <filter-name>InjectFilter</filter-name>
        <filter-class>com.filter.InjectFilter</filter-class>
    </filter>
    <!--     -->
    
    <!--<filter-mapping>
      <filter-name>InjectFilter</filter-name>-->
        <!--“/*”          -->
       <!-- <url-pattern>/*</url-pattern>
    </filter-mapping>-->
    
    <filter-mapping>
      <filter-name>InjectFilter</filter-name>
        <!--“/*”          -->
       <url-pattern>/*</url-pattern>
    </filter-mapping>

 
2、フィルタフィルタコード
package com.filter;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Enumeration;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.Filter;
import javax.servlet.http.HttpServlet;

/**
 *         SQL        
 * */
public  class InjectFilter extends HttpServlet implements Filter {
	/**
	 * 
	 */
	private static final long serialVersionUID = 5286703103846683570L;
	private String failPage = "/info.jsp";//     ,    

    public void doFilter(ServletRequest request,ServletResponse response,
    		FilterChain filterchain)throws IOException, ServletException {
	    //           
	    HttpServletRequest req = (HttpServletRequest) request;
	 	String inj = injectInput(req);
		if (!inj.equals("")) {
			 request.getRequestDispatcher(failPage).forward(request, response);
			 return;
	    } else {
		    //            
	    	filterchain.doFilter(request, response);
	    }
    }
    
    /**
     *   request           
     * @param request
     * @return
     */
    public String injectInput(ServletRequest request) {
	    
	    Enumeration e = request.getParameterNames();
	    String attributeName;
	    String attributeValues[];
	    String inj = "";
	    String injdb = "";
	    while (e.hasMoreElements()) { 
	    	attributeName = (String)e.nextElement();
	    	//          ,             
	    	if(attributeName.equals("userPassword")||attributeName.equals("confirmPassword")||attributeName.equals("PASSWORD")
	    			||attributeName.equals("password")||attributeName.equals("PASSWORD2")||attributeName.equals("valiPassword")){
	    		continue;
	    	}
	    	
	    	attributeValues = request.getParameterValues(attributeName);
	    	for (int i = 0; i < attributeValues.length; i++) {
	    		
	if(attributeValues[i]==null||attributeValues[i].equals(""))
	    			continue;
	    		inj = injectChar(attributeValues[i]);
	    		
	    		if (!inj.equals("")) 
	    		{
	    			return inj;
	    		}		 
	    	}
	    }   
    	return inj;
    }
    
    /**
     *                 
     * @param str
     * @return
     */
    public String injectChar(String str) {
    	
       String inj_str = "\" ) \' * % < > &";
       String inj_stra[] = inj_str.split(" ");
    	
       for (int i = 0 ; i < inj_stra.length ; i++ )
       {
           if (str.indexOf(inj_stra[i])>=0)
           {
               return inj_stra[i];
           }
       }
       return "";
    }
       	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub 
           // System.out.println("----        ----");  
    }  
	
}

 3.サイト間のスクリプト作成にまだ脆弱性があるか、または他の脆弱性のリスクがある場合は、フィルタを作成して検証フィルタを強化し続けます.
1.xmlファイルで新しいフィルタの構成を続行します.
<!--                -->
    
    <filter>  
        <filter-name>XssFilter</filter-name>  
        <filter-class>com.filter.XssFilter</filter-class>  
    </filter> 
    <!--     --> 
    
    <filter-mapping>
      <filter-name>XssFilter</filter-name>
        <!--“/*”          -->
        <url-pattern>/*</url-pattern>
    </filter-mapping> 

2.フィルタコード:
package com.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import com.RequestWrapper;
import javax.servlet.http.HttpServlet;

/*
 * XSS  
 */
public class XssFilter extends HttpServlet implements Filter {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 6846384055249714181L;

	/**  
	    *          
	    */    
	    private String excludedPages;    
	        
	    private String[] excludedPageArray;   
	      
	    @SuppressWarnings("unused")  
	    private FilterConfig filterConfig;  
	  
	    public void destroy() {  
	        this.filterConfig = null;  
	       // System.out.println("----     ----");
	    }  
	      
	    public void doFilter(ServletRequest request, ServletResponse response,  
	            FilterChain chain) throws IOException, ServletException {  
	        boolean isExcludedPage = false;  
	     //        HttpServletRequest
	        HttpServletRequest request2 = (HttpServletRequest) request;  
	        String ctx_path = request2.getContextPath();  
	        String request_url = request2.getRequestURI();  
	        String action = request_url.substring(ctx_path.length());  
	        
	        HttpServletResponse response2 = (HttpServletResponse)response;
	        response2.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly");
	          
	       	    if (isExcludedPage) {  
	            chain.doFilter(request, response2);  
	        } else {  //   RequestWrapper    XSS
	            chain.doFilter(new RequestWrapper(request2), response2);  
	        }  
	          
	    }  
	      
	    /** 
	     *         
	     */  
	    public void init(FilterConfig filterConfig) throws ServletException {  
	        this.filterConfig = filterConfig;  
	        excludedPages = filterConfig.getInitParameter("excludedPages");    
	        if (StringUtils.isNotEmpty(excludedPages)) {  
	            excludedPageArray = excludedPages.replaceAll("[\\s]", "").split(",");  
	            //System.out.println("----      ----");
	        }  
	    }  
}

 2.クラスRequestWrapper
package com.servlet;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import com.util.XssClean;

/*
 *   XSS  
 *     RequestWrapper , getParameter getParameterValues    ,            form        
 */
public class RequestWrapper extends HttpServletRequestWrapper {
	HttpServletRequest orgRequest = null;  
	   
    public RequestWrapper(HttpServletRequest request) {  
        super(request);  
        orgRequest = request;  
    }  
    /** 
     *       request 
     *  
     * @return 
     */ 
    public HttpServletRequest getOrgRequest() {  
        return orgRequest;  
    }  
   
    /** 
     *       request      
     *  
     * @return 
     */ 
    public static HttpServletRequest getOrgRequest(HttpServletRequest req) {  
        if (req instanceof RequestWrapper) {  
            return ((RequestWrapper) req).getOrgRequest();  
        }  
   
        return req;  
    } 

   /**
    *   getParameterMap   , sql、html、script      
    */
   public Map<String,String> getParameterMap() {
       HashMap<String,String> paramMap = (HashMap<String,String>) super.getParameterMap();
       paramMap = (HashMap<String,String>) paramMap.clone();

       for (Iterator iterator = paramMap.entrySet().iterator(); iterator.hasNext(); ) {
           Map.Entry<String,String[]> entry = (Map.Entry<String,String[]>) iterator.next();
           String [] values = entry.getValue();
           for (int i = 0; i < values.length; i++) {
               if(values[i] instanceof String){
                   values[i] = XssClean.xssClean(values[i]);
               }
           }
           entry.setValue(values);
       }
       return paramMap;
   }
   //////////////////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////////////
   //  form data      
   public String[] getParameterValues(String paramString){  
     String[] arrayOfString1 = super.getParameterValues(paramString);  
     if (arrayOfString1 == null)  
       return null;  
     int i = arrayOfString1.length;  
     String[] arrayOfString2 = new String[i];  
     for (int j = 0; j < i; j++)  
       arrayOfString2[j] =XssClean.xssClean_New(arrayOfString1[j]);  
     return arrayOfString2;  
   }  
   

   public String getParameter(String paramString){  
     String str = super.getParameter(paramString);  
     if (str == null)  
       return null;  
     return XssClean.xssClean(str);  
   }  
//////////////////////////////////////////////////
   //                URL      
   public String getHeader(String paramString) {  
     String str = super.getHeader(paramString);  
     if (str == null)  
       return null;  
     return XssClean.xssClean(str);  
   } 
   ////////////////////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////////////////
   
   public String getQueryString() {
		String value = super.getQueryString();
		if (value != null) {
			value = XssClean.xssClean(value);
		}
		return value;
	}
 }

 3.クラスXssClean
package com.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.owasp.validator.html.AntiSamy;
import org.owasp.validator.html.CleanResults;
import org.owasp.validator.html.Policy;

import org.owasp.validator.html.PolicyException;
import org.owasp.validator.html.ScanException;
import org.springframework.web.util.HtmlUtils;
import org.apache.commons.io.IOUtils;

/*
 *    XSS  
 *    dependency  ,    xssClean   antisamy         。  policy.xml    ,
 * policy.xml      html          。antisamy       ,  policy           ,
 *          policy      ,             ,        。
 */
public class XssClean {
    private static  Policy policy = null;  
      
    public static Policy getPolicy() throws PolicyException {  
        if (policy == null) {  
            InputStream policyFile = XssClean.class.getResourceAsStream("/resource/antisamy.xml");  //antisamy.xml           ,              。
              
           //     jar ,    InputStream String,
            //   apache io   import org.apache.commons.io.IOUtils;
            String result = null;
			try {
				result = IOUtils.toString(policyFile, "UTF-8");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
            policy = Policy.getInstance(result); 
            
        }  
        return policy;  
    }  
     // client      request, server      ,       
    public static String xssClean_New(String value) { 
        if (StringUtils.isNotEmpty(value)) {  
            AntiSamy antiSamy = new AntiSamy();  
            try {  
                //                        
            	final CleanResults cr = antiSamy.scan(StringUtil.UrlDecode(value, "UTF-8"), getPolicy());  
               
            	// final CleanResults cr = antiSamy.scan(value, Policy.getInstance("antisamy.xml"), AntiSamy.SAX);
                
                //   HTML    
                value = cr.getCleanHTML(); 
                value = HtmlUtils.htmlEscape(value);
                
                //return cr.getCleanHTML();
            } catch (ScanException e) {  
                e.printStackTrace();  
            } catch (PolicyException e) {  
                System.out.println("  XSS      : " + e.getMessage());  
                
            }  
        }  
        return value;  
    } 
    
    
    
    public static String xssClean_4(String value) {//     
    	value = StringUtil.UrlDecode(value, "UTF-8");
    	value = HtmlUtils.htmlEscape(value);
		value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
		value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
		value = value.replaceAll("'", "& #39;");
		value = value.replaceAll("eval\\((.*)\\)", "");
		value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
		value = value.replaceAll("script", "");
		return value;
    } 

    
    
    /** 
     *      xss                 
     *       XSS  
     * @param s 
     * @return 
     */  
    public static String xssClean(String value) {  
        if (value == null || value.isEmpty()) {  
            return value;  
        }  
        value = StringUtil.UrlDecode(value, "UTF-8");
        value = HtmlUtils.htmlEscape(value);
        
        value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
		value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
		value = value.replaceAll("'", "& #39;");
		value = value.replaceAll("eval\\((.*)\\)", "");
		value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
		value = value.replaceAll("script", "");
        
        StringBuilder sb = new StringBuilder(value.length() + 16);  
        for (int i = 0; i < value.length(); i++) {  
            char c = value.charAt(i);  
            switch (c) {  
            case '>':  
                sb.append(">");//         
                break;  
            case '<':  
                sb.append("<");//         
                break;  
            case '\'':  
                sb.append("'");//         
                break;  
            case '\"':  
                sb.append(""");//         
                break;  
            case '&':  
                sb.append("&");//   &   
                break;  
            default:  
                sb.append(c);  
                break;  
            }  
        }  
       
        return sb.toString();  
    } 
    
    
    
    public static  String xssClean_error(String value) {
        if (value != null) {
            value = value.replaceAll("", "");
            // Avoid anything between script tags
            Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid anything in a src="http://www.yihaomen.com/article/java/..." type of e­xpression
            scriptPattern = Pattern.compile("src[\r
]*=[\r
]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("src[\r
]*=[\r
]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); // Remove any lonesome </script> tag scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); // Remove any lonesome <script ...> tag scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); // Avoid eval(...) e­xpressions scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); // Avoid e­xpression(...) e­xpressions scriptPattern = Pattern.compile("e­xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); // Avoid javascript:... e­xpressions scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); // Avoid vbscript:... e­xpressions scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); // Avoid onload= e­xpressions scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); value = HtmlUtils.htmlEscape(value); } return value; } }

 万事順調だ!Appscanが掃き出すのを心配する必要はありません.私たちの道はIBMの彼の娘のやり方です.