Foro de elhacker.net

Programación => Desarrollo Web => Mensaje iniciado por: MiguelCanellas en 31 Julio 2020, 00:17



Título: [Resuelto]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: MiguelCanellas en 31 Julio 2020, 00:17
Hola,

quería saber si era no se si buena práctica porque no creo que sea muy común, pero veo que puede resultar más fácil y la verdad no veo mucha diferencia... Tampoco quiero que por hacer algo fácil el "sistema" quede horrendo...

como en el post anterior, había dicho que cuando una cadena tiene "hola ' mi nombre es..." esa comilla simple puede dar problemas, y también al reves si fuera unas comillas dobles...

¿Habrá algún problema si decido transformar todo lo que se reciba de esta manera?

Código
  1. $x = str_replace("'", "’"); // cambió ' por ’
  2. $x = str_replace('"', '”'); // cambió " por ”
  3.  

No veo mucha diferencia hasta en estilo puede quedar un poquito mejor (creo)

¿Qué opinan?

EDIT: Me fijé que habría un problema si el usuario registra una contraseña como por ejemplo...

micontraseña'123

entonces su contraseña sería

micontraseña’123

pero voy a prohibir las contraseñas con comillas simples y dobles y ya...


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: EdePC en 31 Julio 2020, 00:46
Dependerá del destino, por ejemplo en MiriadaX (una página de cursos gratuitos) hay cursos de programación PERO han tenido la fantástica idea de mostrar código fuente ya sea en sus PDFs o en Capturas de Pantalla o en la misma página, con esas problemáticas comillas, y pues hay muchas quejas de algunos usuarios que copian y pegan este código dando error al intentar ejecutarlos XD.

Si es solo para lectura como bien ya lo hace Word o Indesign que al momento que poner las comillas sencillas las convierte las comillas tipográficas, no debería haber problemas, "porque se ven mejor" para texto.

- También considera la codificación de caracteres html destino, normalmente para evitarse estos problemas siempre se codifican los caracteres no estandar (htmlentities lo hace perfectamente). Tampoco debería de haber mayor problema porque los navegadores web modernos usan por defecto UTF-8 y deberían de poder mostrar correctamente esos caracteres.


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: MiguelCanellas en 31 Julio 2020, 00:54
Dependerá del destino, por ejemplo en MiriadaX (una página de cursos gratuitos) hay cursos de programación PERO han tenido la fantástica idea de mostrar código fuente ya sea en sus PDFs o en Capturas de Pantalla o en la misma página, con esas problemáticas comillas, y pues hay muchas quejas de algunos usuarios que copian y pegan este código dando error al intentar ejecutarlos XD.

Si es solo para lectura como bien ya lo hace Word o Indesign que al momento que poner las comillas sencillas las convierte las comillas tipográficas, no debería haber problemas, "porque se ven mejor" para texto.

- También considera la codificación de caracteres html destino, normalmente para evitarse estos problemas siempre se codifican los caracteres no estandar (htmlentities lo hace perfectamente). Tampoco debería de haber mayor problema porque los navegadores web modernos usan por defecto UTF-8 y deberían de poder mostrar correctamente esos caracteres.


jaja estoz MiriadaX

Gracias!!!


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: AlbertoBSD en 31 Julio 2020, 01:50
pero voy a prohibir las contraseñas con comillas simples y dobles y ya...

Por seguridad no se debe de restringir ningun tipo caracter en las contraseñas.

Ni se deben de guardar contraseñas en texto plano en las bases de datos.

Saludos


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: MiguelCanellas en 31 Julio 2020, 01:52
Sí, igual existen millones de combinaciones posibles como contraseñas no creo que restringir las comillas simples y dobles haga alguna diferencia.

En lo de texto plano, ya limpio todo antes de ingresar aunque sea un 1 a la base de datos..

Gracias!


EDIT: Te había entendido mal, si con texto plano te referias a que no está hasheado.. si lo cifro


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: @XSStringManolo en 31 Julio 2020, 01:55
Por qué no le añades a mano el caracter de escape cuando defines el string?

Si vas a meter input de usuario sin sanitizar, te hackean la web. Y esto no lo evitas con html_entities ni la función de turno.

Véase tu ejemplo:
Código
  1. $(selector).html('<p>ves aquella esquina? \' tu madre y tu hermana ahí trabajan!</p>');

Imagínate que me dejas registrarme en tu web y vas a poner mi nombre de usuario ahí:
Código
  1. $(selector).html('stringmanolo');

- Si escapas con remplace las comillas hago:
user: stringmanolo\'); alert(); \'
Y queda:
Código
  1. $(selector).html('stringmanolo\\'); alert(); \\'');

