Tag Archive: web


Ha pasado algo más de un año desde la última entrada, pero hemos vuelto con las pilas recargadas. A ver lo que me dura esta vez.
En el último post hablé sobre la seguridad en Symfony y lo desastroso que puede ser una mala configuración. Recordemos que si dejabamos expuesto la carpeta app de un proyecto en Symfony2, podiamos dejar accesible el fichero parameters.yml dejando expuesta las credenciales de la base de datos. Dejar  esto en un servidor con el proyecto accesible desde internet, es invitar a que los malvados nos hagan maldades.

A fecha de hoy, y buscando un poco en Google con el siguiente dork: inurl:app/config/parameters.yml te puedes encontrar varios proyectos con este fichero abierto para todos los públicos.
Y en algunos, no solo te encuentras las credenciales de la base de datos, sino también el usuario y contraseña de una cuenta de correo, (de gmail por ejemplo) si tienen configurado el mailer.

parameters.yml real

Ejemplo de un parameters.yml filtrado

Viendo esto, vamos a repasar las medidas de seguridad para evitar esta fuga de información:

  1. Lo más importante, intenta no dejar publicada la carpeta app. Es el fallo más grande.
  2. Si no queda otro remedio, asegurate que los ficheros .htaccess que vienen con la carpeta estén funcionando, puede que tengamos configurado apache para que no nos deje sobreescribir las directicas de seguridad necesarias.
  3. A lo mejor sería interesante incluir alguna directiva que denegara el acceso a través de web de los ficheros .yml.
  4. Si tenemos el proyecto en un repositorio git, es importantisimo poner en el .gitignore el parameters.yml. Mejor configurarlo 30 veces en producción que tener una sola fuga de información

Con todo esto en cuenta, se nos puede dar la situación de que no quede más remedio que publicar la carpeta app accidentalmente. Pero si hemos seguido los anterioes consejos,
no deberiamos de tener tantos problemas ya que hemos protegido los ficheros yml. Pero creernos que estamos a salvo sería un error. En Symfony2 tenemos la carpeta app/cache
en la que se almacenan los compilados de las plantillas y otros recursos del proyecto. Esta carpeta no suele estar protegida por ningún .htacces, de forma que sus documentos serían accesibles.
Dentro de ella encontramos el fichero appProdDebugProjectContainer.xml donde encontraremos lo mismo que hay en parameters.yml, pero no solo eso, también información jugosa como los bundles que se utilizan en el proyecto, que rutas están protegidas y mediante que roles,etc.

appDevDebugProjectContainer.xml

Fichero appDevDebugProjectContainer.xml publicado

De modo que hay que asegurarse de proteger también esta carpeta.

Conclusión, NO dejeis publicado el directorio app. Os ahorrareis muchos dolores de cabeza. Y tened cuidado con las carpetas que dejais accesible al público, sean del framework que sean.

Hoy, he visto este post “Fuga de información en Symfony al chequear requisitos” y me he preocupado al instante, ya que trabajo con este framework y tengo varios proyectos con él. Así que tras realizar un breve análisis de lo que explica en el post, he llegado a la conclusión que esas fugas son producidas por una mala configuración al subirlo al servidor web. Voy a explicar un poco mejor la organización de carpetas y los posibles fallos de configuración que podrían crear este error.

Estructura de carpetas en symfony

Estructura de carpetas en symfony

La imagen anterior muestra la estructura básica de un proyecto en Symfony2. Nos vamos a centrar en dos carpetas. La carpeta web es la parte pública del proyecto, donde tenemos el controlador principal (punto de entrada de todas las peticiones) y todos los recursos estátitcos que utilizarán nuestras páginas (imágenes, css, javascript, etc). Por otra parte, tenemos la carpeta app ,donde se guarda toda la configuración de nuestro proyecto y el archivo check.php. Según la filosofía de seguridad de Symfony la carpeta app NUNCA debería de ser accesible a través del servidor web, si eso ocurriera, sería desastroso ya que ahí tenemos contraseñas en texto plano, logs, etc. Así que cuando publiquemos un proyecto, siempre debermos dejar visible SOLO la carpeta web, para evitar problemas.  Si por desgracia hay que publicar la carpeta principal del proyecto, en principio no habría problema ya que por defecto todos los directorios críticos vienen protegidos mediante un archivo .htaccess con el siguiente contenido:


<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>

Por lo que es importante que nuestro apache permita sobreescribir estas directivas. Por que si no, tendríamos un problema mucho mayor que acceder al fichero check.php.

Fuga de Parameters.yml

Un ejemplo de lo que puede ocurrir con una mala configuración de Apache

