Category: Desarrollo


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.

Este es el primero de una serie de tutoriales que pretendo publicar acerca de ir creando aplicaciones utilizando JSF 2.1.Intentaré centrarme en cómo se hacen ciertas tareas e ir creando material nuevo que o bien sea difícil de encontrar en nuestro idioma o no se haya publicado nada al respecto en ningún otro idioma. Por ello, pondré enlaces de recomendada lectura que vean que pueden aclarar conceptos, ya que es una tontería volver a publicar algo que esté bien explicado en otro lado.

Cómo primer objetivo, será entender el ciclo de vida y el proceso de creación de una aplicación sencilla en JSF, pero antes de nada, os recomiendo este enlace de adictos al trabajo  en el que se explican todos los conceptos de JSF sin entrar en mucho detalle.

Vamos a comenzar por crear un proyecto, para esta serie de tutoriales usaremos Netbeans 7.2 que ya viene incluido con soporte para JSF 2.1, un contenedor Tomcat 7.0.22 y soporte para Java EE6. Así que creamos un proyecto del tipo web application

Después hacemos las configuraciones del proyecto y pulsando Siguiente, hasta llegar a la elección de que frameworks queremos utilizar, entonces seleccionamos Java Server Faces

Ahora que tenemos el proyecto creado, vamos a crear un pequeño formulario para crear las estadísticas de un personaje de D&D. Necesitaremos  un backend bean, su diseño en facelet (XHTML) y una clase POJO para representar al personaje. Al final del articulo, encontrareis el proyecto que tiene la siguiente estructura:

Podréis observar las impresiones en consola que se hacen en los diferentes métodos, para que veamos y comprendamos mejor el ciclo de vida JSF aplicado al funcionamiento de una aplicación.

Así que vamos a echarle un ojo a la siguiente imagen del ciclo de vida:

ciclo de vida

Cómo podemos ver, tenemos diferentes fases, que en el enlace de adictos al trabajo se explica muy bien:

  1. Restaurar los conponentes de la vista (restore view). En esta etapa el controlador construye en memoria la estructura de componentes de la página.
  2. Aplicar los valores de la petición.. (apply request values). En esta etapa se recuperan los valores de la request y se asignan a los beans de la página.
  3. Procesamiento de las validaciones (process validations). Se verifican los parámetros de entrada según un conjunto de reglas definidas en un fichero de configuración.
  4. Actualizar los valores del modelo (update model values). Los valores leídos y validados son cargados en los beans.
  5. Invocacion a la aplicación (invoke application). Se ejecutan las acciones y eventos solicitados para la página. Si es necesario se realiza la navegación.
  6. Generación de la página (render response). En esta fase se genera la página que será enviada al usuario con todos sus elementos y valores actualizados.

Entonces, cómo afecta esto a nuestro proyecto?  Al  llamar por primera vez a la página, sólo se ejecutan las dos primeras fases, debido a que no hay información de la petición para relllenar el modelo.  Ahora el usuario rellena los datos y pueden ocurrir dos cosas, que haya algún error de validación, en cuyo caso no pasará del paso de validación y no se rellenará el modelo (nunca se ejecuta el setter) ni se ejecutará ninguna acción (no se ejecuta el método save() ). O bien que todo esté correcto, entonces ejecutará el siguiente paso de actualizar los valores del modelo y si no hay ningún error en este paso, se pasarían a ejecutar las invocaciones de los eventos, en este caso, se ejecutaría el método save().

También se puede ver, que el getter en el backend bean, se llama una vez por cada propiedad de la clase POJO, ya que a través de este getter obtenemos la clase POJO, por lo que si lo estuviéramos obteniendo con una consulta a una base de datos o algún otro método costoso, habrá que guardarlo en una variable del bean.

Por supuesto, esto se puede complicar más, porque habrá que tener en cuenta que ocurre cuando hay listeners  de por medio. Pero eso lo dejamos para otra entrada.

El proyecto entero, podeis descargarlo desde aquí.

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.

Actualmente, a la hora de desarrollar aplicaciones, se utilizan multitud de frameworks que nos abstraen de la base de datos que se utilizan. A pesar de las ventajas que esto proporciona, tiene un pequeño “pero”. Perdemos el control sobre las consultas, y en algún momento del desarrollo acabaremos teniendo algún problema que podriamos solucionar rápidamente sabiendo la consulta exacta que se ejecuta.