O hago:
user: \'+alert());//
Código
  1. $(selector).html( '\\' + alert() ); //');

Usa htmlpurifier.
https://github.com/ezyang/htmlpurifier


De todas formas si no sabes lo que pueden hacer en las headers, en php, en js, en html, en css, en jquery y demás... Poco vas a solucionar. Acabaras metiendo input sanitizado en el js y te harán inyección.

Deberías leerte libros de seguridad web.


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: MiguelCanellas en 31 Julio 2020, 02:42
Probé tu código... no se si me equivoque con algo o si te olvidaste algo pero todo eso no me afecto en nada.

Código
  1.        <?php
  2. $string_1 = 'stringmanolo\'); alert(); \'';
  3. $string_2 = '\'+alert());//';
  4. //$string_x = [Función para limpiar el dato]
  5. ?>
  6.  
  7. <script type="text/javascript">
  8. $('body').html('<?php echo($string_2); ?>');
  9. </script>
  10.  


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: @XSStringManolo en 31 Julio 2020, 03:08
Uno de los payloads no es válido, ya lo arreglé.

Código
  1. <html>
  2. <body>
  3. <script>
  4. var $body = {
  5.  html: function(string) {
  6.          document.body.innerHTML = string;
  7.        }
  8. };
  9.  
  10. $body.html('\\' + alert(1) ); //');
  11. $body.html('stringmanolo\\'); alert(2);//'
  12.  
  13. </script>
  14. </body>
  15. </html>


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: MiguelCanellas en 31 Julio 2020, 03:28
Uno de los payloads no es válido, ya lo arreglé.

Código
  1. <html>
  2. <body>
  3. <script>
  4. var $body = {
  5.  html: function(string) {
  6.          document.body.innerHTML = string;
  7.        }
  8. };
  9.  
  10. $body.html('\\' + alert(1) ); //');
  11. $body.html('stringmanolo\\'); alert(2);//'
  12.  
  13. </script>
  14. </body>
  15. </html>

