¿Te has preguntado por que PHP tiene tan mala fama en cuanto a seguridad (y en particular con los SQL Injects)? ¿Realmente se la merece? Vamos al lio ⬇
Antes de nada, para los despistados, aclaración rápida de que es un SQL Inject: es cuando copiáis y pegáis de StackOverflow sin saber qué estáis haciendo.

Mas leer documentación y menos intentar sacar las cosas a base de prueba y error, gandules! ImageImage
Todo empezó con PHP 2 cuando nuestro querido Rasmus Lerdorf (no estoy de coña, así se llama el creador de PHP. Tontos nosotros por no ver la señal luminosa...) integraba PHP con las bases de datos del momento y se dio cuenta que se podían colar comillas simples en las...
...consultas SQL y eso podía provocar errorcillos... por decirlo de alguna manera...

"Esto no puede ser! Debo hacer que PHP sea seguro! Debo evitar los SQLi" se dijo a si mismo. Y creó la función "AddSlashes()" [1], que "escapaba" los caracteres $, \ y ' y así evitaba los SQLi.
Nota: Los escapaba poniendo delante un \ , cuando ANSI SQL expresamente recomienda no hacerlo asi.

[1] php.net/manual/phpfi2.… Image
Escapando únicamente esos caracteres no se cubrían ataques usando unicode (que ya llevaba 6 años existiendo). Supongo que tampoco era plan de hacerlo 100% seguro. ¯\_(ツ)_/¯ Image
Otro problema de AddSlashes() era que... había que usarlo. Y la gente no iba a usarlo, porque al fin y al cabo PHP estaba orientado a gente que quería montarse una página web rápidamente, sin leer mucha documentación y sin complicarse (🧐 anda... esto me suena...).
Así que nuestro profeta tuvo una revelación divina.

"Si los brogramadores no van a AddSlashes(), llevaremos AddSlashes() a los brogramadores!"
Básicamente, cualquier cadena que se enviaba al servidor, PHP la pasaba automáticamente por AddSlashes() y así se evitarían los SQLi.

Bienvenidos a los "magic quotes" (activados por defecto).

"Ahora ya todo el mundo estará protegido contra SQLi, aunque ni sepan que es eso!" Image
No veas las risas de tener que des-escapar cadenas de texto (hola "StripSlashes()" [2]) en los formularios de contacto que se mandaban por correo. PHPMailer tuvo que introducir lógica especial[3] para desactivar temporalmente los magic quotes mientras hacía su trabajo.
Con PHP 4 re-implementaron y mejoraron "addslashes()" [4] (y por lo tanto los "magic quotes").

Ahora ya no escapaba el $, pero añadieron " y NULL a la lista de caracteres a escapar.
Todo se seguía escapando con \ y los caracteres unicode se seguían ignorando (unicode ya llevaba 9 años existiendo).

[4] php-legacy-docs.zend.com/manual/php4/en…

"Se ha hecho lo que se ha podido..."
(Eso es lo que creo que pensó Rasmus)
El caso es que el tío sabía que todo esto era una ñapa que se le había ido de las manos, así que en paralelo estaba trabajando en la solución definitiva, la cual anunció también en PHP 4: "mysql_escape_string()". Esta función era como "addslashes()", solo que mejor!
Mejor en el sentido de que escapaba todavía mas caracteres! El \n, el \r y el \032.
¿Pero entonces esta ya soportaba unicode y por lo tanto evitaba el ataque este de la runa china?

Mmmm... pues no.
"Cago en la leche, Merche, se me ha vuelto a olvidar la historia del unicode..."

(así es cómo me imagino que reaccionó Rasmus al dar un paso atrás y observar su obra)
Con PHP 4.3 nació "mysql_real_escape_string()" (que también se podría haber llamado "mysql_ahora_si_v2_escape_string()").

Esto era el siguiente intento de poner fin a los SQLis.
Y esta ya soportaba unicode!! ...
... pero no escapaba los "
En PHP una cadena se puede crear con ' o ". Y si dentro se quieren poner mas comillas, se pueden escapar con \ o se pueden duplicar. Ejemplos validos:

$s = 'prueba'
$s = "prueba"
$s = 'prue"ba'
$s = "prue'ba"
$a = 'prue''ba'
$a = "prue""ba"
$a = 'prue\'ba'
$a = "prue\"ba"
¿Os acordáis de eso que ANSI SQL no recomendaba usar \ para escapar?

