Frage

Ich versuche, einig anti SQL-Injection in in Java zu setzen und bin zu finden es sehr schwierig, mit dem der „replaceAll“ String-Funktion zu arbeiten. Letztlich muß ich eine Funktion, die alle vorhandenen \ konvertiert zu \\, ein " \", jeder ' \' und jede \n \\n so dass, wenn die Zeichenfolge, die von MySQL SQL-Injections ausgewertet werden blockiert.

Ich habe einige Code aufgebockt Ich arbeitete mit und alle \\\\\\\\\\\ in der Funktion machen meine Augen Nüsse gehen. Wenn jemand ein Beispiel dafür haben, geschieht würde ich es sehr schätzen.

War es hilfreich?

Lösung

PreparedStatements sind der Weg zu gehen, weil sie SQL-Injection unmöglich machen. Hier ist ein einfaches Beispiel der Eingabe des Benutzers als die Parameter unter:

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
      }
   }
}

Egal, welche Zeichen in Namen und E-Mail ist, werden diese Zeichen direkt in der Datenbank gespeichert. Sie werden nicht die INSERT-Anweisung in irgendeiner Weise beeinflussen.

Es gibt verschiedene Set-Methoden für verschiedene Datentypen - die Sie verwenden, hängt davon ab, was Ihre Datenbankfelder sind. Zum Beispiel, wenn man eine Integer-Spalte in der Datenbank hat, sollten Sie eine setInt Methode verwenden. Die PreparedStatement Dokumentation alle listet die verschiedenen Methoden zur Verfügung zum Einstellen und Abrufen von Daten.

Andere Tipps

Die einzige Möglichkeit, SQL-Injection zu verhindern, ist mit parametrisierte SQL. Es ist einfach nicht möglich, einen Filter zu bauen, als die Menschen klüger ist, die SQL für ein Leben hacken.

So verwenden Parameter für alle Eingaben, Updates und wo Klauseln. Dynamische SQL ist einfach eine offene Tür für Hacker, und das schließt dynamisches SQL in gespeicherten Prozeduren. Parametrisieren, parametrieren parametrieren.

Wenn wirklich können Sie nicht verwenden Defense Option 1: Prepared Statements (parametrisierte Abfragen) oder Defense Option 2: Stored Procedures , nicht über Ihr eigenes Werkzeug bauen, verwenden Sie die OWASP Enterprise Security API . Aus dem OWASP ESAPI gehostet auf Google Code:

  

Sie Ihre eigenen Sicherheitskontrollen nicht schreiben! Das Rad neu erfinden, wenn es um die Schaffung von Sicherheitskontrollen für jede Web-Anwendung oder Web-Service führt zu verschwendete Zeit und massive Sicherheitslücken. Die OWASP Enterprise Security API (ESAPI) Toolkits Software-Entwickler Schutz vor sicherheitsrelevanten Design und Implementierung Fehler.

Weitere Informationen finden Sie unter Verhindern von SQL-Injection in Java und SQL-Injection-Prevention-Spickzettel .

Zahlen eine besondere Aufmerksamkeit href="http://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_3:_Escaping_All_User_Supplied_Input" rel="noreferrer"> Defense Option 3 zum , die führt das OWASP ESAPI Projekt).

(Dies ist in der Antwort auf die Bemerkung des OP unter der ursprünglichen Frage,. Ich bin völlig einverstanden, dass PreparedStatement das Werkzeug für diesen Job ist, nicht reguläre Ausdrücke)

Wenn Sie \n sagen, meinen Sie die Sequenz \ + n oder einen tatsächlichen Zeilenvorschub-Zeichen? Wenn es \ + n ist, ist die Aufgabe ziemlich einfach:

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

Um einen umgekehrten Schrägstrich in der Eingabe übereinstimmen, setzen Sie vier von ihnen in dem Regex-String. Um einen umgekehrten Schrägstrich in dem Ausgang zu setzen, setzen Sie vier von ihnen in der Ersatzzeichenfolge. Dies wird vorausgesetzt, Sie die regulären Ausdrücke und Ersatz in Form von Java-String-Literale sind zu schaffen. Wenn Sie sie auf andere Weise (zum Beispiel, indem sie aus einer Datei zu lesen) erstellen, die Sie nicht tun müssen, um das alles doppelt zu entkommen.

