miércoles, 28 de enero de 2015

Usando fuentes de alta calidad en nuestros proyectos web de la mano de Google

Google tiene un interesante proyecto llamado Google Fonts API, que consiste en una colección de fuentes open source de una calidad nada despreciable, disponibles para usar en cualquiera de nuestros proyectos y mejorar su presentación con solo algunas líneas de HTML y CSS.

Funciona sobre la mayoría de navegadores, y su implementación es simple: una vez seleccionemos una fuente que queramos usar de este listado,  debemos insertar la hoja de estilos del proyecto:

<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Tangerine">

Con el atributo family se especificamos el nombre de la fuente que se va a utilizar, por ejemplo en el código anterior la fuente es Tangerine.

Ahora en el CSS de nuestro documento HTML debemos indicar que usaremos esta fuente, como se hace normalmente con CSS:

body {
        font-family: 'Tangerine', serif;
        font-size: 48px;
}

Y finalmente creamos nuestro HTML normalmente:

<div>Haciendo la web m&aacute; bella!</div>

Para obtener un resultado como este:
Fuente Tangerine
Fuente Tangerine
Para más información del proyecto podemos visitar su web oficial.

martes, 27 de enero de 2015

Uso de include() y require() en PHP

A la hora de querer incluir código que está contenido en otros archivos, PHP nos ofrece cuatro funciones: include(), require(), include_once(), y require_once(); las cuales a "simple vista" funcionan igual ya que todas incluyen el código del archivo especificado y hacen que el intérprete de PHP lo evalúe, pero que en realidad difieren las unas de las otras por características específicas que se deben tener en cuenta a la hora de elegir alguna.

A continuación una explicación de su funcionamiento y diferencias:

  • include() como ya se dijo, incluye todo el código de un archivo que le especifiquemos para que dicho código sea evaluado por el intérprete de PHP. El archivo puede ser incluido tantas veces como deseemos y si por alguna razón  no existe o no es accesible, el script desde dónde se está llamando se continuará ejecutando y el intérprete nos arrojará una alerta.
  • include_once() hace lo mismo que include(), pero a diferencia de ésta sólo permite incluir una vez al archivo. Esto nos resulta últil para evitar conflictos con la declaración de variables y demás objetos, así como para no afectar el rendimiento de la aplicación.
  • require() hace también lo mismo que include(), pero a diferencia de la segunda si el archivo que se está llamando no existe la ejecución del script se detendrá.
  • require_once() se comporta como require(), pero como lo hace include_once() no permite que se incluya el archivo más de una vez.

Finalmente al utilizar alguna de estas sentencias es importante tener en cuenta que:

  • Las cuatro son sentencias, no son métodos; por lo cual debemos evitar colocar el nombre del archivo entre paréntesis, solo basta con colocarlo entre comillas dobles.
  • La ejecución de include_once y require_once tiende a ser más lenta que la de include y de require; por lo cual mientras el ámbito del proyecto no lo requiera es recomendable hacer uso de éstas dos últimas.
  • Como buena practica de seguridad, es recomendable que si los archivos que se incluyen manejan información sensible éstos estén  contenidos en directorios protegidos.

sábado, 24 de enero de 2015

Optimizando la ejecución de una macro de excel

Las macros de excel son una excelente alternativa a la hora de automatizar procesos que involucran cálculos y tratamiento de datos, gracias a su fácil programación y a lo fácil que es contar con un equipo con el programa instalado

En los entornos productivos, con el paso del tiempo las macros que vamos escribiendo suelen crecer en tamaño y complejidad a causa de la dinámica de los procesos y del negocio, lo cual suele llevar a que el código tienda a volverse en lento. 

