2011-07-11 19 views
9

¿Existe alguna función o biblioteca que se pueda usar para limpiar la entrada del usuario? Al igual que, por ejemplo, si el usuario ingresa un texto llamado baily's, entonces debería escapar al ' antes de enviarlo a la consulta mysql. Del mismo modo, debería ser capaz de filtrar caracteres nulos y \ n, \ t, \ r, etc. Al igual que en PHP tenemos mysql_real_escape_string($input) ¿hay algo en Java para hacer esto?Limpiar la cadena en java

+0

Si usa una capa ORM (que es una práctica común en Java) o incluso solo enunciados con parámetros nombrados o enumerados, el escape de los parámetros SQL se realizará automáticamente. Siempre y cuando no estés concatenando manualmente cadenas para construir tus consultas, deberías estar a salvo. – aroth

+1

** Ver también: ** ['JDBC - cómo escapar de los parámetros proporcionados por el usuario con una consulta sql'] (http://stackoverflow.com/questions/4954002/jdbc-how-to-escape-user-supplied- parameters-with-a-sql-query) –

Respuesta

11

En Java, no suele hacerlo a mano.

En su lugar utilizará un PreparedStatement y pasará los argumentos a su instrucción SQL a través de los métodos explícitos setString() o setObject().

De esta forma el controlador JDBC lo manejará (ya sea haciendo el escape necesario o enviando la instrucción SQL por separado de los argumentos, dependiendo de la base de datos).

Por ejemplo, el código podría parecer que (utilizando prepareStatement()):

Connection c = ...; // get Connection from somehwere 
PreparedStatement stmt = c.prepareStatement("SELECT * FROM BOOKS WHERE TITLE = ?"); 
stmt.setString(1, userInput); 
ResultSet result = stmt.executeQuery(); 
2

Debe usar PreparedStatement y establecer los valores de $input utilizando la función setString.

El motivo por el que se usa PreparedStatement es que cada base de datos puede necesitar escaparse de cosas diferentes. Esta complejidad está oculta en la implementación concreta de PreparedStatement proporcionada por el proveedor de la base de datos.

1

El escape que utiliza es específico para el sistema para el que desea utilizar la cadena. Si usas MySQL, tienes que hacer diferentes escapes que si quieres usar la cadena en un fragmento de Javascript.

Para responder a su pregunta, necesitamos saber cómo quiere escapar de su cadena. Lo más probable es que no necesite escapar de la cadena antes de usarla en un contexto de base de datos. Por ejemplo, si usa prepared queries, no necesita escaparse de sus valores.

2

Respuesta breve, no, excepto definiciones muy específicas de "limpio". Ahora mismo debe usar una solución específica de idioma: para SQL, simplemente use una declaración preparada.

Respuesta más larga, ha habido trabajos recientes sobre desinfectantes automáticos de cuerdas que determinan cómo incorporar contenido de texto sin formato & correctamente en el contenido en otros idiomas.

Existen escaneos automáticos contextuales automáticos para HTML en lenguajes de plantilla como Soy, Go, una variante de jQuery, cTemplates, clearsilver y, con suerte, otros pronto.

Se está llevando a cabo una investigación generalizando esto para que pueda extenderse fácilmente a otros idiomas. Una idea en la que estoy trabajando es tomar una gramática con anotaciones que describa un lenguaje de destino como SQL y descubrir qué escapes deben hacerse para los agujeros que pueden llenarse con los datos del usuario.

Dada una gramática como lo de abajo que incluye anotaciones que muestran cómo la estructura de los mapas de datos a subseries dentro de la lengua:

JSONValue   := JSONNullLiteral 
         | JSONBooleanLiteral 
         | JSONObject 
         | JSONArray 
         | JSONString 
         | JSONNumber         ; 
JSONObject   := @KeyValueMap ([{] JSONMemberList? [}])  ; 
JSONMemberList  := JSONMember ([,] JSONMemberList)?    ; 
JSONMember   := @Key JSONString [:] @Value JSONValue   ; 
JSONNullLiteral  := @ValueNull "null"        ; 
JSONBooleanLiteral := @ValueFalse "false" | @ValueTrue "true"  ; 
JSONArray   := @List("[" (JSONValue ([,] JSONValue)*)? "]") ; 
JSONString   := @String ([\"] JSONStringCharacters? [\"])  ; 
JSONNumber   := @Number (Sign? (Mantissa Exponent? | Hex)) ; 
JSONStringCharacters := JSONStringCharacter JSONStringCharacters?  ; 
JSONStringCharacter := @Char ([^\"\\\x00-\x1f]) 
         | JSONEscapeSequence       ; 
JSONEscapeSequence := "\\" @Char [/\\\"] 
         | @Char{[\x08]} "\\b" 
         | @Char{[\x0c]} "\\f" 
         | @Char{[\x0a]} "\\n" 
         | @Char{[\x0d]} "\\r" 
         | @Char{[\x09]} "\\t" 
         | @Char ("\\u" @Scalar (hex hex hex hex))  ; 
Mantissa    := (Integer ([.] Fraction?) | [.] Fraction)  ; 
Exponent    := [Ee] Sign? decimal+       ; 
Integer    := [0] | [1-9] [0=9]*       ; 
Fraction    := [0-9]+          ; 
Hex     := [0] [Xx] hex+         ; 
Sign     := [+\-]           ; 

podemos construir una máquina de estados como el siguiente:

enter image description here

que convierte secuencias de eventos (start, start_object, start_key, character 'x', ...) en instrucciones que codifican caracteres en un búfer.

Desde esa máquina de estados también podemos generar rastros genéricos de instrucciones a usar para generar código eficiente para codificadores, y con suerte los algoritmos de análisis de contexto que determinan qué codificadores aplicar cuando.

Si esto funciona, sería hacer que sea fácil de incorporar en los lenguajes de programación de propósito general, los mecanismos para componer automáticamente & contenido de forma segura en lenguajes como SQL, HTML, etc, con ajustes a las definiciones de lenguaje para permitir execute_query para encontrar los límites entre el contenido especificado por el programador y el contenido inyectado en execute_query("SELECT * FROM Table WHERE ID=$ID") y usarlos para escapar automáticamente del contenido inyectado, podemos hacer que esa frase simplemente funcione como lo pretende el programador.