SQL tiene la misma vulnerabilidad que todos los otros lenguajes de programación interpretados dinámicamente (esto incluye scripts de shell, Javascript, PHP ...), que llamo "datos es código". Tales lenguajes tienen una sintaxis concreta que está destinada al consumo humano (" select * from users where
...": palabras y signos que el cerebro humano capta). Su procesamiento implica un primer paso que se llama análisis : la secuencia de caracteres se divide en una estructura interna que describe la < em> significado de la expresión, de una manera que la computadora puede usar de manera eficiente. El análisis es un tema conocido pero incluso si los algoritmos para ello se conocen desde hace décadas, todavía es relativamente complejo para el programador humano.
Cuando un lenguaje se interpreta dinámicamente, hace que sea seductoramente fácil para construir la expresión a partir de parámetros obtenidos dinámicamente. P.ej. "%código%". Las vulnerabilidades de inyección de SQL se esconden allí. El problema es fundamental: al construir la expresión en la sintaxis concreta , el programador está haciendo una inversión ad hoc del análisis. Para hacer tales cosas robustas, el programador debe dominar todas las formas sutiles por las cuales opera el análisis; debe pensar en cada rincón oscuro de la especificación del lenguaje. Muchos programadores lo piensan en términos de "deben escapar los caracteres peligrosos", y suponen que los pocos caracteres peligrosos que podrían pensar representan a todos los "personajes peligrosos" que podrían existir. Esto deja la puerta abierta a muchos problemas, en particular cuando el desarrollador del sitio web, su marco de programación y la base de datos no están totalmente de acuerdo sobre qué es un "personaje peligroso", y esos problemas son propensos a ocurrir. muchas razones, incluyendo simples actualizaciones de software.
Consulte, por ejemplo, esta pregunta para un ejemplo de la clase de cosas que no son capturadas por el marco mental del "personaje que se escapa". Cada vez que veo las funciones select * from users where id = $paramIdFromWebForm;
y mysql_escape_string()
, mis ojos sangran, y me pregunto si no hay en algún lugar una función llamada mysql_real_escape_string()
.
No obstante, hay una forma adecuada de generar expresiones SQL de forma dinámica sin tener que abordar los problemas de "código de datos": expresiones parametrizadas . Se trata de trabajar con la representación abstracta del código SQL, el después de analizar. Cuando usamos expresiones parametrizadas, no intentamos revertir el paso del análisis, y la seguridad es mucho mejor (y también es buena para el rendimiento).
Por lo tanto, no es realmente el error de SQL; El programador aún tiene la culpa, por no usar las soluciones correctas que existen y están documentadas . Todavía podemos considerar que los diseñadores de SQL, y, en particular, las personas que integraron SQL en PHP, deberían haber hecho algunos esfuerzos para hacer que la construcción de expresiones SQL dinámicas sea un poco más difícil cuando no se usa la parametrización. Para un mejor diseño de lenguaje (con respecto a este problema específico), consulte LINQ : mantiene la sintaxis a la que pertenece, es decir en el código fuente, no en cadenas de caracteres interpretadas en tiempo de ejecución.