2008-11-10 30 views
5

Una consulta "estática" sigue siendo la misma en todo momento. Por ejemplo, el botón "Etiquetas" en Stackoverflow, o el botón "7 días" en Digg. En resumen, siempre se asignan a una consulta de base de datos específica, por lo que puede crearlos en el momento del diseño.Cómo crear consultas dinámicas y seguras

Pero estoy tratando de averiguar cómo hacer consultas "dinámicas" donde el usuario básicamente dicta cómo se creará la consulta de la base de datos en tiempo de ejecución. Por ejemplo, en Stackoverflow, puede combinar etiquetas y filtrar las publicaciones de la forma que elija. Esa es una consulta dinámica, aunque muy simple, ya que lo que puedes combinar está dentro del mundo de las etiquetas. Un ejemplo más complicado es si puede combinar etiquetas y usuarios.

En primer lugar, cuando tiene una consulta dinámica, parece que ya no puede usar la API de sustitución para evitar la inyección SQL, ya que los elementos de la consulta dependerán de lo que el usuario decida incluir en la consulta. No puedo ver de qué otra forma construir esta consulta, excepto el uso de anexar cadena.

En segundo lugar, la consulta podría abarcar varias tablas. Por ejemplo, si SO permite a los usuarios filtrar en base a Usuarios y Etiquetas, y estos probablemente viven en dos tablas diferentes, crear la consulta se vuelve un poco más complicado que solo agregar columnas y cláusulas WHERE.

¿Cómo hago para implementar algo como esto?

+0

Para sugerir abstracciones: ¿Qué idioma está utilizando para hablar con su base de datos? ¿Qué base de datos estás usando? –

+0

Su base de datos es muy importante. ¿Qué RDBMS? En segundo lugar, estás dispuesto a limitar en absoluto. ¿Estás dispuesto a decir que solo puedes buscar en 10 etiquetas ... 11 está prohibido? –

Respuesta

0

Bueno, las opciones tienen que asignarse a algo.

Una cadena de consulta SQL CONCAT no es un problema si aún usa parámetros para las opciones.

2

La primera regla es que los usuarios pueden especificar los valores en expresiones SQL, pero no SQL sintaxis. Toda la sintaxis de la consulta debe ser literalmente especificada por su código, no por la entrada del usuario. Los valores que el usuario especifica se pueden proporcionar al SQL como parámetros de consulta. Esta es la forma más efectiva de limitar el riesgo de inyección SQL.

Muchas aplicaciones necesitan "generar" consultas SQL a través del código, porque como usted señala, algunas expresiones, combinaciones de tablas, orden por criterio, etc. dependen de las elecciones del usuario. Cuando crea una consulta SQL pieza por pieza, a veces es difícil asegurarse de que el resultado sea una sintaxis SQL válida.

Trabajé en una clase PHP llamada Zend_Db_Select que proporciona una API para ayudar con esto. Si te gusta PHP, puedes mirar ese código para obtener ideas. No maneja ninguna consulta imaginable, pero lo hace mucho.

Algunos otros marcos de base de datos PHP tienen soluciones similares.

1

Aunque no es una solución general, aquí hay algunos pasos que puede seguir para mitigar el problema de la consulta dinámica pero segura.

Los criterios en los que un valor de columna pertenece a un conjunto de valores cuya cardinalidad es arbitraria no necesitan ser dinámicos. Considere usar la función instr o el uso de una tabla de filtrado especial en la cual se une. Este enfoque se puede extender fácilmente a varias columnas, siempre que se conozca el número de columnas. Filtrar en usuarios y etiquetas podría manejarse fácilmente con este enfoque.

Cuando el número de columnas en los criterios de filtrado es aún pequeño, considere usar diferentes consultas estáticas para cada posibilidad.

Solo cuando el número de columnas en los criterios de filtrado es arbitrario y potencialmente grande, debería considerar el uso de consultas dinámicas. En cuyo caso ...

Para estar seguro de la inyección de SQL, compile u obtenga una biblioteca que defienda contra ese ataque. Aunque es más difícil, esta no es una tarea imposible. Esto se trata principalmente de escanear los delimitadores de cadena SQL en los valores para filtrar.

Para estar a salvo de consultas costosas, considere la posibilidad de utilizar vistas que están especialmente diseñadas para este fin y algunas de lógica inicial para limitar la forma en que se invocarán esas vistas. Este es el mayor desafío en términos de tiempo y esfuerzo del desarrollador.

0

Si usabas python para acceder a tu base de datos, te sugiero que uses el Django model system. Hay muchas aplicaciones similares tanto para python como para otros idiomas (especialmente en ruby ​​on rails). Ahorro mucho tiempo al evitar la necesidad de hablar directamente con la base de datos con SQL.

De the example link:

#Model definition 
class Blog(models.Model): 
    name = models.CharField(max_length=100) 
    tagline = models.TextField() 

    def __unicode__(self): 
     return self.name 

Modelo de uso (esto es, efectivamente, una instrucción de inserción)

from mysite.blog.models import Blog 
b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.') 
b.save() 

Las consultas conseguir mucho más complejo - se pasa alrededor de un objeto de consulta y se pueden añadir filtros/ordenar elementos para ello. Cuando finalmente esté listo para usar la consulta, Django crea una declaración de SQL que refleja todas las formas en que ajustó el objeto de consulta. Creo que es muy lindo.

Otras ventajas de esta abstracción

  • Sus modelos se pueden crear como tablas de bases de datos con claves y limitaciones extranjeros por Django
  • Muchas bases de datos son compatibles (PostgreSQL, MySQL, Lite SQL, etc.)
  • DJango analiza sus plantillas y crea un automatic admin site de ellas.
Cuestiones relacionadas