Código
  1. Realmente no está haciendo nada, no se que pueda estar mal...
  2.  
  3. <?php
  4. $string_1 = "\\' + alert(1) ); //";
  5. $string_2 = "stringmanolo\\'); alert(2);//";
  6. // $string = Clearn($string, 'x');
  7. ?>
  8.  
  9. <script type="text/javascript">
  10. var $body = {
  11.    html: function(string)
  12.    {
  13.         document.body.innerHTML = string;
  14.     }
  15. };
  16.  
  17. $body.html('<?php echo($string_1); ?>');
  18. $body.html(<?php echo($string_2); ?>
  19. </script>
  20.  

De igual forma, cuando reemplacé las comillas simples y dobles se termino la joda, y cuando limpie toda la cadena también... hasta donde yo entiendo...

No ocurre nada anormal, y eso que pruebo el código sin limpiar nada entonces algo está fallando.


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: MinusFour en 31 Julio 2020, 03:42
En lo de texto plano, ya limpio todo antes de ingresar aunque sea un 1 a la base de datos..

El punto es que no debería haber comillas en los hashes. Así que tu función no hace nada.


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: MiguelCanellas en 31 Julio 2020, 04:04
El punto es que no debería haber comillas en los hashes. Así que tu función no hace nada.

No entiendo que me querés decir.


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: MinusFour en 31 Julio 2020, 04:53
No entiendo que me querés decir.

Usuario viene con contraseña: ´´"'´´"'

Tu, como administrador responsable, no utilizas la contraseña del usuario para nada y corres una función hash para obtener algo como:

$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

La cual no tiene ningún apostrofe, acento o comillas. Así que tu función que remplaza comillas... no hace nada.


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: MiguelCanellas en 31 Julio 2020, 05:03
Usuario viene con contraseña: ´´"'´´"'

Tu, como administrador responsable, no utilizas la contraseña del usuario para nada y corres una función hash para obtener algo como:

$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

La cual no tiene ningún apostrofe, acento o comillas. Así que tu función que remplaza comillas... no hace nada.

Tenes razón, igual quiero aclarar que yo no iba a reemplazar las comillas si se trataba de una contraseña. Solamente verificaba y no lo dejaba continuar si enviaba las comillas.

Claro con el cifrado ya se van las comillas y no hace falta, me ahorro un paso innecesario.

Gracias!


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: WHK en 31 Julio 2020, 07:04
Las buenas prácticas dicen que no debes escapar ningun caracter de entrada, solo los de salida o de envío.

Cada lugar utiliza su propia secuencia de escape de caracteres, el agregar backslash a caracteres especiales no es "porque si", es un estándar definido para evitar vulnerabilidades y que todo funcione bien, pero no todos los estandares y secuencias de escape son iguales.

Lo primero es lo primero, hay que saber que no se deben abusar de los backslash o reemplazo de comillas cuando no se requiera por un estandar a modo de secuencia de escape, por ejemplo:

SQL utliza como secuencia de escape el backslash, asi que si haces una consulta sql manual desde php no debes hacer un reemplazo de caracteres manualmente, para eso existe mysql_real_escape_strting(), HTML utiliza como secuencia de escapes el htmlentities, asi que cuando vayas a exponer contenido sobre HTML debes utilizar la secuencia de escape que viene integrado con php que es htmlspecialchars() y ENT_QUOTES, si vas a incrustar contenido dentro de variables de javascript de manera dinámica debes utilizar la secuencia de escape de caracteres de ecmascript que son los caracteres unicode \u0000 o hexadecimales de tipo \x00 o backslash, pero ojo, en javascript la secuencia de escape no es la misma que la de un sql, no todo se arregla con un backslash, por ejemplo, puedes tener un xss con un simple salto de línea y no lo podrás escapar con un backslash, para eso ya existen funciones que escapan los caracteres especiales.

Una secuencia de escape de caracteres está diseñado por lo general para lenguajes interpretables como bash scripting, php, javascript, html, etc, y estas secuencias impiden conflictos de rompimiento de cadenas, esto provoca una inyección, por ejemplo:

Digamos que tengo esta frase: "Mi nombre es: $nombre y mi apellido es $apellido", entonces, que sucede si en nombre pongo: "nombre y mi apellido es x", entonces la frase quedaría así: "Mi nombre es: nombre y mi apellido es x y mi apellido es $apellido", ves? he inyectado dos apellidos porque no existía un delimitador en la palabra nombre ni en apellido, entonces para evitar estas situaciones existen las secuencias de escapes, por ejemplo, en este caso puedo añadir un - entre cada espacio en blanco, entonces quedaría asi: "Mi nombre es: nombre-y-mi-apellido-es-x y mi apellido es $apellido". Como puedes ver, ahora si se puede diferenciar el nombre del apellido real.

Con los lenguajes de programación sucede lo mismo, si en SQL los valores de tipo texto están encerrados en comillas, entonces como puedes ingresar una comilla como valor? esta rompería la cadena de cierre e inyectarías instrucciones sql, para eso se antepone un backslash, para asegurarse que quieres ingresar una comilla como valor y no rompa la cadena. En HTML pasa lo mismo, si quieres que se  vea una etiqueta html no la escribes tal cual o el navegador la interpretará, para eso existen los htmlentities, sino, inyectarás código html provocando un xss.

En resumidas, no debes agregar backslash asi porque si a cualquier texto o reemplazar caracteres, para eso existen los estandares y si agregas caracteres donde no debes puedes abrir problemas de seguridad, los backslash no se usan porque si, se usan para evitar rompimiento de cadenas y en cada lenguaje o situación el escape es distinto y en cada caso existen funciones nativas que te ayudan a hacer esos escapes.

Por ejemplo, digamos que quieres insertar una cadena de texto de manera dinámica dentro de una etiqueta script en html, debes uilizar dos tipos de secuencia de escape distintos, debes utilizar escape para html y para javascipt potqe javascript estará dentro de html:

Código:
<script>var cadena = '$cadena';</script>

Primeramente $cadena debe estar escapado para javascript, el cual debe evitar todo caracter especial y ser reemplazado por valores en hexadecimales, luego de eso debe ser escapado en htmlentities para evitar una inyeccion en html (aunque no se pueda inyectar debido a la transformación de caracteres especiales en hexadecimal pero es por buena práctica). Por ejemplo:

Código:
<script>
for(var i = 0; &lt;= 100; i++){
    var cadena = '\x0C\x3ch1\x3e Texto';
}
</script>

Como puedes ver, la cadena de texto contiene salto de línea y caracteres html y fueron escapados, pero si te fijas tambien, el for de javascript debiera decir "<=" pero está escapado en htmlentities debido a que el código que se encuentra dentro de la etiqueta <script> debe ser interpretada por el motor que interpreta html y luego que decodifica su contenido lo evaluará como código javascript. Que de todas maneras funcione sin escapar no quiere decir que sea correcto, para ello los navegadores web utilizan una tecnología llamada "tolerancia a errores", eso quiere decir que cuando deben interpretar el código lo corrigen de manera automática dentro de lo posible y luego lo pasan a memoria, por ejemplo, si escribes una etiqueta sin cerrar en xhtml esta se toma como inválido pero el navegador lo muestra de todas maneras, pero hablando estrictamente, el caracter "<" dentro de html sin escapar es un error de sintaxis y el navegador no debiera mostrar el contenido del sitio web, pero de todas maneras lo hace pero no está correcto.

la cadena en javascript va a memoria en mdo plano, eso quiere decir que sin escapar, en la memoria el valor de la cadena equivaldrá al texto con el salto de linea mas la etiqueta html, asi que cuando javascript necesite usar esa cadena y mostrarla sobre un espacio html debe escaparlo.

La solución no pasa por eliminar caracteres o detectar cosas peligrosas como con htmlpurifier o algun ids, la idea es programar como corresponde utilizando los estandares como se debe evitando inyecciones usando las secuencias de escapes como se deben, con eso no debieras porque tener vulnerabilidades de tipo inyección ni debieras porque estar eliminando caracteres o detectando textos peligrosos. Por ejemplo, si en el foro quiero escribir una etiqueta <script> ¿porqué debiera detectarlo como peligroso e impedir que lo escriba?, la idea mas bien es permitirme hacerlo y que esta sea guardada y mostrada de manera segura sin alterar el texto original, eso es una buena práctica en el desarrollo.

Vamos, para todo esto no necesitas hacer nada manualmente, de todo eso se encargarn los frameworks, generalmente debes utilizar secuencias de escape para todo cuando no usas frameworks. Por ejemplo, en codeigniter usas active record y no necesitas usar secuencia de escape para sql, con jquery y valores dinamicos por etiquetas no necesitas escribir valores directamente en javascript asi que no necesitas escaparlos y jquery puede insertar textos ya escapados con .text().

Saludos.


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: [u]nsigned en 31 Julio 2020, 23:16
Está bien que aprendas estos detalles en PHP vanilla. Pero si vas a dedicarte al desarrollo de software de forma profesional deberías considerar aprender un framework como Laravel o CodeIgniter, la principal ventaja de usar un framework es que ellos ya implementan soluciones para sanitizar cadenas, evitar ataques como CSRF o Inyecciones SQL y ademas te dan librerías ya armadas para las cosas mas comunes como la conexión a base de datos con algún ORM, manejo de sesiones, archivos, etc... La gracias de esto es evitar tener que ocuparse de esas tareas y centrarse solo en el desarrollo y la lógica de negocio de tu aplicación.

PD: Veo que ninguno del staff se percató de mover el tema al subforo de PHP  :silbar:


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: MiguelCanellas en 1 Agosto 2020, 00:40
WHK:

Woao Gracias por toda esa información es realmente interesante todo lo que dijiste, te pasaste  ;-)

