mysql - reales - ¿Cómo puedo protegerme contra ataques de inyección SQL usando DBI de Perl?
sql injection pdf (5)
¿Cómo llamas a la base de datos?
DBI tiene soporte para declaraciones preparadas que usan placeholders . Tanto DBIx::Class como Rose::DB::Object desinfectan los valores automáticamente, si utiliza el método "buscar" proporcionado por cada biblioteca.
¿Hay alguna función que pueda usar en Perl para desinfectar las entradas antes de ponerlas en MySQL db? No sé muy bien la expresión regular así que antes de hacer mi propia función me preguntaba si ya había una hecha.
Addendum menor (y ciertamente pedante) a las respuestas de "usar marcadores de posición": las consultas parametrizadas no son, estrictamente hablando, "desinfección". No modifican los datos de ninguna manera para que sea seguro. En cambio, protegen contra la inyección de SQL enviando la estructura de consulta (comandos) y los datos por canales separados.
La razón por la cual considero que esta distinción es significativa es porque tratar desinfectar / cotizar / escapar de sus datos y usar consultas parametrizadas ya que lo mismo implica que son intercambiables o, en el mejor de los casos, que los parámetros son solo una mejor manera de citar caracteres peligrosos, por lo que No es gran cosa si te ciñes a citar en lugar de molestarte en descubrir las cosas de placeholder.
En verdad, son técnicas completamente diferentes con niveles de confiabilidad completamente diferentes. Las cotizaciones pueden proporcionar una excelente protección contra las inyecciones, pero siempre existe la posibilidad de que un atacante determinado pueda encontrar algún caso en la esquina que se rompa o resbale a través de su algoritmo de cotización y le permita realizar una inyección SQL exitosa. Las consultas parametrizadas, por otro lado, proporcionan protección absoluta contra la inyección de SQL. Debido a que los comandos y los datos se envían por separado, no hay forma de que el motor de la base de datos pueda ser engañado para ejecutar datos como un comando.
A menos que esté en un caso en que su motor de lenguaje o base de datos no le permita usar un parámetro en su consulta, nunca cite / escape / desinfecte la entrada del usuario como protección contra la inyección de SQL. Siempre use consultas parametrizadas para este propósito si puede hacerlo.
Y el enlace obligatorio: http://bobby-tables.com/ tiene ejemplos de cómo usar consultas parametrizadas en varios idiomas diferentes, incluido Perl.
En casos muy raros , no puede usar marcadores de posición, como se describe en otras respuestas. Pero incluso en casos tan excepcionales, no debes alterar los datos tú solo, ya que crean un lugar para un error potencial. Es mejor utilizar los métodos quote
y quote_identifier
DBI. También hace que su código dependa menos de un RDBMS en particular.
Renuncia. El siguiente es un ejemplo ficticio y no pretende ilustrar el muy raro caso que mencioné.
$dbh->do(''INSERT INTO '' . $dbh->quote_identifier($table) . '' (id, name) VALUES ''
''(NULL, '' . $dbh->quote($name) . '')'');
La forma correcta de desinfectar los datos para insertarlos en su base de datos es usar placeholders de placeholders para todas las variables que se insertarán en sus cadenas de SQL. En otras palabras, NUNCA haga esto:
my $sql = "INSERT INTO foo (bar, baz) VALUES ( $bar, $baz )";
En cambio, ?
usar ?
marcadores de posición:
my $sql = "INSERT INTO foo (bar, baz) VALUES ( ?, ? )";
Y luego pase las variables que se reemplazarán cuando ejecute la consulta:
my $sth = $dbh->prepare( $sql );
$sth->execute( $bar, $baz );
Puede combinar estas operaciones con algunos de los métodos de conveniencia de DBI; lo anterior también se puede escribir:
$dbh->do( $sql, undef, $bar, $baz );
Consulte los placeholders para obtener más información.
Respuesta: Use marcadores de posición SQL (?).
Por qué: la estructura de la declaración SQL y los valores de datos representados por los marcadores de posición se envían a la base de datos completamente por separado. por lo tanto, no hay forma de que los valores de los datos puedan interpretarse como comandos SQL.