Wenn Sie ein Zeilenvorschub-Zeichen in der Eingabe haben und Sie wollen es mit einer Escape-Sequenz zu ersetzen, können Sie einen zweiten Durchgang über den Eingang mit diesem machen:

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

Oder vielleicht möchten Sie zwei Schrägstriche (ich auf, dass nicht ganz klar bin):

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

PreparedStatements sind der Weg in den meisten zu gehen, aber nicht in allen Fällen. Manchmal werden Sie sich in einer Situation, wo eine Abfrage oder ein Teil davon wird für die spätere Verwendung als String aufgebaut und gespeichert werden. Schauen Sie sich die SQL-Injection-Prevention-Spickzettel auf der OWASP-Site für weitere Details und APIs in verschiedenen Programmiersprachen.

Verwenden eines regulären Ausdrucks Text zu entfernen, die eine SQL-Injection klingt wie die SQL-Anweisung an die Datenbank über eine Statement eher als ein PreparedStatement .

Eine der einfachsten Möglichkeiten, um eine SQL-Injection in erster Linie zu verhindern, ist eine PreparedStatement zu verwenden, die Daten übernimmt in eine SQL-Anweisung ersetzen Platzhalter verwenden, die auf Zeichenfolge Verkettungen beruht nicht eine SQL-Anweisung zu erstellen, um zu senden die Datenbank.

Weitere Informationen Prepared Statements aus die Java-Tutorials wäre ein guter Ort, um zu starten.

Prepared Statements sind die beste Lösung, aber wenn Sie es wirklich tun müssen, manuell können Sie auch das StringEscapeUtils -Klasse von der Apache Commons-Lang-Bibliothek. Es hat eine escapeSql(String) Methode, die Sie verwenden können:

import org.apache.commons.lang.StringEscapeUtils; … String escapedSQL = StringEscapeUtils.escapeSql(unescapedSQL);

Falls Sie mit einem Legacy-System zu tun haben, oder Sie haben zu viele Orte zu PreparedStatements in zu kurzer Zeit wechseln - das heißt, wenn sich ein Hindernis ist die beste Praxis von anderen Antworten vorgeschlagen, können Sie versuchen, AntiSQLFilter

Sie müssen den folgenden Code unten. Auf einem Blick kann so aussehen wie jeder alten Code, den ich gemacht. Doch was ich tat, war Blick auf den Quellcode für http://grepcode.com/file/repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.31/com/mysql/jdbc/PreparedStatement .java . Dann nach, dass ich vorsichtig durch den Code von setString sah (int parameter, String x), um die Zeichen zu finden, die es entkommt und maßgeschneiderte diese auf meine eigene Klasse, so dass es für die Zwecke verwendet werden können, die Sie benötigen. Nach allem, wenn diese die Liste der Zeichen, die Oracle entkommt, dann ist dieses Wissen ist wirklich beruhigend Sicherheit-weise. Vielleicht brauchen Oracle einen Schub, ein Verfahren ähnlich wie diese für die nächste große Java-Release hinzuzufügen.

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();
    }
}

eine Prüfung einer Menge Lösung für Prevent sqlmap von SQL-Injection, bei Altsystem Nach der Suche, die kippt allenthalben vorbereitet statments gelten.

java-security-Cross- Site-Scripting-XSS-and-sQL-Injektion Thema Die Lösung wurde

Ich habe versucht @ Richard s Lösung, aber funktionierte nicht in meinem Fall. i verwendet einen Filter

  

Das Ziel dieses Filters ist die Anforderung in eine eigene codiert Wrapper   Wrapper MyHttpRequestWrapper, die transformiert:

     

die HTTP-Parameter mit Sonderzeichen (<,>, ‚, ...) in HTML   Codes über die org.springframework.web.util.HtmlUtils.htmlEscape (...)   Methode. Hinweis: Es ist ähnlich classe in Apache Commons:   org.apache.commons.lang.StringEscapeUtils.escapeHtml (...) die SQL   Zeichen Injektion ( ‚,„, ...) über die Apache Commons classe   org.apache.commons.lang.StringEscapeUtils.escapeSql (...)

<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;
    }
}

Von: [Quelle]

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;

}

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top