Unsigned:

Más que nada quiero programar no tanto por si encuentro trabajo de esto (por lo menos por el momento) es que quiero emprender con una aplicación que tengo rato queriéndola hacer.

Sí, investigue de ataques XSS, CSRF, Inyecciones de SQL, robo de sesiones, este otro ataque que no me acuerdo el nombre... en el que una persona puede meter ahí algo raro en las variables de la url que son los $_GET creo que era algo con header, no me acuerdo la verdad...

La subida de archivos al servidor, la cifrado de contraseñas y algunas cosillas que ya logré solventar (espero) ya hice los testeos y todo parece marchar bien...

Gracias!

¿Por qué tantas vistas el tema?  :xD


Título: Re: [Pregunta]: Alternativa a una solución de escapar comillas simples y dobles
Publicado por: WHK en 1 Agosto 2020, 01:14
Pues generalmente ese tipo de vulnerabilidades los ves con mucho mas frecuencia en desarrollos que no hacen uso de frameworks, ya que al hacer todo a mano tambien hay que preocuparse de toda la seguridad de manera manual, y en mas de una ocación se te pasará algún detalle de seguridad, por eso el uso de frameworks hace que sea menos viable un ataque efectivo de tipo inyección ya que están preparados para evitar ese tipo de cosas. Eso no quiere decir que los desarrollos que usan frameworks no sean vulnerables, pero por lo menos no a cosas tan básicas.

Si quieres hacer un desarrollo pequeño manualmente tendrás que preocuparte manualmente de los tipos de datos, filtrado de datos, prevencion de vulnerabilidades, etc, en cambio si usas un framework solo tendrás que preocuparte por la lógica y las vistas nada más, no tienes que preocuparte por la escalabilidad o en cosas básicas como en una inyección sql.

Si estás recien aprendiendo te recomiendo aprender otros lenguajes como java y usar frameworks como spring, ya que este integra mecanismos de seguridad automatizados mucho mas avanzados que php, por ejemplo, usas templates thymeleaf que escapa automaticamente los caracteres para evitar xss, el spring security te da mecanismos de seguridad contra csrf, manejo de autenticaciones, autorización a secciones, etc.