He estado leyendo / viendo mucho contenido de Robert C. Martin. Me he encontrado con él diciendo que SQL es innecesario debido a las unidades de estado sólido. Cuando busco en otras fuentes para respaldar esto, recibo un montón de artículos aleatorios que describen la diferencia del rendimiento de SQL entre los discos duros y las unidades de estado sólido (que está relacionado pero no es lo que estoy tratando de investigar).
En última instancia, no entiendo a qué está tratando de llegar. ¿Está diciendo reemplazar SQL con tecnologías No-SQL? ¿Está diciendo almacenar datos en archivos en un sistema de archivos? ¿O solo quiere que la gente deje de usar SQL / Bases de datos relacionales debido a los ataques SQLi? Me temo que me estoy perdiendo el punto que está tratando de hacer.
Proporcionaré algunos enlaces aquí para que pueda leer directamente de su mente:
Primero, afirma que SQL debería eliminarse por completo del sistema.
La solución. La única solución. Es eliminar SQL del sistema por completo. Si no hay un motor SQL, entonces no puede haber ataques SQLi.
Y aunque habla de reemplazar SQL con una API, NO creo que se refiera a poner SQL detrás de una API debido a esa cita previa y lo que dice anteriormente en el artículo.
Los marcos no manejan el problema; ...
Nota al margen: al decir SQL, estoy bastante seguro de que Robert se refiere a la mayoría de las bases de datos relacionales. Quizás no todos, pero la mayoría. En cualquier caso, la mayoría de las personas están utilizando SQL de todos modos. entonces...
Si SQL no se usa para conservar datos, entonces, ¿qué se supone que debemos usar?
Antes de responder eso, también debo señalar. Robert enfatiza que las unidades de estado sólido deberían cambiar las herramientas que utilizamos para conservar los datos. La respuesta de Søren D. Ptæus señala esto.
También debo responder al grupo "pero integridad de datos". Tras una investigación adicional, Robert dice que deberíamos usar bases de datos transaccionales como datomic . Luego, CRUD se convierte en CR (crear y leer) y las transacciones SQL desaparecen por completo. La integridad de los datos es, por supuesto, importante.
No puedo encontrar una pregunta que abarque todo esto. Supongo que estoy buscando alternativas que coincidan con las pautas de Robert. Datomic es uno pero ¿es eso? ¿Qué otras opciones coinciden con estas pautas? ¿Y funcionan realmente mejor con unidades de estado sólido?
eval(request.GET["table_name"] + ".get(pk=" + request.GET["pk"] + ")"))
. No es SQL el que realmente tiene la culpa, sino programadores pobres e ignorantes.Respuestas:
Bob Martin está exagerando claramente para dejar su punto más claro. ¿Pero cuál es su punto?
Según tengo entendido, en esa publicación de blog (su primer enlace) Martin intenta convencer a la gente de que deje de usar SQL, pero no las bases de datos relacionales. Estas son dos cosas diferentes .
SQL es un lenguaje extremadamente poderoso, y está estandarizado hasta cierto punto. Permite crear consultas y comandos complejos de una manera muy compacta, de manera legible, comprensible y fácil de aprender. No depende de otro lenguaje de programación, por lo que es utilizable para la mayoría de los programadores de aplicaciones, sin importar si prefieren Java, C, C ++, C #, Python, Ruby, JavaScript, Basic, Go, Perl, PHP u otra cosa.
Sin embargo, este poder tiene un costo : escribir consultas / comandos SQL seguros es más difícil que escribir preguntas inseguras. Una API segura debería facilitar la creación de consultas seguras "por defecto". Las personas potencialmente inseguras deberían necesitar más esfuerzo mental o al menos más de tipeo. En mi humilde opinión, Martin está despotricando contra SQL en su forma actual.
El problema no es nuevo y existen API más seguras que el SQL estándar para acceder a una base de datos relacional. Por ejemplo, todos los mapeadores OR que conozco están tratando de proporcionar dicha API (aunque generalmente están diseñados para otros objetivos principales). Las variantes de SQL estático dificultan la creación de consultas dinámicas con datos de entrada no desinfectados (y eso no es una invención nueva: el SQL incorporado, que a menudo utiliza SQL estático, tiene alrededor de 30 años).
Desafortunadamente, no conozco ninguna API que sea tan flexible, estandarizada, madura, independiente del lenguaje y también tan poderosa como SQL, especialmente SQL dinámico. Es por eso que tengo algunas dudas sobre la sugerencia de Martin de "no usar SQL" como una forma realista de resolver los problemas mencionados. Entonces lea su artículo como un pensamiento en la dirección correcta, no como una "mejor práctica" que pueda seguir ciegamente a partir de mañana.
fuente
La opinión de Bob Martin es solo eso; La opinión de un hombre.
Se espera que un programador entienda el sistema que está escribiendo lo suficientemente bien como para ejercer un cuidado razonable sobre su seguridad y rendimiento. Eso significa que, si está hablando con una base de datos SQL, hace lo que dice el sitio web de Bobby Tables : desinfecta sus datos de entrada. Significa que coloca su base de datos SQL en una máquina que promete un rendimiento adecuado. Hay formas muy conocidas y bien entendidas de hacer estas cosas, y si bien no garantizan una seguridad absoluta o un rendimiento ideal, ninguna otra cosa lo hace.
La afirmación de que ya no necesitamos SQL porque ahora tenemos SSD es simplemente engañosa. SQL no fue inventado porque los discos duros de alta velocidad aún no existían; se inventó porque necesitábamos una forma estándar de la industria para expresar conceptos de recuperación de datos. Los sistemas de bases de datos relacionales tienen muchas otras cualidades además de la velocidad y la seguridad que los hacen ideales para las operaciones comerciales; en particular, ACID . La integridad de los datos es al menos tan importante como la velocidad o la seguridad, y si no los tiene, ¿cuál es el punto de proteger los datos incorrectos o recuperarlos lo más rápido posible?
Antes de tomar la histeria de un hombre como evangelio, le sugiero que aprenda sobre la seguridad y el rendimiento de las aplicaciones y sistemas en sus propios términos, no leyendo artículos aleatorios de Internet. La seguridad, el rendimiento y el diseño robusto del sistema son mucho más que simplemente "evitar esta tecnología".
No prohibimos los cuchillos de cocina porque algunas personas desafortunadas logran cortarse accidentalmente los dedos con ellos.
fuente
¿Qué está diciendo realmente?
TL; DR: Sí (más o menos)
En una charla más reciente que a la que se vinculó básicamente sobre el mismo tema, dice: "La base de datos es un detalle. ¿Por qué tenemos bases de datos?" .
Afirma que la base de datos se creó para facilitar el acceso a los datos de los discos giratorios, pero en el futuro "no [...] habrá discos" gracias a la nueva tecnología y lo que él llama "RAM persistente" y que será más fácil de usar. almacenar datos utilizando las estructuras que usan los programadores, como tablas hash o árboles.
Continúa prediciendo que las bases de datos relacionales en general desaparecerán en gran medida debido a su nueva competencia:
Entonces no, para él no se trata solo de inyección SQL, aunque opina que SQL es inherentemente defectuoso en este sentido .
Nota del autor:
Las declaraciones en esta publicación son solo citas para comprender la opinión de Robert C. Martin sobre este tema y no representan la opinión del autor. Para un punto de vista más diferenciado, vea la respuesta de Robert Harvey .
fuente
SQL es un detalle. El conocimiento de un detalle no debe extenderse.
A medida que SQL se usa en más y más lugares en su código, su código se vuelve cada vez más dependiente de él.
A medida que aprende más y más trucos SQL, resuelve más y más problemas usando SQL. Esto significa que cambiar a otra API para persistir implica más que solo traducir. Tienes que resolver problemas que no sabías que tenías.
Te encuentras con esto incluso cambiando entre bases de datos. Uno ofrece la sofisticada característica 5 de whizzbang, por lo que la usa en varios lugares solo para descubrir que la característica 5 de whizzbang es exclusiva y ahora tiene un problema de licencia que costará mucho dinero. Por lo tanto, hace mucho trabajo desenterrando en todos los lugares donde usó la función 5 y resolviendo el problema por su cuenta solo para descubrir más tarde que también está usando la función 3 whizzbang.
Una de las cosas que hace que Java sea tan portátil es que ciertas características de la CPU simplemente no están disponibles. Si estuvieran disponibles, los usaría. Y de repente hay CPU en las que mi código Java no funcionará porque no tienen esas características. Es lo mismo con las características de la base de datos.
Es muy fácil sacrificar su independencia sin darse cuenta. SQL es una elección, no un hecho. Si toma la decisión de usar SQL, hágalo en un solo lugar. Hazlo de una manera que pueda deshacerse.
El hecho de que SQL tenga problemas de seguridad y que nos estamos moviendo a modelos de memoria persistentes no significa que SQL esté condenado. Simplemente lleva a casa el punto de que es una elección. Si desea preservar el derecho a tomar esa decisión, debe hacer el trabajo.
Vale la pena señalar que el movimiento de la base de datos de los años 80 y el tío Bob tienen una historia bastante desagradable. Tenía todos sus problemas resueltos con un sistema de archivos planos cuando la administración forzó a un administrador de base de datos a entrar en su vida. Este evento lo empujó a su carrera estelar de consultoría. (Él cuenta esta historia en uno de sus primeros libros limpios, olvide cuál) Sabe cómo resolver problemas sin DB's y tiene poca paciencia para aquellos que actúan como si fuera un hecho.
También cuenta una historia sobre posponer la adición de una base de datos a una aplicación hasta el último minuto cuando un cliente la solicitó, y la agregó en un día como una característica opcional. Mi conjetura es que él ve que la mayoría de nosotros usamos los DB como adicción. Está tratando de mostrarnos cómo dejar el hábito.
fuente
La cita de tu primera cita es (énfasis mío),
La queja está en contra de dejar que los programadores de aplicaciones usen SQL.
La solución sugerida es permitirles usar una API en su lugar: que no es SQL y no permite la inyección.
En mi opinión, los ejemplos de tales API pueden incluir:
http://bobby-tables.com/csharp sugiere que los programadores de C # puedan usar la API ADO.NET.
Ese no es un ejemplo perfecto porque ADO.NET es una API amplia o profunda (es decir, potente o de uso general), que también permite a sus usuarios ingresar SQL sin formato (o sin formato).
Algunos desarrolladores de SQL o administradores de bases de datos sugieren que una base de datos debe configurarse de modo que solo permita el acceso a través de (un número limitado de procedimientos almacenados por expertos) , y que los desarrolladores de aplicaciones no deberían poder escribir sus propias consultas SQL (peligrosas)
Otra forma de "eliminar SQL del sistema" es colocar la base de datos (que expone SQL) en otro sistema, al que se accede a través de una API REST o similar.
Por lo tanto, en mi opinión, la solución general o el sistema (s) todavía pueden usar una base de datos (especialmente dado que un motor de base de datos implementa propiedades útiles de ACID y se escala bien, etc.) puede ser una tontería intentar prescindir de una, o escribir una aplicación específica).
Los requisitos de la queja se cumplen si la API SQL de la base de datos está oculta para los desarrolladores de la aplicación, detrás de alguna otra API (por ejemplo, ADO, quizás un ORM, un servicio web o lo que sea).
En general, supongo que significa tener un DAL específico de la aplicación (una "capa de acceso a datos" o "capa de abstracción de base de datos"). Un DAL aísla la aplicación de los detalles de cómo y dónde se almacenan y / o obtienen los datos. El DAL puede o no implementarse usando una base de datos SQL.
fuente
Todos parecen estar respondiendo esta pregunta desde un punto de vista de seguridad, o con una lente SQL.
Vi una conferencia de Robert Martin donde relata que, como programadores, utilizamos muchas estructuras de datos diferentes que son óptimas para nuestros programas específicos. Por lo tanto, en lugar de almacenar universalmente todos los datos en una estructura tabular, debemos almacenar nuestros datos en tablas hash, árboles, etc. para que podamos tomar los datos y saltar directamente al programa.
Interpreté su mensaje como solo diciendo que deberíamos descartar nuestros supuestos actuales sobre el almacenamiento persistente por un momento para considerar otras posibilidades futuras además del antiguo formato tabular SQL. SSD es una solución candidata, pero no la única.
fuente
En realidad, no debe usar bases de datos y SQL, de manera bastante explícita. La primera referencia es un tema bien conocido, la segunda referencia suena como una queja. Aunque, estoy interpretando que tiene una buena razón para usar bases de datos y no usar SQL. Desde mi punto de vista, esto ni siquiera es un consejo razonable.
Desafortunadamente, el ejemplo que está usando es un ejemplo bien conocido con una solución bien conocida que luego señala. Suele ocurrir cuando un programador no se da cuenta de lo que está haciendo. Por ejemplo, la construcción de cadenas que contienen SQL como:
Opuesto a
Este es un ejemplo de DBI perl para el código ruby on rails. El código de rieles que proporciona es fácil de confundir entre lo seguro y lo inseguro. Al igual que muchos ORM, se esconde lo que está debajo del SQL y, a menudo, se trata de una interfaz que construye y ejecuta el sql por usted. ¿No suena esto casi como lo que una API estaría haciendo por ti?
Mi interpretación de la primera referencia es que sugiere que deberíamos reemplazar un problema bien conocido que tenga una solución bien conocida.
También es lamentable que no mencione que si se hace correctamente hará que el código sea más fácil de escribir y más legible, aunque si se hace bien, en realidad puede ser más difícil de escribir y menos legible. Además, no menciona que SQL es realmente muy fácil de leer y hace lo que generalmente esperaría que hiciera.
Es parcialmente correcto, en última instancia tendremos una memoria infinitamente grande y rápida y un procesador infinitamente rápido. Hasta que nos salgamos de la física actual que restringe la informática, él no está en lo correcto.
Sí, el disco giratorio es cosa del pasado, y ahora usamos SSD. Los discos funcionan con aproximadamente ~ 10 milisegundos por transferencia de datos, los SSD funcionan con ~ 0.5 milisegundos (500 microsegundos) de tiempo de acceso a datos. La RAM es del orden de 100 nano segundos, los procesadores funcionan en el orden de 100 segundos de pico segundos. Este es el corazón de por qué necesitamos bases de datos. Las bases de datos administran la transferencia de datos entre discos giratorios o SSD con memoria principal. El advenimiento de los SSD no ha eliminado la necesidad de bases de datos.
fuente
Responder
El artículo 'Bobby Tables' parece sugerir que esto, en sí mismo, es una razón para no usar SQL:
Él podría tener otras razones que discute en otra parte. No lo sabría porque realmente no leo mucho de sus cosas.
Digresión
Esta parte no es realmente una respuesta, pero creo que la cuestión del valor de SQL es mucho más interesante (al igual que otros, aparentemente).
Tengo mucha experiencia en el uso de SQL y creo que tengo una buena comprensión de sus fortalezas y debilidades. Mi sensación personal es que ha sido abusado y abusado, pero que la idea de que nunca deberíamos usarlo es un poco tonto. La idea de que debemos elegir 'SQL siempre' o 'SQL nunca' es una falsa dicotomía.
En cuanto a que la inyección SQL sea un argumento para no usar SQL, eso es ridículo. Este es un problema bien entendido con una solución bastante simple. El problema con este argumento es que SQLi no es la única vulnerabilidad que existe. Si crees que usar las API JSON te hace seguro, te espera una gran sorpresa.
Creo que todos los desarrolladores deberían ver este video titulado "Viernes 13: Atacando a JSON - Alvaro Muñoz & Oleksandr Mirosh - AppSecUSA 2017"
Si no tiene el tiempo o la inclinación para mirarlo, aquí está la esencia: muchas bibliotecas de deserialización JSON tienen vulnerabilidades de ejecución remota de código. Si está utilizando XML, tiene aún más de qué preocuparse. Prohibir SQL de su arquitectura no hará que su sistema sea seguro.
fuente
Quiero abordar solo una breve declaración:
No. Esa es una suposición equivocada. No podemos decir que debemos dejar de usar automóviles, porque son responsables de las personas que mueren en accidentes automovilísticos. Del mismo modo, las bases de datos SQL / relacionales (o cualquier otra cosa en este contexto, como RDBMS) no son responsables de la carga maliciosa de SQL que un atacante puede realizar en su aplicación web. Estoy seguro de que el autor no quiso decir eso, porque hay toda una hoja de trucos de prevención de inyección SQL para este propósito.
fuente
El problema de Martin parece ser que los programadores construyen SQL dinámico directamente desde la entrada del usuario, algo así como (perdóname, soy principalmente un programador C y C ++):
que es absolutamente una receta para la acidez estomacal (de ahí la tira de Bobby Tables ). Cualquier programador que ponga código como ese en un sistema de producción merece un paddlin '.
Puede mitigar (si no eliminar por completo) el problema utilizando declaraciones preparadas y desinfectando adecuadamente sus entradas. Si puede ocultar el SQL detrás de una API de modo que los programadores no estén creando directamente cadenas de consulta, mucho mejor (que es parte de lo que Martin defiende).
Pero en cuanto a deshacerse de SQL por completo, no creo que sea práctico o deseable. Los modelos relacionales son útiles , por eso existen en primer lugar, y SQL es probablemente la mejor interfaz para trabajar con modelos relacionales.
Como siempre, se trata de utilizar la herramienta adecuada para el trabajo. Si su aplicación de carrito de compras no necesita un modelo relacional completo, entonces no use un modelo relacional (lo que significa que no necesitará usar SQL). Para las veces que necesite un modelo relacional, entonces seguramente trabajará con SQL.
fuente
sprintf
no contiene el tipo de desinfección que requiere SQL, las funciones diseñadas específicamente para este propósito sí lo hacen y son perfectamente seguras. Ejemplo: SqlQuery en Entity Framework .sprintf
utilizan SQL dinámico, que no es cómo lo haces.Las dos fuentes que vincula transmiten mensajes diferentes:
La publicación del blog dice que la lógica de acceso a datos no debería existir como texto en tiempo de ejecución, para que no se mezcle con la entrada del usuario no confiable. Es decir, la publicación del blog condena la escritura de consultas mediante la concatenación de cadenas.
La conferencia es diferente. La primera diferencia está en el tono: la conferencia especula y cuestiona, pero no condena. No dice que las bases de datos sean malas, pero nos desafía a imaginar la persistencia sin una base de datos. Argumenta que en los 30 años transcurridos desde que las bases de datos relacionales se generalizaron, muchas cosas han cambiado, y destaca dos que posiblemente podrían afectar nuestra elección de tecnología de persistencia:
¿Estas circunstancias cambiantes cambian la tecnología de persistencia óptima? Curiosamente, el tío Bob no lo dice, presumiblemente porque siente que ninguna respuesta sería correcta para todos los programas. Es por eso que nos advierte que tratemos nuestra elección de tecnología de persistencia como un detalle en lugar de consagrarla en tabletas de piedra y transmitirla como sabiduría recibida a nuestros compañeros.
¿Existen alternativas?
Escribir lógica de acceso a datos sin cadenas es completamente posible. En la tierra de Java, puede usar QueryDSL , donde las consultas se describen utilizando una API con fluidez de tipo seguro generada a partir de su esquema de base de datos. Tal consulta podría tener el siguiente aspecto:
Como puede ver, la lógica de la consulta no se expresa como una Cadena, separando claramente la estructura confiable de la consulta de los parámetros no confiables (y, por supuesto, QueryDSL nunca incluye los parámetros en el texto de la consulta, sino que usa declaraciones preparadas para separar la consulta para sus parámetros en el nivel JDBC). Para lograr la inyección SQL con QueryDSL, tendría que escribir su propio analizador para analizar una cadena y traducirla a un árbol de sintaxis, e incluso si lo hiciera, probablemente no agregaría soporte para cosas desagradables como
select ... into file
. En resumen, QueryDSL hace que la inyección de SQL sea casi imposible, y también mejora la productividad del programador y aumenta la seguridad de refactorización. Se evitó el mayor riesgo para la seguridad de las aplicaciones web, que ha existido el tiempo suficiente para generar gags en ejecucióny aumentó la productividad del desarrollador? Me atrevo a decir que si todavía escribes consultas como cadenas, lo estás haciendo mal.En cuanto a las alternativas a las bases de datos relacionales, es curioso saber que el control de concurrencia de versiones múltiples de Postgres es exactamente ese tipo de estructura de datos de solo agregar de la que habla el tío Bob, aunque probablemente estaba pensando más en las tiendas de eventos y el abastecimiento de eventos patrón en general, que también encaja perfectamente con la noción de mantener el estado actual en la RAM.
fuente