Eso en MySQL se llama NO_BACKSLASH_ESCAPES y si está activado* provoca que \ no sirva como carácter de escape.

*muy probable; la propia doc de MySQL recomendaba activarlo para evitar el marrón de addslashes()
Todo esto quiere decir que "mysql_real_escape_string()" tiene que comprobar si "NO_BACKSLASH_ESCAPES" está activado y si lo está duplicar las comillas en las cadenas en vez de escaparlas con \ ...
... el problema es que "mysql_real_escape_string()" usa "escape_quotes_for_mysql()" [5], y esta a su vez no puede saber que comillas se han usado para definir la cadena, así que...
...asume que se ha usado ' y por lo tanto duplica todos los ' e ignora todos los "

[5] bazaar.launchpad.net/~mysql/libmysq…
Esto significa que dependiendo de las comillas que has usado para definir la cadena, se te podría colar un SQLi con un simple " Image
"Joder, ya valió con las putas comillas, cojones. Que tengo otras cosas que hacer... por eso no podemos tener cosas bonitas..."

- Rasmus SQLinjectof, lamento al óleo sobre lienzo de piel de asno, circa 2003 Image
Viendo que todo esto era un fracaso continuo, nuestro ídolo decidió replantearse todo de 0. Y para PHP 5.1 nació PDO.

Y PDO era un gran avance! Bueno... regulinchi...
Se acabo lo de concatenar cadenas de texto y jugar al escapa-escapa. Lo malo es que seguías siendo parcialmente vulnerable al ataque de la runa china que mencioné mas arriba.
El problema venía de que PHP y la base de datos no se ponían de acuerdo que encoding usar y cada uno interpretaba los multibytes como le daba la gana, lo cual provocaba que en algunos encodings pudieras provocar el SQLi.
El segundo problema es que PHP no implementó manera alguna de "poner de acuerdo" PDO y la base de datos sobre el encoding que debían usar hasta la versión 5.3.6.
Pero oye, son edge cases. Podríamos dar el tema por arreglado... Excepto que PDO es un pelín lento y bastante tosco de usar (es una solución genérica).
Viene el "aparta, que no sabes"...

Nace la extensión "MySQLi"
("i" de "basta ya de Injections, por favor", me imagino).

Esto viene a ser una extensión dedicada a MySQL, por fuera de PHP, que quiere marcar historia. Y joder si la marca...
¿Veis la sensación de desesperación al ver que en Star Wars un jedi mata a su padre y se convierte en el malo malísimo y luego 6 pelis más tarde otro jedi mata a su padre y se convierte en el nuevo malo malísimo y vuelta a empezar? Pues esto igual.
Por lo visto nadie ha aprendido absolutamente nada sobre el tema de preparar queries en vez de jugar al escapa-escapa. Así que obviamente MySQLi repite toda la historia con "mysqli_real_escape_string()" [6].

[6] php.net/manual/en/mysq…
Siguen pasando los años y "web hecha en PHP" es prácticamente sinónimo de "mas SQLi que estrellas en el cielo". (Hola WordPress, Drupal, Prestashop!)
Siguen pasando los años y empiezan a nacer frameworks y con ellos el concepto de "ORM".

Parece que "ORM" por fin entiende que escribir queries a mano es la receta perfecta para dispararse en el píe, así que esconde todo eso detrás de...
...unas cuantas funciones que "mapean" objetos de datos a instrucciones de SQL.

Pasamos a otro nivel completamente. Aquí ya no existe ni el concepto de "escapar" ni el de "preparar queries". El programador puede olvidarse de escribir sentencias en SQL.
La parte negativa es que ahora cada framework tiene su propio ORM, y esos ORM también pueden tener vulnerabilidades; lo cual significa que hemos incrementado exponencialmente el vector de ataque.
Por si fuera poco, tenemos a los PEACHEPEROS viejos que ya no tienen ganas de aprender cosas nuevas y esto de los frameworks y los ORMs se les queda muy ajeno;
a los PEACHEPEROS jovenes que no han vivido nada de esto y no le tienen miedo a escribir alguna que otra query a mano porque algunos edge cases con el ORM se hacen difíciles;
y a los PEACHEPEROS que deben soportar legacy y por mucho que quieran, no pueden usar ORMs.
Conclusión: PHP intentó solucionar varias veces (de manera tonta e ingenua, ignorando parte de la problemática) un problema cuya solución no pasa por el código, sino por el programador.

Pro tip: No seáis chapuceros.

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Diario de un picateclas

Diario de un picateclas Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @devruso

