Category: Frameworks


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.

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.

Desde hace unos meses que comencé a enredar con Icefaces 3, me topé con un problema al utilizar uno de los componentes más potentes para formularios. Se trata del componente  ace:dateTimeEntry,  para tener una bonita presentación a la hora de introducir fechas y horas en los formularios. El componente, dispone de dos formatos de presentación, el primero establece el calendario en bruto en la página y el segundo, y más útil, nos muestra un campo de texto que al recibir el foco, muestra un popup con el calendario para introducir la fecha. Un ejemplo de uso de esta esta segunda forma de renderización es la siguiente:

<ace:dateTimeEntry id="cal"
value="#{bean.persona.fechaNacimiento}"
timeZone="Canada/Mountain"
pattern="dd/MM/yyyy"
navigator="true"
yearRange="1940:1980"
renderAsPopup="true"/>

Con el atributo renderAsPopup , conseguimos que se renderice como un popup. Para el resto de opciones, aunque se explican por sí solas, podeis ver cómo funcionan en el showcase de icefaces. Una vez presentado el componente, vamos a ver el problema que me surgía y hasta la semana pasada no he conseguido dar con el origen. Cuando renderizaba el componente de esta forma,  el popup se mostraba, pero al realizar una navegación y volver al formulario, el popup con el calendario dejaba de mostrarse.  Después de mucho darle vueltas al porqué y preguntar en el foro de icesoft(sin mucho éxito), conseguí dar con el problema. Lo primero que hay que tener en cuenta, esque en Icefaces trabaja completamente con Ajax, con lo cual, cuando realizamos una actualización de sección, solo refresca la partede la página que ha cambiado. Para ello, el servidor envia como respuesta un XML con los cambios que ha habido. Entonces, en algunas páginas, esta respuesta, hacía cambiar el body entero, con una respuesta parecida a esta:

<div><partial-response></div>
<div><changes></div>
<update id="javax.faces.ViewBody"><body title=""><div id="header">...

En el momento que aparece <update id=”javax.faces.ViewBody”>, se nos fastidia el popup de dateTimeEntry, debería de aparecer un id de los que hayamos puesto nosotros. Tras revisar y revisar el código, el fallo está en algo bastante tonto, pero no trivial. Resulta que en las plantillas, para organizar las secciones de cada página, lo tenía dividido utilizando divs y algún que otro table, sin asignarle un id.  Y JSF, para detectar los cambios que hay en el DOM cuando cambiamos de navegación, utiliza los id para localizar que parte tiene que sustituir, así que asignandole un id, debería bastar, pero aún así, se dan comportamientos extraños. Por lo que lo mejor, es utilizar las etiquetas propias de JSF para organizar el código, que luego se sustituira en el cliente por un div.

De forma que para arreglar este error y evitar otros posibles funcionamientos erráticos, habría que sustituir (si tenemos algo parecido) esto:


<div id="content">

<ui:insert name="content"></ui:insert>

</div>

&nbsp;

&nbsp;

Por esto otro:


<h:panelGroup layout="block" id="content">

<ui:insert name="content"></ui:insert>

</h:panelGroup>

Y siempre, siempre, siempre, asignarle un id a los panelGroup, para que JSF encuentre correctamente donde tiene que sustituir al hacer cambios en el DOM.

Hace ya algún tiempo que descubrí Unity3D, un motor de juegos que es bastante potente y sencillo de manejar comparado con otros de los disponibles. Además, cuenta con una versión gratuita con la que poder trabajar, así que para desarrollar juegos Indies, viene perfecto. Estos días he estado trasteandolo un poco  y he de decir que es una maravilla trabajar con él,  ya que su sencilles viene acompañada de una buena documentación y algunos tutoriales muy interesantes, en especial el de como hacer un juego de plataforma 2D con las 3D. Tras completarlo, y avanzarlo un poco más, puedo decir que se pueden hacer grandisimas cosas con él, aparte también se pueden crear juegos para Iphone y Android, aunque para eso ya hay que pagar.
Como dato interesante, el Sonic Fan Remix está hecho con este motor, así que podeis ver algo de su potencia en directo y lo que se puede conseguir con este motor y muchísimo amor.

Tras unos días jugueteando con OpenXava, he visto las posibilidades que tiene, para crear aplicaciones muy rapidamente. Así que he decidido compartir unos pequeños tips, para crear configurar un entorno que nos permita empezar a crear rápidamente aplicaciones.

Paso 1: Descargar OpenXava

El primer paso y más obvio, es descargar OpenXava, actualmente en su versión 4m2. Podeis hacerlo directamente desde su página o pulsando en el enlace que os ofrezco.

