<?xml version="1.0"?>
     <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
     <channel>
      <link>http://www.bitacora.gesbit.com/</link>
      <title>Bitácora de Gesbit - Entrada "¿Es un fallo? ¿O una funcionalidad?" de la bitácora</title>
      <generator>Gesbit</generator>
      <description>Bitácora del gestor de bitácoras</description>
      <atom:link href="http://www.bitacora.gesbit.com/rss/" rel="self"
       type="application/rss+xml" />
    
      <item>
       <link>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/</link>
       <guid>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/</guid>
       <pubDate>Wed, 02 Jul 2008 20:26:18 +0200</pubDate>
       <title><![CDATA[ ¿Es un fallo? ¿O una funcionalidad? ]]></title>
       <description><![CDATA[<p>Me temo que voy otra vez a aburrirte hablando sobre el caché de contenidos de Gesbit, recientemente disponible, como seguramente sepas. Hace poco que tratamos de este asunto en esta bitácora, e incluso le he dedicado varias entradas, la última: <a title="Entrada en esta bitácora" href="http://www.bitacora.gesbit.com/disponible-el-cache-de-contenidos/">Disponible el caché de contenidos</a>. El caso es que me he topado con lo que pudiera parecer un problema, o al menos una cierta vulnerabilidad.</p>
<p>Intentaré explicar esto a continuación, a ver si también, de este modo, y puesto que en esta bitácora faltan otros puntos de vista en forma de comentarios (los tuyos, por ejemplo), como he dicho ya más de una vez, escribiré por ver si yo también puedo poner en claro algunas de las cosas que tengo dando vueltas en la cabeza. Así es, ni siquiera yo tengo claro que lo notado tenga alguna relevancia.</p>
<p>Resulta que el sistema de caché hace uso de las URLs de las bitácoras para saber, por decirlo así, si dicha URL está ya "cacheada" o no lo está. Ahora bien, siendo esto así, como lo es, un usuario malintencionado podría solicitar una URL como esta, por ejemplo:</p><div class="gbhighlighcode"><div class="sourcecode"><pre class="php">http:<span style="color: #808080; font-style: italic;">//www.unabitacora.com/?nocache=1</span></pre></div></div>
<p>Como puedes ver, la URL en cuestión incluye en este caso una variable, que Gesbit no tendrá en cuenta, pero, que, en todo caso forma parte de la URL. De este modo, el sistema de caché comprobaría si dicha URL ha sido "cacheada", y, si no lo ha sido, "dejará" que Gesbit genere dinámicamente la página correspondiente. Como acaso ya imagines, la página generada formaría parte entonces del caché de Gesbit (si está en uso) y se serviría en otras ocasiones para la misma URL.</p>
<p>Ahora bien, es fácil suponer que un usuario malintencionado podría usar este tipo de URLs para "forzar" la generación dinámica de páginas, para "saltarse" el sistema de caché, y, en un momento dado, para llevar a cabo un "ataque" de "denegación de servicio" contra el servidor que albergue la bitácora en cuestión. El sistema de caché reconocería estas URLs como distintas, porque, realmente, lo son:</p><div class="gbhighlighcode"><div class="sourcecode"><pre class="php">http:<span style="color: #808080; font-style: italic;">//www.unabitacora.com/?nocache=2</span>
http:<span style="color: #808080; font-style: italic;">//www.unabitacora.com/?nocache=3</span>
http:<span style="color: #808080; font-style: italic;">//www.unabitacora.com/?nocache=4</span>
http:<span style="color: #808080; font-style: italic;">//www.unabitacora.com/?nocache=N</span></pre></div></div>
<p>He comprobado que este "problema" sucede no sólo en el sistema de caché implementado en Gesbit, sino en otros sistemas similares, y es que, como digo, siempre que estos se basen en la URL para conformar un "identificador" para las páginas que se sirven, será posible utilizar la técnica mostrada para "saltarse" el sistema de caché de contenido, para forzar la generación de páginas dinámicas.</p>
<p>He consultado privadamente con el autor de uno de estos "sistemas de caché" y, según él no se trata de un fallo, porque, lo mismo que ocurre con estas URLs ocurriría con cualquier otra que incluyera variables. Creo que entiendo lo que quiere decir, y creo sinceramente que este hombre sabe más que yo de estos menesteres, pero, todavía no me quedo del todo tranquilo.</p>
<p>Y es que el asunto, si es que representa o puede representar un problema, no tiene fácil solución, a lo que se ve. Lo segundo que se le ocurre a uno (por no aburrir no diré lo primero que se le ocurre) es conformar una lista de variables "válidas", de modo que no se tengan en cuenta el resto de variables en las URLs. Esta, que podría parecer una solución ideal, dista mucho de serlo, en el caso de Gesbit, al menos. </p>
<p>Es verdad que sería posible crear la tal lista de variables "válidas", pero, en el supuesto caso de que los plugins o temas de Gesbit necesitasen usar variables, el asunto no pintaría nada bien. Esto es porque el sistema de caché de contenidos en Gesbit funciona sin necesidad de hacer ni una sola consulta a la base de datos de Gesbit.</p>
<p>El sistema de caché se pone en marcha antes incluso de que el sistema de plugins lo haga, porque este requiere ya de una consulta a la base de datos: para obtener, justamente, las opciones de Gesbit, entre las que se encuentra la que determina qué plugins están "activos", cuál es el tema "actual", etc. Entonces, aquí, surge un dilema.</p>
<p>Si concluimos que sería bien crear la tal lista de variables "válidas" para solucionar el posible "problema" (luego se verá porqué entrecomillo) en el caché de contenidos, entonces será necesario hacer al menos una consulta a la base de datos de Gesbit, antes de que el sistema de caché se ponga en marcha. ¡Y esto es precisamente lo que se pretende evitar!</p>
<p>Por otro lado, y, queriendo entender la opinión del compañero, que, sin duda, sabe más que yo de estos menesteres, quiero pensar que soy demasiado imaginativo... y en realidad el susomentado "problema" con el caché de contenidos en realidad no es tal. Es cierto que el usuario que lo sepa puede "saltarse" el caché y "forzar" la generación de una página dinámica. A esto Gesbit no le preocupa mucho, porque, genera páginas con soltura sin problemas.</p>
<p>Pero, cuando hablo de un posible problema, ¿a qué me estoy refiriendo exactamente? ¿Qué quiero decir? Si lo que pienso, como es la verdad, es que alguien podría realizar una ataque de denegación de servicio a una bitácora, ¿para qué va a tener necesidad nadie de saltarse el caché de contenidos, si puede pedir, directamente, otra página de la bitácora, que, precisamente, no pasa por el caché de contenidos?</p>
<p>Hablo, por ejemplo, de la página que da entrada al panel de administración de Gesbit, por ejemplo. ¡Pero es que valdría cualquier otro archivo, cualquier otra petición, para hacer lo que se pretende! La hoja de estilo de un tema, por ejemplo, alguien puede "pedirla" y "pedirla" al servidor hasta dejarle KO, si es que esto es posible. Y aquí es cuando caigo del guindo.</p>
<p>Tal vez sea por algo alrededor de esto último que digo, por lo que esta persona con la que he consultado, no considera un problema este asunto: si alguien quiere hacer un ataque de denegación de servicio, no necesita saltarse el caché de contenidos... utilizará cualquier otra URL para hacer lo que pretende. Y, por otro lado, ahí acaba todo, es decir, no hay otro problema que ese con el caché de contenidos.</p>
<p>En fin. Que voy a publicar esta entrada, más que nada, porque queda demostrado, una vez más, que escribir sobre algo ayuda a encontrar una posible solución a lo que sea. En este caso no he encontrado una solución, pero, me he quedado más tranquilo, porque, he llegado a la conclusión, creo, acertada. Y el problema que veía al principio, parece que, en realidad, no es tal.</p>
<p>Pues mejor, ¿no te parece a ti también así?</p>]]></description>
      </item>
      
      <item>
       <link>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/#comment-65</link>
       <guid>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/#comment-65</guid>
       <pubDate>Fri, 04 Jul 2008 19:04:29 +0200</pubDate>
       <title><![CDATA[ Comentario por "David Esperalta" ]]></title>
       <description><![CDATA[Voy a tratar de explicar porqué "tengo para mí" que el sistema no se resentiría. Para conocer si un archivo está o no expirado, no se accede al contenido del mismo, no se lee, sino que usa la función "filemtime()" de PHP, cuyo resultado se compara con una determinada variable.

Por otro lado, que un archivo se "revise", no quiere decir que vaya a ser borrado, que, creo yo, sería lo que más tiempo consumiría. Y, hablando de borrado, en mi ignorancia yo supongo que la "orden" de borrado que se da al sistema operativo, este la ejecutará de forma inteligente.

¿Qué quiero decir? Por ejemplo, en el panel de administrador de Gesbit, existe un enlace que el usuario puede usar para borrar el caché de contenidos. Dicho enlace ejecuta (mediante una petición HTTP en segundo plano) cierto "script", que se encarga de borrar todos los archivos del caché, esta vez, expirados o no.

Pues bien, la respuesta es inmediata... pero absoluta y realmente inmediata. Uno pulsa el enlace... y acto seguido recibe el mensaje que retorna de vuelta el "script" en cuestión: "El caché de contenidos se ha vaciado". Yo, en mi ignorancia, supongo que el sistema, si lo ve oportuno, puede no borrar los archivos "cuando se lo dices", sino cuando mejor le viene.

Pero, el caso es que la "orden" se cumple ipsofacto, sin que sea apenas necesario tiempo. No sé si me explico... en definitiva creo que el sistema (en este caso GNU/Linux) se comporta excelentemente, y por eso he dicho arriba que pienso que ni con 200 ni con 2000 archivos se resentiría mucho, porque estas tareas son, en mi opinión, muy rápidas.

Pero, en fin, dicho esto, también digo que una cosa no quita la otra. Sólo que es menester tener un poco los pies en la tierra, pensar en la realidad del asunto, optimizar, por supuesto, pero, no hasta el punto de que sea para algo que, en verdad, puede no ser el cuello de botella de la aplicación. Pero con esto no menosprecio tu opinión, Román, todo lo contrario: sigo estando de acuerdo contigo.

Quería añadir a lo dicho que no existe sólo un método para borrar los archivos en caché, sino que, por ejemplo, cuando se actualizan o borran etiquetas, categorías, entradas, páginas, opciones... también se procede a hacer una limpieza del caché, esta vez borrando no ya archivos expirados, sino "relacionados" con el contenido actualizado en la bitácora.

¿Igual es que estoy hoy demasiado vago o qué? Je je je... ciertamente parece que has dado en un buen punto Román, y que habría que tratar de buscarle una solución, y punto. No tratar de justificar cómo se hace ahora, como parezco hacer, aunque en base a cierta experiencia y pruebas, sino tratar de mejorar el asunto y ya está. ¿Para qué darle más vueltas? Ya veremos...]]></description>
      </item>
      
      <item>
       <link>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/#comment-64</link>
       <guid>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/#comment-64</guid>
       <pubDate>Fri, 04 Jul 2008 18:51:37 +0200</pubDate>
       <title><![CDATA[ Comentario por "David Esperalta" ]]></title>
       <description><![CDATA[Hola Román. Lo que dices no carece del todo de sentido. Por ahora, al no haber muchas visitas en mis bitácoras, el número de archivos en el caché se sitúa (en la que más visitas recibe) en menos de 200. No parecen muchos archivos... de hecho no se nota una bajada de rendimiento ni nada parecido. Pero voy a hacer pruebas con <a rel="nofollow" href="http://www.bitacora.davidesperalta.com/descubriendo-xdebug-para-php/" title="Entrada en mi bitácora personal">XDebug y WinCacheGrind</a>.

No obstante, eso no quiere decir que, como tú, piense que tal vez este asunto puede mejorarse, en lugar de revisando a cada petición si existen archivos expirados, haciéndolo cada cierto tiempo únicamente. Probablemente pueda encontrarse una solución a esto, aunque, para mí tengo que el sistema no se resiente, y que no lo haría aunque fueran muchos, pero muchos archivos... muchos más que 200 e incluso que 2000.

En todo caso lo que dices tiene mucho sentido, y, como digo, todo sería tratar de encontrar alguna otra solución satisfactoria. Por el momento no sé si voy a tocar el asunto, pero, tomo buena nota de ello por si en futuro notara que, efectivamente, no debo revisar los archivos del caché a cada petición. En todo caso voy a hacer ahora mismo unas cuentas pruebas con ayuda de XDebug y WinCacheGrid, como digo. Sólo que las haré sobre Windows... sobre mi sistema... y el servidor en que se encuentran mis bitácoras es bastante más potente.]]></description>
      </item>
      
      <item>
       <link>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/#comment-63</link>
       <guid>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/#comment-63</guid>
       <pubDate>Fri, 04 Jul 2008 17:59:23 +0200</pubDate>
       <title><![CDATA[ Comentario por "roman" ]]></title>
       <description><![CDATA[<em>En realidad el caché se "limpia" solo. Cada vez que se hace una petición a una bitácora, se instancia la clase "GbCache", y, lo primero que hace, es comprobar si existe una respuesta "cacheada" para la petición que se lleva a cabo. Pero, aún antes de esto, ya comprueba si en el caché hay archivos "expirados", y los borra, si es así.</em>

Y, ¿qué pasa si tienes una cantidad enorme de páginas y visitas? ¿No será excesivo estar revisando todos los archivos de <em>cachè</em> en cada acceso?

Por dar un ejemplo, que puede estar equivocado, pienso en los archivos de sesión de PHP. Si termina una sesión y no se llama a session_destroy(), el archivo de sesión que se guarda en el servidor no se borra, aunque como tal ya no es válido. PHP maneja una <em>probabilidad</em> para su <em>recolección de basura</em>, de forma que no borra en cada acceso sesiones expiradas, sino sólo <em>cada tanto</em>, de acuerdo a la probabilidad que se le indique. Si PHP hace esto, pienso, quizá sea porque pueda resultar excesivo verificar en cada ocasión todos los archivos.

Bueno, solo un comentario.

Saludos]]></description>
      </item>
      
      <item>
       <link>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/#comment-62</link>
       <guid>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/#comment-62</guid>
       <pubDate>Fri, 04 Jul 2008 09:36:13 +0200</pubDate>
       <title><![CDATA[ Comentario por "David Esperalta" ]]></title>
       <description><![CDATA[Hola Román,

<em>Disculpa la demora en contestar pero estaba esperando a que se me ocurriera alguna idea brillante. No ha pasado nada :D</em>

No te preocupes, hombre, no faltaba más. Si a ti no se te ha ocurrido nada... ¡yo me niego a seguir dándole vueltas! ;)

<em>Creo que entiendo el punto y ciertamente no veo cómo podría evitarse, aunque quizá un "ataque" de esta naturaleza afectaría más que nada al atacante ¿no? Si una página ya está en el cachè, quienes accedan a ella como dios manda, seguirán obteniéndola rápidamente. No así quienes decidan añadirle parámetros, cada vez que la pidan obtendrán un copia regenerada.</em>

Así es la verdad. De hecho creo que el ataque de que he hablado yo (más que nada) queda claro que no sólo podría venir de ahí: ese tipo de ataques "DOS", en caso de querer hacerse, puede llevarse a cabo de otras formas, no importa si el sistema de caché está ahí, está "activo" o no lo está. Esto ya parece quedarme claro: fue un error mío pensar que ambas cosas, ataque DOS y caché, tenían algo que ver.

<em>Claro que la generación de estas copias es una carga para el servidor, pero -y este punto no lo tengo claro- ¿cuál es el principal objetivo del cachè? ¿Aligerar la carga general del servidor o presentar las páginas lo más rápido posible al usuario?</em>

Digamos que ambas cosas. Pero Gesbit no muestra problemas en generar páginas: es bastante rápido también sin usar el caché de contenido. Por otro lado, es claro que la carga del servidor se reduce con el caché, porque, para empezar no se utiliza la base de datos en absoluto, cuando se sirve una página desde el caché.

Este tipo de caché, que no es exhaustivo, puede venir muy bien si tu bitácora llega a la portada de algún sitio del estilo de Digg o Menéame, puesto que recibirías un montón de visitas "seguidas", a una determinada página de la bitácora, que se supone entraría a formar parte del caché acto seguido, evitando su regenaración por cada una de las visitas "intempestivas" que recibieras.

<em>En cuanto a lo primero, ya vimos que de todas formas pueden hacer su DOS, y en cuanto a lo segundo pues, lo dicho, el ataque se les regresa como bumerang :D</em>

Creo que llevas razón una vez más, y lo digo por lo que a continuación añadiré.

<em>La única preocupación que veo en estos momentos sería la de saturar el servidor con archivos de cachè innecesarios, pero supongo que puede implementarse un proceso (posiblemente un CRON) que limpie archivos que sobrepasen una antigüedad determinada.</em>

En realidad el caché se "limpia" solo. Cada vez que se hace una petición a una bitácora, se instancia la clase "GbCache", y, lo primero que hace, es comprobar si existe una respuesta "cacheada" para la petición que se lleva a cabo. Pero, aún antes de esto, ya comprueba si en el caché hay archivos "expirados", y los borra, si es así.

Esto funciona con una constante de tiempo. Ahora mismo Gesbit establece dos horas de expiración para los archivos en caché, de modo que, efectivamente, puede comprobarse que en el caché no hay archivos de más de dos horas desde su creación. Como digo, no se trata de un sistema de caché muy exhaustivo, pero, creo que sirve bien a su objetivo.

En definitiva, creo que este asunto ha quedado más o menos claro. Si alguien quiere llevar a cabo un ataque DOS, el sistema de caché poco o nada tiene que decir, no como yo pensaba. Y, si alguien quiere usar lo que hemos estado comentando para obtener páginas "siempre dinámicas", en realidad, Gesbit no tiene problema en servirlas de este modo.

Muchas gracias por tus comentarios Román. He aquí a una persona que sabe y no le molesta compartir con los demás lo que sabe, todo lo contrario, lo hace en el <a rel="nofollow" href="http://www.clubdelphi.com/" title="ClubDelphi">ClubDelphi</a> (con marca de mayor número de mensajes incluida) desde hace años, sin ir más lejos. Esto no sería reseñable si toda la gente fuera así. Así que gracias otra vez Román. ;)]]></description>
      </item>
      
      <item>
       <link>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/#comment-61</link>
       <guid>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/#comment-61</guid>
       <pubDate>Thu, 03 Jul 2008 22:42:48 +0200</pubDate>
       <title><![CDATA[ Comentario por "roman" ]]></title>
       <description><![CDATA[Hola,

Disculpa la demora en contestar pero estaba esperando a que se me ocurriera alguna idea brillante. No ha pasado nada :D

Creo que entiendo el punto y ciertamente no veo cómo podría evitarse, aunque quizá un "ataque" de esta naturaleza afectaría más que nada al atacante ¿no? Si una página ya está en el <em>cachè</em>, quienes accedan a ella <em>como dios manda</em>, seguirán obteniéndola rápidamente. No así quienes decidan añadirle parámetros, cada vez que la pidan obtendrán un copia regenerada.

Claro que la generación de estas copias es una carga para el servidor, pero -y este punto no lo tengo claro- ¿cuál es el principal objetivo del <em>cachè</em>? ¿Aligerar la carga general del servidor o presentar las páginas lo más rápido posible al usuario?

En cuanto a lo primero, ya vimos que de todas formas pueden hacer su DOS, y en cuanto a lo segundo pues, lo dicho, el ataque se les regresa como bumerang :D

La única preocupación que veo en estos momentos sería la de saturar el servidor con archivos de <em>cachè</em> innecesarios, pero supongo que puede implementarse un proceso (posiblemente un CRON) que limpie archivos que sobrepasen una antigüedad determinada.

Saludos]]></description>
      </item>
      
      <item>
       <link>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/#comment-60</link>
       <guid>http://www.bitacora.gesbit.com/es-un-fallo-o-una-funcionalidad/#comment-60</guid>
       <pubDate>Wed, 02 Jul 2008 23:15:36 +0200</pubDate>
       <title><![CDATA[ Comentario por "David Esperalta" ]]></title>
       <description><![CDATA[De todas formas... creo que se entiende a lo que yo me refería: efectivamente, parece claro que si quieren "saturar" el servidor podrán hacerlo, en un momento dado, independientemente del "problema" de que he hablado, pero, ¿esto es totalmente insignificante?

Es decir,... lo cierto es que alguien puede pasarse el caché por alto, ¿no? ¿Tú cómo lo ves Román? :)

Es que, joroba, para una vez que "descubro" algo "curioso" resulta que no tiene que ver... :D :D]]></description>
      </item>
      
     </channel>
    </rss>