3 Jul
Sigues sin tener ni la más mínima idea de que cojones es todo eso de los "módulos" de JS y a estas alturas ya te da hasta corte preguntar? O a lo mejor simplemente quieres tener más munición para cagarte en toda la estirpe de JS? En cualquier caso este es tu hilo! ⬇
Todo empezó hace muchos años, cuando alguien decidió que meter 84 toneladas cúbicas de JS en cada página para hacer un sinfín de virguerías molestas era buena idea.
Y así nacieron los "utils.js" de un peso medio más alto que la mama de tu peor enemigo y de un contenido de dudosa calidad, fruto de meses y meses de copiar y pegar de foros daniweb y yahoo answers. Pero incluso los peores chapuceros javascripteros se dieron cuenta...
Read 35 tweets
14 May
Sheldon tenía un "Fun with Flags", yo tengo un "Fun with Strings". Por demanda popular, ¡DENTRO HILO! ⬇
Todo empezó hace un porrón de años cuando los arcanos de los 0 y los 1 inventaron la tabla ASCII.
Majestuosa tabla que contenía absolutamente todas las letras, números y símbolos. Todos los
que se les ocurrieron en 1 tarde, quiero decir.
Y todo era maravilloso, porque con 1 byte representábamos cualquier carácter.
Y para medir "la longitud" de una cadena nos bastaba con contar cuántos bytes tenía, porque 1 letra = 1 byte.
Y para pasar de mayusculas a minúsculas sumabas 32 al valor decimal del carácter y pista.
Read 24 tweets
17 Feb
¿Os habéis preguntado por qué en nuestro campo existe tanta sobre ingeniería y por qué todo se ha vuelto innecesariamente complejo?
Os cuento el motivo, ejemplos incluidos! Dentro hilo ⬇
Hay todo un cumulo de motivos y razones. Desde falta de dirección, falta de visión global, herramientas y/o arquitectura incorrecta, solución mal planteada o ejecutada, cúpula de la cadena de mando completamente descerebrada, etc...
Si esto fuese un blog, me saldría un post de 60.000 palabras (10.000 irían al síndrome de "Yo también!" de la comunidad de JavaScript), pero no lo es, así que voy a resumirlo todo en un vicioso bucle de 5 pasos.
Read 13 tweets
24 Jan
A ver, en serio, ¿a nadie más le fascina el mundo de los virus de wordpress?

Necesito abriros los ojos a esa maravilla! ⬇
Cuando te montas un server pequeño para "meter mierdas" dentro (la web de tu cuñado, el pet project del fin de semana, el owncloud para luego no meter nada dentro, etc...), sueles buscar un panel de control que te facilite las cosas (plesk, cpanel, ispconfig...)
Pero es que resulta que todo eso es perder el tiempo. Hay maneras muchísimo mas cómodas y rápidas de hacerte con un panel de control.

¿Cómo? Muy fácil: te instalas un wordpress con 50 plugins en el server.
Read 10 tweets
22 Jan
Pensabais que la vida de los devs frontend es miserable? Vamos con la de los devs full-stack en microempresas tipo MadHouse! ⬇
Estas tú tan tranquilamente sentado en tu puesto de trabajo, picatecleando mierdas, cuando aparecen (en manada) los 3 "jefecillos" (por llamarlos de alguna manera, porque "personajes de cuidado que nadie sabe a qué se dedican en la empresa" queda feo).
Se sientan a tu alrededor (en plan emboscada) y sacan el cuaderno con las <ideas>. Sigue una tanda de chorradas, a cada cual mas loca que la anterior.
Read 15 tweets
24 Dec 20
Que tiempos los de hace 15 años! Te mandaban hacer alguna chuminada en PHP (leer un excel o manda correos por SMTP), y tu, sin ganas, te ibas a Google a buscar como hacerlo, te encontrabas con "chilkat php extension", pero era de pago. (...)
La pagabas con el eMule, y luego la subías por FTP al server, reiniciabas el PHP (te subadan los cojones si había clientes viendo la web o si eran las 12 del mediodía). Aquello petaba 20 veces porque la extensión no era compatible con esa versión de PHP, pero no pasaba nada (...)
porque tu, previsor, ya tenías listas para subir 7 u 8 versiones más.

Al final alguna funcionaba y te decías "venga, perfecto, ahora a picar" y te tirabas el resto de la tarde subiendo el test.php al server y dandole al F5 en mierdapagina.com/test.php para probar.
Read 5 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!

Follow Us on Twitter!

:(