복붙노트

[SQL] 자바 - 방지 SQL 주입에 이스케이프 문자열

SQL

자바 - 방지 SQL 주입에 이스케이프 문자열

나는 자바 장소에 일부 안티 SQL 인젝션을 넣을려고하고은 "완전히 대체"문자열 함수와 작업하기가 매우 어려운 발견하고있다. 궁극적으로 나는 어떤 "를 \"어떤 \\에 \ 기존 변환하는 기능을 필요로 어떤 '에 \'및 \ n 여기서 n 그래서 문자열이 MySQL의 SQL 주입에 의해 평가 될 때 차단됩니다 \\합니다.

내가 작업 한 몇 가지 코드를 올려요 한과 기능의 모든 \\\\\\\\\\\ 내 눈이 너트 이동하고 있습니다. 사람이의 예를 가지고 발생하면 나는 대단히 감사하겠습니다.

해결법

  1. ==============================

    1.자는 PreparedStatements은 SQL 주입이 불가능하기 때문에, 갈 수있는 방법입니다. 여기서 변수로서 사용자의 입력을 가지고 단순한 예이다 :

    자는 PreparedStatements은 SQL 주입이 불가능하기 때문에, 갈 수있는 방법입니다. 여기서 변수로서 사용자의 입력을 가지고 단순한 예이다 :

    public insertUser(String name, String email) {
       Connection conn = null;
       PreparedStatement stmt = null;
       try {
          conn = setupTheDatabaseConnectionSomehow();
          stmt = conn.prepareStatement("INSERT INTO person (name, email) values (?, ?)");
          stmt.setString(1, name);
          stmt.setString(2, email);
          stmt.executeUpdate();
       }
       finally {
          try {
             if (stmt != null) { stmt.close(); }
          }
          catch (Exception e) {
             // log this error
          }
          try {
             if (conn != null) { conn.close(); }
          }
          catch (Exception e) {
             // log this error
          }
       }
    }
    

    문자가 이름과 이메일에 상관없이이 그 문자가 데이터베이스에 직접 배치됩니다. 그들은 어떤 방식으로 INSERT 문에 영향을 미치지 않습니다.

    당신이 당신의 데이터베이스 필드가 무엇인지에 따라 사용 하나 - 다른 데이터 유형에 대해 다른 설정 방법이 있습니다. 데이터베이스의 정수 열이있는 경우 예를 들어, 당신은 setInt 방법을 사용해야합니다. 설정 및 데이터를 가져 오는 사용할 수있는 PreparedStatement의 문서 목록 모든 다른 방법.

  2. ==============================

    2.SQL 주입을 방지 할 수있는 유일한 방법은 매개 변수화 된 SQL 함께. 단순히 스마트 생계를 위해 SQL을 해킹 사람보다의 필터를 구축 할 수 없습니다.

    SQL 주입을 방지 할 수있는 유일한 방법은 매개 변수화 된 SQL 함께. 단순히 스마트 생계를 위해 SQL을 해킹 사람보다의 필터를 구축 할 수 없습니다.

    그래서 모든 입력, 업데이트 및 조항에 대한 매개 변수를 사용합니다. 동적 SQL 단순히 해커에 대한 개방하고, 그 프로 시저 동적 SQL을 포함한다. 매개 변수화는, 파라미터 화, 매개 변수화.

  3. ==============================

    3.문 준비 (매개 변수화 된 쿼리) 또는 국방 옵션 2 : 정말 당신이 국방 옵션 1 사용할 수없는 경우 자신의 도구를 구축하지 않습니다, 저장 프로 시저의 OWASP 기업 보안 API를 사용합니다. OWASP ESAPI에서 구글 코드에서 호스팅 :

    문 준비 (매개 변수화 된 쿼리) 또는 국방 옵션 2 : 정말 당신이 국방 옵션 1 사용할 수없는 경우 자신의 도구를 구축하지 않습니다, 저장 프로 시저의 OWASP 기업 보안 API를 사용합니다. OWASP ESAPI에서 구글 코드에서 호스팅 :

    자세한 내용은 Java 및 SQL 주입 방지 치트 시트에서 SQL 주입을 방지 참조하십시오.

    국방 옵션 3에 특별한주의 : 이스케이프 모든 사용자가 제공 한 입력이 소개 OWASP ESAPI 프로젝트).

  4. ==============================

    4.(이것은 원래의 질문에서 영업 이익의 코멘트에 대답에, 나는하지 정규 표현식에, PreparedStatement로이 일을위한 도구입니다 완전히 동의합니다.)

    (이것은 원래의 질문에서 영업 이익의 코멘트에 대답에, 나는하지 정규 표현식에, PreparedStatement로이 일을위한 도구입니다 완전히 동의합니다.)

    당신이 말하는 \ N 때, 당신은 순서 \ + n 또는 실제 개행 문자를 의미합니까? 그것은 + N, 작업은 매우 간단합니다 \ 인의 경우 :

    s = s.replaceAll("['\"\\\\]", "\\\\$0");
    

    입력 한 백 슬래시를 일치 시키려면, 당신은 정규식 문자열에 그들 중 네 넣어. 출력에 하나의 백 슬래시를 넣어, 당신은 대체 문자열에서 그들을 네 넣어. 이것은 당신이 자바 문자열 리터럴의 형태로 정규 표현식에 및 교체를 만드는 가정한다. 당신이 그들에게 다른 방법을 작성하는 경우 (예를 들어, 파일에서 그들을 읽고), 당신은 이중 탈출하는 모든 작업을 수행 할 필요가 없습니다.

    당신이 입력에 줄 바꿈 문자가 있고 이스케이프 시퀀스로 교체하려는 경우, 당신은이에 입력을 통해 두 번째 패스를 할 수 있습니다 :

    s = s.replaceAll("\n", "\\\\n");
    

    아니면 당신은 (내가 그 너무 명확하지 않다) 두 개의 백 슬래시를 원하는 :

    s = s.replaceAll("\n", "\\\\\\\\n");
    
  5. ==============================

    5.자는 PreparedStatements는 대부분의 갈 길, 모든 경우는 아니지만 있습니다. 때때로 당신은 쿼리, 또는 그것의 일부가 내장 나중에 사용하기 위해 문자열로 저장 될 수있는 상황에서 자신을 발견 할 것이다. 서로 다른 프로그래밍 언어에 대한 자세한 내용 및 API에 대한 OWASP 사이트에 SQL 주입 방지 치트 시트를 확인하십시오.

    자는 PreparedStatements는 대부분의 갈 길, 모든 경우는 아니지만 있습니다. 때때로 당신은 쿼리, 또는 그것의 일부가 내장 나중에 사용하기 위해 문자열로 저장 될 수있는 상황에서 자신을 발견 할 것이다. 서로 다른 프로그래밍 언어에 대한 자세한 내용 및 API에 대한 OWASP 사이트에 SQL 주입 방지 치트 시트를 확인하십시오.

  6. ==============================

    6.SQL 문은 PreparedStatement로보다는 문을 통해 데이터베이스로 전송되고 같은 SQL 주입 소리를 일으킬 수 텍스트를 제거하는 정규 표현식을 사용.

    SQL 문은 PreparedStatement로보다는 문을 통해 데이터베이스로 전송되고 같은 SQL 주입 소리를 일으킬 수 텍스트를 제거하는 정규 표현식을 사용.

    처음에 SQL 주입을 방지하는 가장 쉬운 방법 중 하나는 데이터베이스에 전송하는 SQL 문을 생성하는 문자열 회씩 연결에 의존하지 않는 자리 표시자를 사용하여 SQL 문에 대신에 데이터를 받아들이 된 PreparedStatement를 사용하는 것입니다.

    자바 튜토리얼에서 문 준비를 사용하여 자세한 내용은 시작하기에 좋은 장소가 될 것입니다.

  7. ==============================

    7.문 준비는 최적의 솔루션,하지만 당신이 정말로 그것을 할 필요가있는 경우 수동으로도 아파치 코 몬즈 - 랭 라이브러리에서 StringEscapeUtils 클래스를 사용할 수 있습니다. 그것은 당신이 사용할 수있는 escapeSql (String) 메소드를 가지고 있습니다 :

    문 준비는 최적의 솔루션,하지만 당신이 정말로 그것을 할 필요가있는 경우 수동으로도 아파치 코 몬즈 - 랭 라이브러리에서 StringEscapeUtils 클래스를 사용할 수 있습니다. 그것은 당신이 사용할 수있는 escapeSql (String) 메소드를 가지고 있습니다 :

    수입 org.apache.commons.lang.StringEscapeUtils; ... 문자열 escapedSQL = StringEscapeUtils.escapeSql (unescapedSQL);

  8. ==============================

    8.경우 레거시 시스템 다루고있는, 또는 너무 짧은 시간에자는 PreparedStatements로 전환 너무 많은 곳이 - 다른 답변에서 제안하는 가장 좋은 방법을 사용하는 장애물이있는 경우 즉, 당신은 AntiSQLFilter을 시도 할 수 있습니다

    경우 레거시 시스템 다루고있는, 또는 너무 짧은 시간에자는 PreparedStatements로 전환 너무 많은 곳이 - 다른 답변에서 제안하는 가장 좋은 방법을 사용하는 장애물이있는 경우 즉, 당신은 AntiSQLFilter을 시도 할 수 있습니다

  9. ==============================

    9.아래 다음과 같은 코드가 필요합니다. 한눈에, 이것은 내가 만든 것이 이전의 모든 코드처럼 보일 수 있습니다. 그러나, 내가 한 일은 http://grepcode.com/file/repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.31/com/mysql/jdbc/PreparedStatement의 소스 코드를보고했다. 자바. 그리고 그 후, 나는 신중하게 (차례 parameterIndex INT, 문자열 X)는 탈출이 당신이 필요로하는 목적으로 사용될 수 있도록 내 자신의 클래스에이 사용자 정의 문자를 찾을 수 setString 등의 코드를 통해 보았다. 결국, 이것은 오라클은 다음이 정말 보안이 많다는 위안 알고, 탈출 것을 문자 목록 경우. 아마 오라클은 다음 주요 자바 버전이 비슷한 방법을 추가 찔러 필요합니다.

    아래 다음과 같은 코드가 필요합니다. 한눈에, 이것은 내가 만든 것이 이전의 모든 코드처럼 보일 수 있습니다. 그러나, 내가 한 일은 http://grepcode.com/file/repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.31/com/mysql/jdbc/PreparedStatement의 소스 코드를보고했다. 자바. 그리고 그 후, 나는 신중하게 (차례 parameterIndex INT, 문자열 X)는 탈출이 당신이 필요로하는 목적으로 사용될 수 있도록 내 자신의 클래스에이 사용자 정의 문자를 찾을 수 setString 등의 코드를 통해 보았다. 결국, 이것은 오라클은 다음이 정말 보안이 많다는 위안 알고, 탈출 것을 문자 목록 경우. 아마 오라클은 다음 주요 자바 버전이 비슷한 방법을 추가 찔러 필요합니다.

    public class SQLInjectionEscaper {
    
        public static String escapeString(String x, boolean escapeDoubleQuotes) {
            StringBuilder sBuilder = new StringBuilder(x.length() * 11/10);
    
            int stringLength = x.length();
    
            for (int i = 0; i < stringLength; ++i) {
                char c = x.charAt(i);
    
                switch (c) {
                case 0: /* Must be escaped for 'mysql' */
                    sBuilder.append('\\');
                    sBuilder.append('0');
    
                    break;
    
                case '\n': /* Must be escaped for logs */
                    sBuilder.append('\\');
                    sBuilder.append('n');
    
                    break;
    
                case '\r':
                    sBuilder.append('\\');
                    sBuilder.append('r');
    
                    break;
    
                case '\\':
                    sBuilder.append('\\');
                    sBuilder.append('\\');
    
                    break;
    
                case '\'':
                    sBuilder.append('\\');
                    sBuilder.append('\'');
    
                    break;
    
                case '"': /* Better safe than sorry */
                    if (escapeDoubleQuotes) {
                        sBuilder.append('\\');
                    }
    
                    sBuilder.append('"');
    
                    break;
    
                case '\032': /* This gives problems on Win32 */
                    sBuilder.append('\\');
                    sBuilder.append('Z');
    
                    break;
    
                case '\u00a5':
                case '\u20a9':
                    // escape characters interpreted as backslash by mysql
                    // fall through
    
                default:
                    sBuilder.append(c);
                }
            }
    
            return sBuilder.toString();
        }
    }
    
  10. ==============================

    10.올린 사람 : [출처]

    올린 사람 : [출처]

    public String MysqlRealScapeString(String str){
      String data = null;
      if (str != null && str.length() > 0) {
        str = str.replace("\\", "\\\\");
        str = str.replace("'", "\\'");
        str = str.replace("\0", "\\0");
        str = str.replace("\n", "\\n");
        str = str.replace("\r", "\\r");
        str = str.replace("\"", "\\\"");
        str = str.replace("\\x1a", "\\Z");
        data = str;
      }
    return data;
    

    }

  11. ==============================

    11.SQL 인젝션 못하도록하는 SQLMaps 용 용액 많이 테스트를 검색 한 후, 기존 시스템의 경우에는 모든 곳 준비된 문에서도 적용 질수있다.

    SQL 인젝션 못하도록하는 SQLMaps 용 용액 많이 테스트를 검색 한 후, 기존 시스템의 경우에는 모든 곳 준비된 문에서도 적용 질수있다.

    자바 보안 크로스 사이트 스크립팅-XSS-및-SQL 주입 주제 이 솔루션은 WAS

    난 @ 리차드의 솔루션을 시도하지만 내 경우에는 작동하지 않았다. 전 필터를 사용

    <filter>
    <filter-name>RequestWrappingFilter</filter-name>
    <filter-class>com.huo.filter.RequestWrappingFilter</filter-class>
    </filter>
    
    <filter-mapping>
    <filter-name>RequestWrappingFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    
    
    
    package com.huo.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.ServletReponse;
    import javax.servlet.http.HttpServletRequest;
    
    public class RequestWrappingFilter implements Filter{
    
        public void doFilter(ServletRequest req, ServletReponse res, FilterChain chain) throws IOException, ServletException{
            chain.doFilter(new MyHttpRequestWrapper(req), res);
        }
    
        public void init(FilterConfig config) throws ServletException{
        }
    
        public void destroy() throws ServletException{
        }
    }
    
    
    
    
    package com.huo.filter;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    import org.apache.commons.lang.StringEscapeUtils;
    
    public class MyHttpRequestWrapper extends HttpServletRequestWrapper{
        private Map<String, String[]> escapedParametersValuesMap = new HashMap<String, String[]>();
    
        public MyHttpRequestWrapper(HttpServletRequest req){
            super(req);
        }
    
        @Override
        public String getParameter(String name){
            String[] escapedParameterValues = escapedParametersValuesMap.get(name);
            String escapedParameterValue = null; 
            if(escapedParameterValues!=null){
                escapedParameterValue = escapedParameterValues[0];
            }else{
                String parameterValue = super.getParameter(name);
    
                // HTML transformation characters
                escapedParameterValue = org.springframework.web.util.HtmlUtils.htmlEscape(parameterValue);
    
                // SQL injection characters
                escapedParameterValue = StringEscapeUtils.escapeSql(escapedParameterValue);
    
                escapedParametersValuesMap.put(name, new String[]{escapedParameterValue});
            }//end-else
    
            return escapedParameterValue;
        }
    
        @Override
        public String[] getParameterValues(String name){
            String[] escapedParameterValues = escapedParametersValuesMap.get(name);
            if(escapedParameterValues==null){
                String[] parametersValues = super.getParameterValues(name);
                escapedParameterValue = new String[parametersValues.length];
    
                // 
                for(int i=0; i<parametersValues.length; i++){
                    String parameterValue = parametersValues[i];
                    String escapedParameterValue = parameterValue;
    
                    // HTML transformation characters
                    escapedParameterValue = org.springframework.web.util.HtmlUtils.htmlEscape(parameterValue);
    
                    // SQL injection characters
                    escapedParameterValue = StringEscapeUtils.escapeSql(escapedParameterValue);
    
                    escapedParameterValues[i] = escapedParameterValue;
                }//end-for
    
                escapedParametersValuesMap.put(name, escapedParameterValues);
            }//end-else
    
            return escapedParameterValues;
        }
    }
    
  12. from https://stackoverflow.com/questions/1812891/java-escape-string-to-prevent-sql-injection by cc-by-sa and MIT license