Para evitar este tipo de cosas, Mysql dispone de un estupendo log de consultas, que podemos activar  y ver la consulta exacta que hace nuestro framework a la base de datos.

Para activar y ver dicho log es bastante sencillo:

mysql> set global general_log='on';
mysql> set global log_output='table';
mysql> select * from mysql.general_log\G

El resultado será algo parecido a esto:

*************************** 47. row ***************************
event_time: 2012-08-29 11:43:46
user_host: root[root] @ localhost [127.0.0.1]
thread_id: 85
server_id: 1
command_type: Query
argument: SHOW FULL COLUMNS FROM `activites` FROM `gas` LIKE 'journee'
*************************** 48. row ***************************
event_time: 2012-08-29 11:43:46
user_host: root[root] @ localhost [127.0.0.1]
thread_id: 85
server_id: 1
command_type: Query
argument: INSERT INTO gas.activites (id, matricule, secteur, secteur2, CIN,
journee) VALUES (0, 30, 4, 4, '12345678X', null)

Donde vemos las consultas que se hacen directamente en la base de datos y detectar posibles errores que nos den una idea de por donde encaminar una posible solución.

Una vez que acabemos, es recomendable desactivar los logs, por tema de eficiencia y para no llenar de basura la tabla, que en un futuro nos haga más dificil volver a buscar fallos.

mysql> set global general_log='off';

En caso de querer vaciar la tabla de log, tan sencillo como:

truncate table mysql.general_log;

Y para acabar, este truquito, lo ví en el libro Mysql Troubleshooting de O’Really , que tiene bastantes cosas interesantes respecto a mysql.

Después de mucho tiempo sin trabajar con mi servidor local de prueba, habia olvidado la contraseña del usuario root de la base de datos. Así que una googleada rápida he llegado a la siguiente solución:

Usted puede recuperar la contraseña del servidor de base de datos MySQL con los siguientes pasos:

Paso 1: Detener cualquier proceso del servidor MySQL.
Paso 2: Iniciar el proceso del servidor MySQL (mysqld) con la opción –skip-grant-tables por lo cual este no preguntará por la contraseña.
Paso 3: Conectar al servidor MySQL como el usuario root
Paso 4: Configurar una nueva contraseña para la nueva contraseña root
Paso 5: Salir y reiniciar el servidor MySQL

A continuación están los comandos necesarios para cada uno de los pasos mencionados anteriormente (iniciar sesión como el usuario root):

Paso # 1: Detener el servicio mysql

# /etc/init.d/mysql stop

Salida:

Stopping MySQL database server: mysqld.

Paso # 2: Iniciar el servidor MySQL sin contraseña:

# mysqld_safe --skip-grant-tables

Salida:

[1] 5988

Iniciando el motor de mysqld de las bases de datos desde /var/lib/mysql

mysqld_safe[6025]: started

Paso # 3: Conectar al servidor mysql usando el cliente mysql:

# mysql -u root

Salida:

Bienvenido al monitor de MySQL.  Comandos y con ; o \g.

Your MySQL connection id is 1 to server version: 5.0.21-log

Tipiar ‘help;’ o ‘\h’ para obtener ayuda. Tipiar ‘\c’ para en vaciar el buffer.

mysql>

Paso # 4: Configurar una nueva contraseña del servidor MySQL para el usuario root:

mysql> use mysql;
mysql> update user set password=PASSWORD("NEW-ROOT-PASSWORD") where User='root';
mysql> flush privileges;
mysql> quit

Paso # 5: Detener el servidor MySQL:

# /etc/init.d/mysql stop

Salida:

Stopping MySQL database server: mysqld

STOPPING server from pid file /var/run/mysqld/mysqld.pid

mysqld_safe[6121]: ended

[1]+  Done                    mysqld_safe –skip-grant-tables

Paso # 6: Iniciar el servidor MySQL y verificar la contraseña:

# /etc/init.d/mysql start
# mysql -u root -p

Fuente: http://www.codigomaestro.com/mysql/recuperar-contrasena-root-de-mysql/