Pregunta

Tengo algo de código que utiliza consultas parametrizadas para prevenir contra de la inyección, pero también tengo que ser capaz de construir dinámicamente la consulta, independientemente de la estructura de la tabla.¿Cuál es la manera correcta de hacer esto?

He aquí un ejemplo, supongamos que tengo una tabla con columnas Nombre, Dirección, Teléfono.Tengo una página web donde puedo ejecutar Mostrar Las Columnas y rellenar un desplegable select con ellos como opciones.

Siguiente, tengo un cuadro de texto llamado Búsqueda.Este cuadro de texto se utiliza como parámetro.

Actualmente mi código se ve algo como esto:

result = pquery('SELECT * FROM contacts WHERE `' + escape(column) + '`=?', search);

Puedo obtener una espeluznante sensación de que aunque.La razón por la que estoy usando consultas con parámetros es evitar el uso de escape.También, escape es probable que no se diseñó para escapar de los nombres de columna.

Cómo puedo asegurarme de que esto funciona de la manera en la que pretendo?

Editar: La razón por la que requieren consultas dinámicas es que el esquema es configurable por el usuario, y no voy a estar en torno a arreglar nada rígida.

¿Fue útil?

Solución

En lugar de pasar los nombres de columna, acaba de pasar un identificador que el código se traduce a un nombre de columna utilizando un codificado de la tabla.Esto significa que usted no necesita preocuparse acerca de los datos maliciosos que se pasan, ya que todos los datos están traducidos legalmente, o que se sabe para ser válido.Psudoish código:

@columns = qw/Name Address Telephone/;
if ($columns[$param]) {
  $query = "select * from contacts where $columns[$param] = ?";
} else {
  die "Invalid column!";
}

run_sql($query, $search);

Otros consejos

El truco es tener confianza en su escape y la validación de las rutinas.Puedo usar mi propio SQL función de escape que está sobrecargado de los literales de diferentes tipos.Nada puedo insertar expresiones (como opuesto a los citados valores literales) directamente desde la entrada del usuario.

Sin embargo, puede ser hecho, os recomiendo una por separado — y de la estricta función para validar el nombre de la columna.Permite aceptar sólo un identificador único, algo así como

/^\w[\w\d_]*$/

Usted tendrá que confiar en los supuestos que usted puede hacer acerca de sus propios nombres de columna.

Yo uso ADO.NET y el uso de Comandos SQL y SQLParameters a los comandos que tener cuidado con el Escape problema.Así que si usted está en un Microsoft-entorno de la herramienta así, puedo decir que yo uso esta muy sucesfully para construir SQL dinámico y al mismo tiempo proteger mi parámetros

la mejor de las suertes

Hacer que la columna con base en los resultados de otra consulta a una tabla que enumera los posibles esquemas de valores.En la segunda consulta, puede codificar el seleccionar el nombre de la columna que se utiliza para definir el esquema.si no se devuelven filas, a continuación, entró en la columna no es válido.

En SQL estándar, usted identificadores delimitados en comillas dobles.Esto significa que:

SELECT * FROM "SomeTable" WHERE "SomeColumn" = ?

se selecciona a partir de una tabla llamada SomeTable con la muestra de capitalización (no es un caso de conversión de la versión de el nombre), y se aplicará de una condición a una columna llamada SomeColumn con la muestra de capitalización.

De por sí, no es muy útil, pero...si se puede aplicar el escape() técnica con comillas dobles para los nombres introducidos a través de su formulario web, entonces usted puede construir su consulta razonablemente con confianza.

Por supuesto, usted dijo que quería evitar el uso de escapar - y, de hecho, usted no tiene que utilizar en los parámetros donde se proporciona el ?lugar de los titulares.Pero donde se están poniendo datos facilitados por el usuario en la consulta, usted necesita para protegerse de la mala gente.

Diferentes DBMS tienen diferentes maneras de proporcionar identificadores delimitados.MS SQL Server, por ejemplo, parece que el uso de corchetes [SomeTable] en lugar de las comillas dobles.

Los nombres de columna en algunas bases de datos pueden contener espacios, que significa que usted tendría que citar el nombre de la columna, pero si su base de datos no contiene columnas, simplemente ejecute el nombre de la columna a través de una expresión regular o algún tipo de verificación antes de empalme en el SQL:

if ( $column !~ /^\w+$/ ) {
  die "Bad column name [$column]";
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top