Para evitar lo anterior, como en cualquier desarrollo de software, es importante adoptar buenas prácticas entre las cuales se pueden destacar los siguientes principios:

  • DRY (Don't repeat yourself - No te repitas): que básicamente consiste en que no se debe eliminar al máximo la duplicidad de procesos, o en este caso de instrucciones, para lo cual es fundamental hacer uso de funciones, clases, módulo y demás elementos que proveen los lenguajes de programación (para el caso de este artículo vba de excel) y sus paradigmas.
  • KISS (Keep It Simple, Stupid - Mantenlo simple, estúpido): el cual establece que un sistema funciona mejor si se elimina al máximo la complejidad en su diseño.
  • YAGNI (You ain't gonna need it - No vas a necesitarlo): el cual consiste en que una funcionalidad que no va a ser utilizada no debe ser implementada.

Pero más allá de la metodología que se adopte para los procesos de desarrollo, también es importante desde la misma creación del código fuente contar con buenas practicas para que al momento de ejecutar nuestros programas el tiempo que estos se tarden sea el mejor.

A continuación comparto algunas de las practicas que suelo realizar al escribir el código de las macros de excel, las cuales naturalmente no son todas las posibles, pero que en mi caso me han sido de gran utilidad para optimizar el rendimiento de las mismas.

Deshabilitar algunas funcionalidades propias de excel

Una de las cosas que más ralentizan la ejecución de una macro son el hecho de que todo el proceso que estas hacen se muestra en pantalla, por lo cual suelo deshabilitar esta característica mientras se ejecuta el código de la macro así:

Application.screenupdating=False

Con esto cada vez que se ejecute el código, no se verá en pantalla todo el proceso sino que la macro se ejcutará de una manera más silenciosa. Una vez se termine la rutina o proceso que estamos codificando solo basta con cambiar de nuevo el valor a true:

Application.screenupdating=True

También es bueno deshabilitar otras características como los cálculos y eventos automáticos:

Application.calculation=xlCalculationManual
Application.EnableEvents=False

Con base a lo anterior así sería el ejemplo de una macro con las instrucciones mencionadas:

Private Sub Worksheet_Activate()
    ' Declaro e inicializco variables
    Dim NumeroPagos As Long
    NumeroPagos = 0
    
    Application.ScreenUpdating = False ' Deshabilito actualización en pantalla
    Application.Calculation = xlCalculationManual ' Deshabilito los cáculos automáticos
    Application.EnableEvents = False ' Deshabilito los eventos automáticos
    ActiveSheet.PivotTables("Resumen Pagos").PivotCache.Refresh 'Actualizo la tabla dinámica
    NumeroPagos = Range("A" & Rows.Count).End(xlUp).Row ' Obtengo la cantidad de registros en la hoja
    Application.DisplayStatusBar = True ' Activo la barra de estado
    Application.StatusBar = "Hay " & NumeroPagos & " registros." ' Cambio el contenido de la barra de estado
    Application.ScreenUpdating = False ' Habilito de nuevo la actualización en pantalla
    Application.Calculation = xlCalculationAutomatic ' Habilito de nuevo los cálculos automáticos
    Application.EnableEvents = False ' Habilito de nuevo los eventos automáticos
End Sub


Centralizar a la medida de lo posible el código fuente

Siendo consecuentes con los principios mencionados al comienzo de la entrada, una buena practica es centralizar el código fuente que contiene funciones y rutinas en módulos, y hacer uso de estas a través de los diferentes eventos disponibles en cada hoja.

Utilizar la instrucción with para trabajar con los objetos

Si se necesita trabajar con un objeto como una hoja, un rango, o una gráfica por ejemplo; es más óptimo acceder a éste y manipularlo con la instrucción with ya que solo debo hacer referencia al objeto una vez:

' De la forma tradicional debo hacer referencia al objeto en cada línea
ActiveWorkbook.Sheets(1).Range("A1:A3").Font.Size = 12
ActiveWorkbook.Sheets(1).Range("A1:A3").Font.Name = "Calibri"
ActiveWorkbook.Sheets(1).Range("A1:A3").Font.Bold = True
    
' Usando With solo lo debo hacer una vez, lo cual optimiza el tiempo de ejecución
With ActiveWorkbook.Sheets(1).Range("A1:A3").Font
        .Size = 12
        .Name = "Calibri"
        .Bold = True
End With

Usar las formulas directamente desde visual basic

Haciendo uso del método WorksheetFunction  del objeto Application se pueden ejecutar las mismas formulas que se tienen disponibles en la hoja de cálculo, teniendo en cuenta que al usarlas desde excel éstas están con su nombre en inglés. Por ejemplo:

' Escribo la fecha y hora actuales usando la función AHORA()
Range("A").Value = Application.WorksheetFunction _
.now()

Conclusiones


Los puntos descritos en esta entrada no son los definitivos, existen muchos más "trucos" y buenas practicas que contribuyen a optimizar el tiempo de ejecución. En términos generales las buenas practicas que se aplican en otros lenguajes de programación se pueden aplicar con éxito a la hora de escribir macros.

El tiempo de ejecución de una macro es un factor importante para mejorar la experiencia del usuario final, y más aún si estamos en un entorno corporativo donde el tiempo es valioso; por lo cual, desde la misma etapa de diseño de una solución se debe apuntar a hacer uso de las mejores practicas de programación.

jueves, 22 de enero de 2015

Auditando la seguridad de nuestro servidor web con Nikto

Nikto es una herramienta Open Source escrita en Perl cuyo objetivo es auditar la seguridad de servidores web buscando problemas y alertas relacionadas con errores de configuración, software desactualizado, configuraciones por defecto, programas y archivos inseguros, y demás posibles vectores de ataque.

Funciona bajo Linux, Windows, MAC OSX y múltiples variantes de UNIX. Es una herramienta diseñada para la evaluación de sistemas, por lo cual su funcionamiento no pasa desapercibido ante herramientas de defensa como los IDS por ejemplo. Al ser una herramienta de diagnóstico sólo nos arroja información y no provee ningún mecanismo de ataque.

Para su instalación sólo basta con cumplir ciertos requerimientos, descargarlo e instalarlo; de hecho en muchas distribuciones viene incluido en los repositorios por lo que solo basta instalarlo desde la línea de comandos usando el gestor de paquetes propio de la distribución que usemos. Para mi caso que uso Elementary (también funciona en Debian, Ubuntu y similares) sólo basta con teclear en la consola:

sudo apt-get install nikto

Una vez instalado, para auditar un servidor solo basta con ejecutar el programa con los siguientes parámetros:

nikto -host [direccion o hostname del servidor]

Por ejemplo:

nikto -host 192.168.0.1

Así el programa comenzará a auditar el servidor, proceso que dura varios minutos; y comenzará a arrojar información relacionada con el software que tiene instalado, servicios que presta, CGIs, módulos habilitados, aplicaciones instaladas, archivos, directorios, vulnerabilidades encontradas con su respectivo identificador y toda posible información.

Auditando la seguridad de un servidor con Nikto
Auditando la seguridad de un servidor con Nikto
Nikto ofrece diferentes opciones para parametrizar la auditoria como por ejemplo especficar por cuales puertos se deben hacer las peticiones, si se debe usar un proxy, se se debe usar SSL a la fuerza, si se deben usar algunos de sus plugins, entre otras; esta es la lista de opciones se encuentra disponible ejecutando nikto -h.

Es importante resaltar que toda la información que muestra el programa no necesariamente representa una amenaza de seguridad, sin embargo nos permite tener una completa visión de como un posible atacante ve nuestro sistema. Un escenario que no respresenta un riesgo es que por ejemplo nos puede mostrar que en el servidor hay instaladas aplicaciones conocidas como wordpress, phpmyadmin, entre otras; las cuales en si no representan algún riesgo (si están bien configuradas claro está).

Todo esfuerzo para proteger la información e infraestructura que soporta nuestros sistemas de información no está demás, y más aún cuando estamos hablando de entornos productivos. Si bien en el mercado existen múltiples herramientas para probar y explotar la inseguridad de un servidor y/o aplicación, nikto hace muy bien su trabajo y de una forma simple.

Como desarrolladores no está demás que en los procesos de desarrollo incluyamos actividades enfocadas a la seguridad informática y a la seguridad de la información, para que desde su concepción la calidad de nuestros productos sea la mejor posible.

Para más información de la herramienta y su funcionamiento podemos consultar su documentación oficial que están en inglés.

lunes, 19 de enero de 2015

Protegiendo directorios en aplicaciones que corren sobre Apache

Uno de los errores más frecuentes al desarrollar aplicaciones web es el dejar directorios críticos accesibles a cualquier persona, los cuales pueden contener archivos y scripts con información sensible que solo debería ser visible a usuarios autorizados y/o a la propia aplicación.

Ejemplo de acceso a un directorio web por cualquiera
Ejemplo de acceso a un directorio web por cualquiera

En el ejemplo anterior se ve como es posible acceder al contenido de un directorio y explorar sus archivos, e incluso descargar y visualizar su contenido dependiendo de su naturaleza. Lo anterior se da porque no hay un archivo "index" que es el primero que ejecuta el servidor Apache, por lo cual la solución más inmediata es definir un archivo index que muestre un mensaje al usuario cuando intente acceder al directorio o que automáticamente lo redireccione a otro lugar.

Por ejemplo con php el contenido del index podría ser:

header("Location: ../error_acceso.php")

Y el contenido del archivo error.php sería algo como:

echo 'Usted no tiene permisos para acceder a esta sección!
Contactar al administrador';

Error de acceso a directorio personalizado
Error de acceso a directorio personalizado con PHP

Otra manera de asegurar un directorio es haciendo uso del propio servidor Apache (el servidor http más usado en internet), el cual nos provee un mecanismo que permite mediante un archivo de configuración creado por nosotros mismos, agregar diferentes características a los directorios que conforman una aplicación web, entre ella la autenticación.

Para añadir autenticación (acceso con usuario y contraseña) a un directorio lo primero que debemos hacer es crear un archivo de texto plano llamado .htaccess el cual debe ser guardado en el directorio que debemos proteger y cuyo contenido debe ser algo como esto:

AuthName "Acceso restringido"
AuthType Basic
AuthUserFile /opt/lampp/var/.htpasswd
AuthGroupFile /dev/null
require valid-user

Lo cual en resumen es lo siguiente:

  • La primera línea especifica el texto que se mostrará en la ventana de autenticación
  • La segunda línea especifica que será una atenticación básica usando el módulo mod_auth_basic de apache. Más información aquí.
  • La tercera línea indica el archivo .httpasswd donde están almacenados el usuario y clave válidos, el cual se explicará unas líneas más adelante.
  • La cuarta línea especfica la ubicación de la lista de usuarios autorizados para autenticarse, que este caso es ninguna (null) ya que solo usaremos el que esté especificado en el archivo .htpasswd.
  • La quinta y última línea indica que solo tendrán acceso los usuario válidos (previamente autenticados).

Finalmente se debe generar el archivo .htpasswd que contendrá el nombre de usuario y la clave encriptada válidos para acceder al directorio. Para generarlo sólo basta con acceder a la carpeta bin de nuestra instalación de apache, que para mi caso que estoy sobre linux y uso XAMPP es /opt/lampp/bin, y desde allí ejecutar el programa httpasswd así:

sudo ./htpasswd -c /opt/lampp/var/.httpasswd usuario

Donde  /opt/lampp/var es la ruta donde se guadará el archivo, la cual debe coincidir con la especificada en el archivo .htaccess y debe ser una ruta interna accesible por la aplicación pero no accesible desde internet (por seguridad no usar ubicaciones contenidas en los archivos htdocs, www o similares); y usuario será el nombre de usuario que queremos usar para autenticarnos. una vez lo ejecutemos el programa nos preguntará la clave que asignaremos, la escribimos y la confirmamos:


Ejecutando httpasswd de apache
Ejecutando httpasswd de apache
Y listo, una vez creados los archivos y si apache tiene la configuración correcta con los módulos necesarios habilitados, cada vez que se intente acceder al directorio protegido el navegador nos solicitará usuario y clave; sin embargo no debemos ser confiados y usando el sentido común debemos evitar a la medida de lo posible publicar información sensible en los directorios y archivos de las aplicaciones web.