Paso 2: Descargar Eclipse

Bueno, este paso no siempre es necesario si ya teneis un Eclipse descargado, solo aseguraos de que es la versión con soporte para JEE, para poder tener las vistas y librerías necesarias. Podeis descargarlos Aqui

Paso 3: Leeros la documentación oficial

Antes de seguir paso a paso, recomiendo que leais la guía de referencia que viene en la wiki de OpenXava, sobre como crear el primer proyecto. Aunque los pasos que daremos aqui, serán algo diferentes.

Paso 4: Pasar a un workspace más quirurgico.

Si seguimos los pasos de la guía de referencia, esta nos indica que cambiemos el workspace al que viene dentro de la carpeta que descargamos, pero esto no siempre es deseable, ya sea por prefrencias personales, para mantener un orden, o porque después realmente, los ejemplos de openxava no nos interesa tenerlos por ahi pululando.
Así que vamos a personalizar nuestro entorno para empezar a crear aplicaciones OpenXava.

Del arbol de directorios de la carpeta de OpenXava que nos descargamos, dentro del workspace que viene, solo son necesarias dos carpetas de proyectos, que son la de OpenXava y OpenXavaPlantilla.
OpenXava es el proyecto base, sobre el que se apoyaran todas nuestras aplicaciones, y OpenXavaPlantilla, como su nombre indica, es la plantilla para crear nuevos proyectos.
Lo que tenemos que hacer, es copiar esas dos carpetas al workspace que queramos, ya sea el que utilizamos habitualmente, o en uno nuevo y vacio, para dedicarlo solo a las aplicaciones que desarrollemos con este framework.

Una vez tenemos esto, solo tenemos que arrancar Eclipse, y señalar a este nuevo workspace creado.  En caso de que no reconozca los dos proyectos, tendremos que crear un nuevo proyecto desde los directorios copiados.
File > New > Project… > Java Project
Y marcamos la opción de Create Project from existing source, y buscamos la carpeta, le asignamos un nombre al proyecto, preferiblemente el mismo que la carpeta contenedora (vamos, OpenXava y OpenXavaPlantilla)
Con esto, ya tenemos nuestro entorno listo.

Paso 5: Asociar el servidor tomcat a Eclipse

El último paso para tener nuestro entorno listo, es asociar el servidor tomcat a eclipse. Haciendo esto, nos ahorramos tener que estar lanzando los scripts para lanzar/parar el servidor, ya que podemos hacerlo directamente desde Eclipse, y también podremos utilizar el depurador. Lo primero, es poner la carpeta de Tomcat que viene con OpenXava en un lugar que nos resulte apropiado, eso a conveniencia de cada uno.  Ahora solo nos queda asociar el servidor, para ello abrimos la pestaña de servidores ( Window > Show view > Others… > Servers), dentro de la pestañita, pulsamos con el botón derecho y New > Server , ahora seleccionamos Apache Tomcat 6.0 y le damos a siguiente, nos pedirá configurar un RuntimeTime Enviorment para ese server, así que le indicamos un nombre y buscamos la carpeta del tomcat que copiamos, y le damos a finalizar.

Con estos pasos, ya tenemos nuestro entorno listo para crear una nueva aplicación con OpenXava y poder ejecutarla en nuestro servidor. Próximamente, publicaré como crear la primera aplicación OpenXava utilizando MySQL como gestor de base de datos.

Enlaces:

Buscando en la red herramientas de desarrollo rápido, para que nos endendamos, un tipo de herramienta que nos genere código y nos ayude a crear aplicaciones lo más rápido posible. Según la wikipedia, netbeans sería una herramienta de desarrollo rápido, y la verdad que este famoso IDE nos ayuda muchisimo a crear aplicaciones con unos pocos clicks y unas cuantas lineas de código que escribamos nosotros.

La herramienta que he encontrado, se llama OpenXava y nos permite crear aplicaciones web de gestión en escasos minutos. Nos podemos olvidar de tener que generar las tablas para la base dedatos, así como todo el tema de inserción modificación y eliminación de la base de datos. OpenXava se encarga de estas gestiones mediante JPA, aparte, también nos crea la parte de vista y controlador. Practicamente nos hace todo el trabajo, nosotros solo tenemos que escribir unas clases POJO y añadirles unas anotaciones para la persistencia, y en pocos segundos, obtendremos una aplicación funcional, ahorrandonos muchas horas y muchos quebraderos de cabeza.

Os recomiendo que le echeis un vistazo a sus ejemplos, para que veais su potencial:

http://www.openxava.org/web/guest/demos