Visto todo esto, he caido de que hay otro punto de fuga de información importante. Dentro del directorio web, tenemos el archivo app.php que es el controlador principal, el punto de entrada de todas las peticiones. También tenemos el fichero app_dev.php, también controlador principal pero que nos permite utilizar el entorno de desarrollo. Este entorno nos suele dar varias ventajas cuando estamos desarrollando y depurando un proyecto, una de ellas es la barra de “profiler” que nos permite hacer un seguimiendo de muchisima información.

El profiler en accion

El profiler en accion

Si se accede a esta información en producción, podrian obtener todas las rutas de nuestro proyecto, acceso al phpinfo, las consultas sql que utilicen nuestras páginas, bundles usados por el proyecto y la versión de symfony. Supongo que me dejaré alguna cosa en el tintero, pero cómo veis no es moco de pavo. Así que es importante no subir este fichero a los servidores de producción o modificarlos para incluir alguna restricción. Por defecto, incluyen este pedazo de código:


if (isset($_SERVER['HTTP_CLIENT_IP'])
|| isset($_SERVER['HTTP_X_FORWARDED_FOR'])
|| !in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1'))
) {
header('HTTP/1.0 403 Forbidden');
exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}

Que en principio, parece que nos protege. Pero según creo, de esto por ahora sólo son conjeturas, si nuestro servidor está detrás de un proxy, permite saltarse la restricción debido a que una de las condiciones (isset($_SERVER[‘HTTP_X_FORWARED_FOR’))  permite bypasearlo. Por lo que habría que editarlo.

Cómo recomendación final, es importante revisar todos estos puntos cuando tengamos el proyecto en producción para evitar dar demasiadas pistas a posibles atacantes y ahorrarno un disgusto en el futuro.

A estas alturas del partido, podemos encontrar por la red numerosos artículos y opiniones contándonos las bondades de utilizar control de versiones, especialmente Git. Así que he decidido aportar mi granito de arena dando mi opinión de porqué hay que utilizar este fabuloso sistema de control de versiones. Voy a resumirlo en 10 puntos, que creo que cubre  la mayoría de ventajas, por supuesto no son todas, pero en mi opinión creo que sí las más importantes.

  1. Nos proporciona organización: esto es común a cualquier sistema de control de versiones, eso de tener 30 carpetas para diferenciar las versiones sólo nos suele traer dolores de cabeza, pérdida de tiempo y problemas a la hora de entregar un trabajo o ponerlo en producción.
  2. Podemos probar nuestro código de forma más ordenada sin necesidad de crear copias de los ficheros o el proyecto. Codeamos, probamos, que funciona, bien, que no funciona, hacemos un revert y no ha pasado nada.
  3. Nuestro código estará más limpio, ya que con Git no es necesario ir comentando código “por si luego lo uso”. Esto, aparte de ser una mala práctica, luego nos costará más mantener el código, mientras con git siempre podremos ver las versiones antiguas de nuestros archivos y rescatar código eliminado.
  4. Más sencillo controlar los cambios, proyectos y ver el historia. Si instalamos un visor web en nuestro servidor de repositorios, cómo GitLab, o utilizamos GitHub, podremos ver todos nuestros proyectos y navegar de forma sencilla por todas las versiones, ramas, etc.
  5. Las puestas en producción son más sencillas y rápidas, sobre todo hablando de entornos web. Hay gente que todavía utiliza el FTP cómo medio de subir los proyectos, y muchas veces sin comprimir, tardando bastante en subir un proyecto. Aparte de que si has cambiados varios ficheros y se te olvida subir alguno, puedes ocasionar errores en el funcionamiento de la aplicación. Con Git, basta con hacer un pull del proyecto para que suba los cambios casi de forma instantánea y sin dolores de cabeza.
  6. Sirve cómo sistema de copia de seguridad, siempre que lo tengamos en un servidor. Git trabaja de forma no destructiva, así que salvo que utilicemos uno o dos comandos especiales. Nuestra información siempre estará ahí. También donde tengamos un repositorio (servidor y diferentes máquinas), tendremos la historia completa del repositorio. Hay quien piensa que guardandolo en Dropbox o similares tenemos una copia de seguridad. Pero cómo accidentalmente borremos el proyecto de la carpeta, se borarrá entodos los equipos sincronizados. Esto me ha pasado y no fué agradable.
  7. Nos permite fiscalizar mejor nuestro trabajo. Hay veces que necesitamos un historial de los cambios de una aplicación para facturarlos o por otras necesidades. Esto, normalmente conlleva un tiempo buscando correos y papeles con las especificaciones o a veces ni eso ya que las peticiones se hicieron telefónicamente. Si usamos Git podremos ver de un vistazo todos los cambios y cuando se hicieron. Si a esto le añadimos una buena metodología en los mensajes de los commits, aparte del cuándo, podremos saber el qué se cambió.
  8. Compartir nuestro código, Git es ideal para hacer trabajo colaborativo, permitiendo desarrollos en paralelos y si utilizamos GitHub, podemos publicar nuestro código para que la comunidad lo aproveche y nos ayude a mejorarlo.
  9. Trabaja desde cualquier sitio, teniendo un servidor de Git (propio o GitHub) es tremendamente sencillo poder descargarte una versión de tu proyecto en cualquier sitio y trabajar fuera de tu ámbito normal. Esto viene genial para arreglar errores críticos que te pillen fuera de la oficina o por si pierdes o rompes tu equipo.
  10. Estaréis mejor visto laboralmente, actualmente en la gran mayoría de las ofertas de trabajo de programador, están pidiendo que se sepa utilizar un sistema de control de versiones, especialmente Git. Así que dedicándole un par de mañanas, podréis añadir a vuestro curriculum una nueva habilidad que os facilitará encontrar un empleo.

Espero haberos convencido, a aquellos que aún no lo utilicen, para probar este sistema y ver cómo vuestra calidad de vida de programadores.

Después de mucho sin actualizar, ya iba tocando.

Llevo algo más de un mes dandole duro a Symfony 2 otra vez. Esta vez con la versión 2.1, y estoy descubriendo un nuevo mundo utilizando composer para gestionar las dependencias.

Todo aquél que haya comenzado a utilizarlo, sabrá que el repositorio oficial de composer es https://packagist.org/, y aunque tiene un buscador muy bueno, no proporciona suficiente información acerca de los bundles que puedes encontrar. Aparte, de que no es un repositorio exclusivo de bundles de Symfony 2, aunque es lo que más hay.

Así que buscando esta mañana un Bundle para retocar imágenes, he dado con la página http://knpbundles.com/ , que contiene una gran cantidad de bundles (2003 actualmente). Nos da bastante información acerca de cada uno, así como el nombre y enlace para pacakgist (e incluirlo directamente en el composer.json) y la dirección en github. Desde luego , es lo suficientemente interesante cómo para dedicarle unos minutos de nuestro tiempo.

Para nosotros los programadores, hay una cosa que puede resultar algo complejo: Crearse un portfolio. Para los artistas y diseñadores, es suficiente con crearse una página simple y unas cuantas capturas de sus trabajos. Pero para un programador, es más complejo, si has hecho una aplicación web accesible al público, puedes poner el enlace. Pero, ¿Y si solo has creado un módulo de una aplicación? ¿ Y sí has colaborado en un proyecto con una pequeña parte? ¿Y si quieres enseñar una aplicación de la universidad?. Incluso a veces, a  un posible contratador, le puede interesar más ver la calidad de nuestro código. Para este tipo de casos, tenemos una opción, que además nos permite recibir feedback de otros usuarios. Para que nos entendamos, una red social de desarrolladores.

Estoy hablando de Github, que aparte de todo esto, nos proporciona un control de versiones, que debería de ser algo obligado para todos nuestros proyectos.
A pesar de sus bondades, tiene una cosa muy buena y una cosa muy mala. La cosa muy buena esque te puedes crear una cuenta gratis, la mala cosa, esque los proyectos que subamos han de ser públicos, salvo que nos hagamos una cuenta de pago. En este último caso, el número de proyectos privados dependerá de la cantidad que paguemos. Aún así, sigue siendo una opción bastante interesante, sobre todo si tenemos algún proyecto interesante en mente, ya que nos abrimos a colaborar con más desarrolladores y eso siempre es bueno.

Os dejo una lista con los enlaces para configurar git de forma sencilla :

Me he decidido a comenzar a explorar Ruby on Rails. La verdad que parece una solución MVC bastante potente, ya que entre todas sus ventajas, ofrece una interfaz REST que viene bastante bien para proporcionar servicios a consumir por otras aplicaciones.

La instalación en Ubuntu es bien sencilla siguiendo los pasos de la Wiki oficial.

Una vez hecho estos pasos, podemos seguir los pasos del primer ejemplo de un blog que viene en el Get Started

Aunque me he encontrado con un problema siguiendo los pasos, al intentar crear la base de datos. El problema era que aunque había cambiado el fichero de configuración de base de datos para utilizar mysql, me seguía diciendo que faltaba la gema de sqlite3, concretamente:

Could not find sqlite3-ruby-1.3.2 in any of the sources
Try running `bundle install`.

Así que tenemos dos soluciones:
La primera y menos limpia, es la de instalar la gema y dejarla ahí aunque no la utilicemos.

La segunda, es editar el fichero Gemfile, donde se indican las dependencias y comentamos la línea de sqlite y añadimos la de mysql:

#gem 'sqlite3-ruby', :require => 'sqlite3'
gem 'mysql'

De esta forma, tambien nos evitamos el error uninitialized constant Mysql

Bueno, después de unas cuantas semanas sin postear, volvemos con las pilas recargadas. Vamos a empezar con un pequeño tutorial, para introducir informes creados con Jasper Reports en nuestras aplicaciones webs usando el framework Struts 2.

Para este tutorial, vamos a presuponer que se saben crear informes con jasper report (mejor, si utilizamos la herramienta iReport) y que tenemos ya montada una aplicación con Struts 2.

Lo primero que tenemos que hacer, es importar tantos las librerías de Jasper repots como el plugin para struts 2. El jar del pluggin lo podreís encontrar, con las librerias de struts 2, se llama struts2-jasperreports-plugin-2.1.x.jar , como veis, es muy facil identificarla.  Para ver que librerias necesitais de jasper report, podeis remitiros a la documentación oficial.

Una vez importadas las librerias, lo siguiente, sería abrir nuestro fichero de configuración struts.xml y hacer que el package en el que está la acción que nos mostrará el report, incluya el soporte para interpretar los informes:


<package name="default" namespace="/" extends="struts-default,json-default,jasperreports-default">

 <action name="Certificados">
 <result name="success" type="jasper">
 <param name="location">informes/report3.jasper</param>
 <param name="dataSource">resultados</param>
 <param name="format">PDF</param>
 <param name="reportParameters">params</param>
 </result>

 <result name="informe2" type="jasper">
 <param name="location">informes/peticion_justificacion.jasper</param>
 <param name="connection">conexion</param>
 <param name="format">PDF</param>
 <param name="reportParameters">params</param>
 </result>
 </action>
 </package>

Como podemos ver, el paquete, extiende la clase jasperreports-default , con lo que las acciones podrán devolver resultados del tipo jasper, para poder imprimir nuestros informes.  Después de eso, podeis ver dos acciones, y es de notar que el tipo es  jasper, con lo cual, ya se entiende, que es un informe.  Las acciones,  tienen que llevar los siguientes parámetros de forma obligatoria:

  • location: es la localización del informe compilado que queremos que se ejecute como resultado.
  • datasource : podemos especificar el nombre de una propiedade de la acción, que deberá devolver una colección de beans, de la cual queremos extraer las propiedades.
  • connection: pondremos el nombre de una propiedade de la acción que devuelva una conexión a la base de datos, que usará el report para conectarse y ejecutar la sentencia que lleve este implicita.

Entre datasource y connection, solo hace falta especificar una de las dos. En el código de ejemplo, hay dos parámetros más:

  • format: Será el formato de salida del informe, podrá ser PDF o cualquier otro que permita Jasper Report, (ver la documentación oficial)
  • reportParameters: Será un mapa, con una lista de parámetros que se utilizará dentro del report, por ejemplo para parametrizar la consulta del report.

Ahora solo nos queda ver, el código de una acción, que como veremos a continuación, puede llegar a ser muy simple:


public class CertificadosAction extends ActionSupport implements ApplicationAware{
private Collection resultados;
private Map<String,Object> app;
private Map<String,Object> params;

@Override
public String execute(){
ProxyBD proxy = (ProxyBD)app.get("db"); // Un objeto que envuelve la conexión
resultados = proxy.getDatos();
params = new HashMap<String,Object>();

params.put("param1","dato 1");
params.put("fecha",new Date());

return SUCCESS;
}

public Connection getConexion(){
ProxyBD proxy = (ProxyBD)app.get("db");
return  proxy.getConnection();
}

public Map getParams(){
return params;
}
public Collection getResultados(){
return resultados;
}

public void setApplication(Map<String, Object> arg0) {
app = arg0;
}
}

Como se puede ver, para un informe sencillo, el código de la acción es realmente reducido, incluso para informes más complejos, no es necesario complicar mucho más la acción. Se puede ver, que tiene varios atributos,  uno los resultados, que sería el datasource para el informe, otro son los parámetros adicionales que se desean enviar al report y por último, la conexión, de forma que esta misma acción, se puede reutilizar para diferentes report, dependiendo del resultado de la acción.

De momento, esto es todo por ahora,  en próximas entregas veremos como tratar con subreports sin perder la cabeza y algún que otro truquillo más.

Enlaces: