Categoría: Buenas prácticas

En estos artículos podrás leer sobre buenas prácticas de programación

  • Qué se necesita para poner online una aplicación PHP

    Qué se necesita para poner online una aplicación PHP

    Una pregunta que parece algo obvia, ¿no? Lo que se necesita para poner en línea una aplicación PHP es un hosting. No hay mucho más que decir al respecto, ¿cierto? Pues… tal vez convenga hilar un poco más fino.

    Si bien en sus inicios PHP se utilizaba exclusivamente para la creación de aplicaciones web, hoy en día abarca un abanico mucho más amplio.

    En este artículo me centraré en la infraestructura mínima necesaria para poner en línea una aplicación web desarrollada con PHP.

    Qué debe tener un servidor para hostear una aplicación PHP

    Lo primero que debemos comprender es que, para que una aplicación web esté en línea, independientemente del lenguaje en que esté desarrollada, se requiere:

    1. Que el código esté disponible en alguna computadora conectada a Internet (El Servidor)
    2. Que dicha computadora cuente con algún software capaz de recibir peticiones a través de Internet (El WebServer) instalado y funcionando
    3. Que la dirección IP de esa computadora sea conocida en forma pública (o fácilmente averiguable)

    En el caso de PHP un requisito adicional es que esté presente en el servidor un software capaz de interpretar y ejecutar el código (El intérprete).

    Existen muchas combinaciones diferentes de software que se encargan de esto, entre las más conocidas podemos encontrar:

    Incluso es posible utilizar el Internet Information Server si el sistema operativo del servidor es Windows.

    Luego será necesario configurar el servidor web de modo que ciertas peticiones sean derivadas al intérprete de php (A diferencia de otras que simplemente deben ser servidas enviando el contenido de los archivos solicitados).

    Esta configuración es diferente según el paquete de software con que se cuente.

    Qué servicios aparte del hosting se necesitan para poner online una aplicación PHP

    Usualmente, cuando se desea poner un sitio en línea, se busca que los visitantes accedan al mismo a través de una dirección sencilla de recordar (Lo que se conoce como un dominio), sin embargo, para que la computadora cliente pueda conectarse a la computadora servidor es necesario conocer su dirección IP.

    Para ello existe un servicio adicional: el DNS.

    De modo que, para que nuestro sitio esté disponible al público será necesario, además de registrar un dominio, configurar el DNS para que realice esa traducción.

    Luego, dependiendo de las necesidades específicas del sitio que queremos montar, es probable que sea necesaria la instalación de algún software de gestión de bases de datos (Como MySQL, PostGre o alguno similar).

    Respecto de la computadora que actuará como servidor, existen diferentes opciones (de diferentes costos y requisitos técnicos).

    Se puede usar una computadora personal propia, contratar espacio en un servidor compartido, comprar una computadora y dejarla en un proveedor que garantice la alimentación y conectividad, usar un servidor virtual… en fin, las opciones son muchas.

    ¿Te cuesta decidir? Este post puede ayudarte.

  • Docker o VM ¿Cuál es mejor para PHP?

    Estás montando tu entorno de trabajo local para trabajar en un proyecto PHP.

    Hay muchas cosas por definir pero una es segura: no vas a usar XAMPP ni nada parecido… después del último fiasco fue suficiente, hay que virtualizar sí o sí.

    Y la pregunta es: ¿voy con Docker o con una VM?

    Creeme que te entiendo, estuve mucho tiempo en tus zapatos.

    Hoy por hoy mi elección es clara: Docker. Pero no te pido que me creas así sin más, dejame darte una breve explicación para que saques tu conclusión.

    En qué se parecen y en qué se diferencian Docker y las Máquinas Virtuales

    Docker es un sistema de administración de contenedores. Sin entrar en mucho detalle, diré que es un método para crear y administrar entornos de ejecución aislados del resto.

    Las máquinas virtuales son sistemas de simulación de hardware.

    ¿Entonces…?

    Las máquinas virtuales son, en cierta medida, más poderosas ya que permiten crear un entorno de computación «completamente» separado del host, donde puede instalarse, por ejemplo, un sistema operativo diferente de aquel del host.

    Docker (o algún otro sistema de contenedores) en cambio no virtualiza hardware, si no software. Esto significa que sus posibilidades son algo más limitadas (Por ejemplo, montar un contenedor Linux en un host Windows es algo que, en principio no es posible).

    Hasta aquí la balanza parece inclinarse hacia las VMs, ¿no? Entonces… ¿por qué deberías preferir Docker?

    Los contenedores Docker son mucho más livianos que las VMs. Esto implica que:

    • Se inician/frenan mucho más rápido
    • Ocupan mucho menos espacio en el disco
    • Consumen muchos menos recursos del host

    Todo esto hace que sea mucho más viable tener un gran número de contenedores Docker ejecutando en un mismo host, a diferencia de lo que ocurre con las máquinas virtuales.

    Dejando estos detalles de implementación de lado, en la práctica las diferencias son mínimas. Cambia un poco la forma de configurar el entorno pero ambos se prestan muy bien para la automatización.

    Tanto Docker como los sistemas de virtualización cuentan con interfaces de línea de comandos muy potentes y, sobre esas herramientas básicas se montan algunas más avanzadas (Vagrant para el caso de VMs y docker-compose para Docker) o incluso algunas con interface gráfica, lo cual facilita mucho su uso.

    De modo que, siendo que el costo de implementar una o la otra es prácticamente igual, ¿por qué ir con la que más recursos consume?

    Por supuesto que la realidad es más compleja, hay que analizar el caso por caso pero, en líneas generales, mi recomendación es ir con Docker.

    Cómo arrancar con Docker

    Bueno, este tema excede un poco el objetivo de este post, pero voy a intentar hacer un breve resúmen y dejarte algunas referencias que puedan ayudarte:

    1. Instalar Docker
    2. Buscar una imagen que puedas usar como prueba
    3. Crear un contenedor
    4. Correr el «Hola Mundo!» 🙂

    Esto es una visión muy reducida. Si querés más detalles te invito a leer este post.

    Y si ya diste tus primeros pasos pero tenés dudas, te recomiendo mirar la Guía Práctica de Dockerización de PHP.

  • Validaciones… ¿lado cliente o lado servidor?

    Validaciones… ¿lado cliente o lado servidor?

    Nadie duda de que los campos de los formularios que envían los usuarios deben ser validados.

    Seguro eso es lo que te dijeron cuando empezaste a estudiar, lo que no es muy claro cuando se trata de programación web es cuál es la manera correcta de hacerlo.

    En otras palabras, ¿cuáles son las mejores prácticas cuando se trata de validar?

    Más allá de las herramientas que vayas a usar para realizar la validación, lo primero que debes responder es dónde debe realizarse esa validación, ¿en el cliente o en el servidor?

    La respuesta corta primero: Idealmente las dos, y si sólo puedo elegir una, definitivamente del lado servidor.

    ¿Querés más detalles? Te invito a acompañarme a la respuesta larga 🙂

    Respuesta larga:

    ¿Por qué es más importante la validación del lado servidor que del lado cliente?

    Sencillamente porque tenés mucho más control sobre lo que sucede.

    En una aplicación de escritorio (o una que no sea de tipo cliente-servidor) no existe este problema: la aplicación es una sola con lo cual, lo que el front-end captura puede ser considerado confiable y volver a realizar la validación en el backend resultaría redundante.

    Cuando hablamos de una aplicación web, en realidad estamos hablando de dos aplicaciones independientes. Compartir en X

    Pensá un momento en cómo es el modelo de ejecución de una aplicación web:

    1. El cliente realiza un pedido
    2. El servidor responde con HTML, JavaScript, CSS, etc…
    3. El cliente dibuja la página
    4. El usuario completa los datos
    5. El cliente realiza un nuevo pedido enviando los datos ingresados
    6. El servidor los procesa y eventualmente almacena
    7. Vuelta al paso 2

    Desde el punto de vista del servidor, el pedido que se le realiza puede haber sido generado usando el HTML que él mismo ha enviado o no… imposible saberlo.

    De modo que, en definitiva, los datos recibidos no pueden ser considerados confiables.

    Podés ver cómo «fabricar» un pedido cualquiera usando una herramienta como cURL.

    Tomemos un sitio cualquiera como http://www.recruitersonline.com/members/ron4_add.php:

    Si vemos el código fuente:

    Podemos notar rápidamente que los datos que se introduzcan en este formulario serán enviados a ron4_add_thanks.php.

    Valiéndonos de cURL podemos armar un pedido como:

    Esto haría que el servidor reciba XXXX como valor del campo adm_first_name.

    Suponiendo que tal valor no sea aceptable y que la validación sólo se realizara a través de JavaScript… habríamos logrado saltearnos esta validación simplemente usando un cliente diferente.

    De hecho, en este tipo de problemas se basan los ataques tales como sql injection.

    Pero entonces…

    ¿Vale la pena hacer validaciones del lado cliente?

    ¡Claro que SI!.

    Las validaciones del lado del cliente son un favor que le hacemos a los usuarios bien intencionados que simplemente han cometido un error al ingresar información de buena fé.

    El favor consiste en ahorrarles el round-trip al servidor con información que sabemos de antemano que será rechazada.

    Es cierto que hoy en día el tiempo de ida y vuelta se ha reducido en forma significativa, sin embargo, aún hay escenarios en los que puede hacer una diferencia (Por ejemplo en el caso de aplicaciones móviles donde la red es inestable o peor, se consumen datos del plan).

    La validación del lado servidor es una necesidad mientras que la validación del lado cliente es una comodidad. Compartir en X
  • Cuál es el modo más seguro de tratar con passwords en PHP

    Es bastante común últimamente recibir noticias de que algún sitio de gran popularidad ha sido hackeado (O, como suele comunicarse, «su seguridad se ha visto comprometida»).

    Dependiendo del tipo de sitio del que se trate el problema puede preocuparnos más o menos.

    Claro que eso es cuando somos meramente usuarios del sitio… ¿qué pasa cuándo se trata de un sitio que está bajo nuestra responsabilidad?

    Aclaremos algo antes de seguir: es imposible hacer un sitio 100% libre de vulnerabilidades.

    Si hay gente decidida a romper nuestra seguridad lo van a lograr (Si tienen la capacidad técnica y/o el teléfono de alguien que la tenga).

    Es por eso que es muy importante, no sólo poner trabas a los atacantes si no también dejar un botín poco atractivo para el caso de que lo consigan.

    Algo bastante común es que la gente reutilice sus contraseñas en diferentes sitios, con lo cual, el acceso a las contraseñas de un sitio puede permitir a los atacantes hacerse «gratuitamente» con el acceso a otros…

    Nuevamente, no vamos a poder evitar que se ponga en juego la integridad de los datos que nuestros usuarios dejan en otros sitios, pero al menos podremos decir que no lo han logrado por nuestra bajada de guardia.

    Cómo proteger la información sensible

    La única medida real con la que contamos hoy en día es la encripción de los datos sensibles (Como ser las contraseñas).

    Hasta hace un tiempo se utilizaba mucho la función MD5 para transformar una clave legible humanamente en un texto indescifrable. Por ejemplo el MD5 de ‘Hola mundo!’ es ‘d501194c987486789bb01b50dc1a0adb’.

    Lo que se hacía entonces era calcular el md5 del texto ingresado como contraseña y eso era lo que se almacenaba en la base de datos (y cuando se intentaba un login se volvía a calcular el md5 con lo que se tenía guardado, de modo que la verdadera contraseña no estaba en la base).

    Desafortunadamente, todo avanza rápido en la informática y estas funciones (md5 y sha1) ya no son suficientemente seguras (Las computadoras de hoy son tan rápidas que se ha vuelto un problema menor romper este tipo de encripción).

    ¡Pero no todo está perdido! 🙂

    Más allá de md5 y sha1

    Desde la versión 5.5 de PHP nos encontramos con buenas librerías de criptografía internas. Dos funciones interesantes son password_hash y password_verify.

    Con la primera se obtiene un hash a partir de un texto plano (lo ingresado por el usuario).

    Con la segunda se verifica que un texto plano corresponda con un hash.

    A muy alto nivel lo que logra es lo mismo que antes, sólo que mucho más seguro (Los algoritmos usados por password_hash son más fuertes).

    Pero en realidad es bastante más lo que se logra… Al levantar el nivel de abstracción (usamos una función de hashing que internamente puede usar diversas estrategias para lograr su objetivo) logramos también independizarnos de la implementación particular.

    ¿Qué significa esto? Simplemente que si en un futuro el algoritmo de encripción usado cambia (Por ejemplo porque se encuentra uno mejor), nuestro código no se verá afectado.

    Y ahora, ¿qué pensás hacer con las passwords de tus sitios?

  • Dónde almacenar la configuración de una aplicación PHP de forma segura

    Dónde almacenar la configuración de una aplicación PHP de forma segura

    Una pregunta que me llegó de un amigo que viene del mundo .Net (Que parece ser un poco más organizado o estandarizado que el nuestro :).

    Lo primero que deberíamos preguntarnos es de qué nos estamos queriendo proteger.

    Por lo general, la posibilidad de que alguien externo a nuestra organización tenga acceso a la configuración de nuestra aplicación no parece muy tentadora… ¿por qué? Básicamente porque puede haber información sensible (Como ser contraseñas, nombres de hosts donde están las bases de datos, etc…) que podrían dar a un atacante una ventaja importante si decidiera hacernos un daño.

    Una línea de defensa que tenemos es guardar estos archivos en un directorio que no sea públicamente accesible.

    Si usás el webserver Apache, conocerás seguramente la directiva DocumentRoot: lo que está «a la vista» de los visitantes es exclusivamente lo que está dentro de ese directorio (O subdirectorios, según cómo esté configurado el servidor), pero (y esta es la parte interesante), no es lo único que está a la vista para un script php.

    Ejemplo:

    <VirtualHost *:80>
     ServerName my.domain.com
     ServerAdmin webmaster@localhost
     DocumentRoot /usr/share/apache2/mysite
    
     <Directory /usr/share/apache2/mysite>
      Options FollowSymLinks
      AllowOverride All
     </Directory>
    </VirtualHost>

    Con esta configuración, cuando yo ingrese a la URL http://my.domain.com/index.php, el servidor me dará el HTML generado por la ejecución del archivo /usr/share/apache2/mysite/index.php.

    Imaginemos que index.php tiene algo como esto:

    <?php 
    
    require_once '../config.php';
    echo 'Hola Mundo!';

    Si yo intentara entrar (desde mi browser) al archivo config.php debería escribir algo como http://my.domain.com/../config.php (Eso obviamente, sabiendo que ahí se encuentra el archivo que busco).

    Si bien podría llegar a pasar que el webserver esté mal configurado y permita hacer eso, en la gran mayoría de los casos, eso simplemente será imposible (Los requests están confinados a leer archivos que están dentro del DocumentRoot).

    Si estás usando un framework estándar (Symfony, CakePHP, Laravel, etc…), esto ya estará previsto (Habrá un directorio especial para almacenar los archivos de configuración, pero siempre en última instancia se va a tratar de un tema de permisos configurados a nivel de webserver).

    ¿Conocés alguna otra forma de proteger tus archivos de configuración? ¡Compartila en los comentarios!