Estoy tratando de poner un poco de inyección anti SQL en Java y me resulta muy difícil trabajar con la función de cadena "replaceAll". En última instancia, necesito una función que convierta cualquier existente \
a \\
, any "
a \"
, any '
a \'
y any \n
a \\n
para que cuando la cadena sea evaluada por MySQL, las inyecciones SQL se bloqueen.
He acumulado un código con el que estaba trabajando y todo \\\\\\\\\\\
en la función me está volviendo loco. Si alguien tiene un ejemplo de esto, lo agradecería mucho.
CREATE VIEW myview AS SELECT * FROM mytable WHERE col = ?
ya que la declaración principal es una declaración DDL , aunque la parte que está tratando de parametrizar es en realidad DML .Respuestas:
Las declaraciones preparadas son el camino a seguir, porque hacen que la inyección de SQL sea imposible. Aquí hay un ejemplo simple que toma la entrada del usuario como parámetros:
No importa qué caracteres estén en el nombre y el correo electrónico, esos caracteres se colocarán directamente en la base de datos. No afectarán la declaración INSERT de ninguna manera.
Existen diferentes métodos establecidos para diferentes tipos de datos: el que use dependerá de los campos de su base de datos. Por ejemplo, si tiene una columna INTEGER en la base de datos, debe usar un
setInt
método. La documentación de PreparedStatement enumera todos los diferentes métodos disponibles para configurar y obtener datos.fuente
La única forma de evitar la inyección de SQL es con SQL parametrizado. Simplemente no es posible construir un filtro que sea más inteligente que las personas que piratean SQL para ganarse la vida.
Por lo tanto, use parámetros para todas las entradas, actualizaciones y cláusulas where. Dynamic SQL es simplemente una puerta abierta para los hackers, y eso incluye SQL dinámico en los procedimientos almacenados. Parametrizar, parametrizar, parametrizar.
fuente
Si realmente no puede usar la Opción de defensa 1: Declaraciones preparadas (consultas parametrizadas) o la Opción de defensa 2: Procedimientos almacenados , no cree su propia herramienta, use la API de seguridad empresarial de OWASP . Desde el OWASP ESAPI alojado en Google Code:
Para obtener más detalles, consulte Prevención de la inyección de SQL en Java y la hoja de trucos de prevención de inyección de SQL .
Preste especial atención a la Opción de defensa 3: Escapar de todas las entradas proporcionadas por el usuario que presenta el proyecto OWASP ESAPI ).
fuente
(Esto responde al comentario del OP bajo la pregunta original; estoy completamente de acuerdo en que PreparedStatement es la herramienta para este trabajo, no expresiones regulares).
Cuando dices
\n
, ¿te refieres a la secuencia\
+n
o un carácter de salto de línea real? Si es\
+n
, la tarea es bastante sencilla:Para hacer coincidir una barra invertida en la entrada, debe colocar cuatro de ellas en la cadena de expresiones regulares. Para poner una barra diagonal inversa en la salida, coloque cuatro de ellas en la cadena de reemplazo. Esto supone que está creando expresiones regulares y reemplazos en forma de literales de Java String. Si los crea de otra manera (por ejemplo, al leerlos desde un archivo), no tiene que hacer todo ese doble escape.
Si tiene un carácter de salto de línea en la entrada y desea reemplazarlo con una secuencia de escape, puede hacer un segundo pase sobre la entrada con esto:
O tal vez quieras dos barras invertidas (no estoy muy claro en eso):
fuente
Las declaraciones preparadas son el camino a seguir en la mayoría, pero no en todos los casos. A veces se encontrará en una situación en la que una consulta, o una parte de ella, debe construirse y almacenarse como una cadena para su uso posterior. Consulte la hoja de trucos de prevención de inyección de SQL en el sitio OWASP para obtener más detalles y API en diferentes lenguajes de programación.
fuente
Las declaraciones preparadas son la mejor solución, pero si realmente necesita hacerlo manualmente, también puede usar la
StringEscapeUtils
clase de la biblioteca Apache Commons-Lang. Tiene unescapeSql(String)
método que puedes usar:import org.apache.commons.lang.StringEscapeUtils; … String escapedSQL = StringEscapeUtils.escapeSql(unescapedSQL);
fuente
El uso de una expresión regular para eliminar texto que podría causar una inyección SQL suena como si la instrucción SQL se enviara a la base de datos a través de un en
Statement
lugar de unPreparedStatement
.En primer lugar, una de las formas más fáciles de evitar una inyección de SQL es usar a
PreparedStatement
, que acepta datos para sustituir en una declaración SQL utilizando marcadores de posición, que no se basa en concatenaciones de cadenas para crear una declaración SQL para enviar a la base de datos.Para obtener más información, Uso de declaraciones preparadas de tutoriales de Java sería un buen lugar para comenzar.
fuente
En caso de que esté lidiando con un sistema heredado, o tenga demasiados lugares para cambiar a
PreparedStatement
s en muy poco tiempo, es decir, si hay un obstáculo para usar la mejor práctica sugerida por otras respuestas, puede probar AntiSQLFilterfuente
Necesita el siguiente código a continuación. De un vistazo, esto puede parecerse a cualquier código antiguo que inventé. Sin embargo, lo que hice fue mirar el código fuente de http://grepcode.com/file/repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.31/com/mysql/jdbc/PreparedStatement. java . Luego, después de eso, busqué cuidadosamente el código de setString (int parameterIndex, String x) para encontrar los caracteres de los que se escapa y lo personalicé en mi propia clase para que pueda usarse para los fines que usted necesita. Después de todo, si esta es la lista de personajes de los que Oracle escapa, entonces saber esto es realmente reconfortante en cuanto a seguridad. Tal vez Oracle necesite un empujón para agregar un método similar a este para la próxima versión principal de Java.
fuente
mysql-connector-java-xxx
, elcase '\u00a5'
ycase '\u20a9'
declaraciones parecen haber sido eliminadoorg.ostermiller.utils.StringHelper.escapeSQL()
ocom.aoindustries.sql.SQLUtility.escapeSQL()
.Después de buscar una gran cantidad de soluciones de prueba para evitar que sqlmap sea inyectado por sqlmap, en el caso de sistemas heredados que no pueden aplicar declaraciones preparadas en todas partes.
java-security-cross-site-scripting-xss-and-sql-injection topic FUE LA SOLUCIÓN
Probé la solución de @Richard pero no funcionó en mi caso. utilicé un filtro
fuente
java-security-cross-site-scripting-xss-and-sql-injection topic
? Estoy tratando de encontrar una solución para una aplicación heredada.De: [Fuente]
}
fuente
Si está utilizando PL / SQL, también puede usar
DBMS_ASSERT
, puede desinfectar su entrada para que pueda usarlo sin preocuparse por las inyecciones de SQL.vea esta respuesta por ejemplo: https://stackoverflow.com/a/21406499/1726419
fuente