Automágica: durante 2017 estoy trabajando bastante en Automágica, mi software para editar libros: Más información - Posts relacionados

Es dificil escribir las reglas de un juego!

Hoy a la tarde estuvimos jugando con mi abuela al Crapó. Es un juego de cartas inglesas bastaste jugado en mi familia. En una oportunidad había buscado las reglas en Wikipedia y al no encontrarlas me propuse publicarlas. Hoy saldé la deuda, pero me di cuenta que no es nada fácil escribir las reglas de un juego, aunque uno lo haya jugado mil veces!

¿Cómo empezás? ¿Definís un vocabulario? Si emepezás a nombrar conceptos del juego que los lectores desconocen, podés perderlos o van a terminar leyendo arriba y abajo, arriba y abajo hasta comprenderlo por entero!

Busqué cómo estaban explicados otros juegos de naipes e intenté imitarlos. No se qué tan bien salió, pero por lo menos está hecho. Ahora cualquier wikipedista puede mejorar lo que hice, redacción, estilo, formato.

A este blog lo llamo, en borrador permanente, así que en lugar de dejarles las intrucciones aquí, los invito a leerlas en Wikipedia y a jugarlo. Si las dejara aquí serían letra muerta, emparchadas talvez con algún generoso comentario que corriga mis errores, pero Wikipedia es la letra viva y ahí me gusta contribuir este tipo de cosas.

Saludos!


La historia de Python: Y la serpiente ataca

El siguiente texto es una traducción del artículo And the Snake Attacks de Greg Stein publicado en http://python-history.blogspot.com/.

Y la serpiente ataca

Esta bien. Bueno. En 1995, cuando tuve mi primer contacto con Python, cualquier referencia a una "serpiente" estaba prohibida. Python tomaba el nombre de Monty Python, no del reptil. Si alguien estaba atacando, eran Los Caballeros que dicen Ni o posiblemente el Conejo de Caerbannog.

De cualquier manera, volviendo a 1994, yo estaba combatiendo con villanos ficticios en la escena LPMUD. La Web apenas estaba presente, y la banda ancha era algo inaduito. El entretenimiento de bajo ancho de banda estaba a la orden del día.

Esperá. Demos un paso atrás. 1979. Mi primera computadora fue una Apple ][, y uno de mis juegos favoritos era Colossal Cave. Inmediatamente después, conocí y jugué Zork. Yo estaba enamorado del concepto de ficción interactiva y de como una computadora podía llevarte a través de esas historias. Esos juegos me engancharon, y me llevaron a una vida de computadoras. (Y si, ¡te podes imaginar la emoción de reunirme con Don Woods casi 25 años mas tarde!)

Por eso la escena MUD me intereso bastante. Pero yo quería ayudar a hacer esos juegos. Conocí a John Viega, un compañero creador de LPMUD, programador y diseñador. Al mismo tiempo, el estaba trabajando en el Laboratorio de Graficos por Computadora de la Universidad de Virgina, en un sistema llamado Alice. Este sistema estaba pensado para gente poco conocedora, y querian un lenguaje facil de aprender para crear animaciones. Elijieron Python por su claridad, poder y simplicidad.

John era un fanático tremendo, y me encamino a Python. "Tenes que aprender esto!" "Bueno, bueno" decía yo. El lenguaje era fácil, pero poderoso. Podía hacer de todo, sin mucho fastidio.

Era febrero de 1995, y no volví atras.

No sabía en ese momento cuan trascendental seria Python en mi carrera y en mi vida. Gracias, Guido, por tu creación.

Traducido por Joaquín Sorianello.

Revisado por Juan José Conti.

Si encontrás errores en esta traducción, por favor reportalos en un comentario y los corregiremos a la brevedad.

Todas las traducciones de esta serie pueden encontrarse en La historia de Python.


Cabañas Cayastá

El fin de semana mi familia estuvo de paseo en las Cabañas Cayastá. Yo iba a unirme desde el viernes, pero como estuve un poco enfermo solo pude pasar en las cabañas una sola una noche. Ya conocíamos el lugar, puesto que habíamos pasado un fin de semana allí hace dos años. Es un predio parquizado muy grande (5 hectareas) con 26 cabañas, salida al río y mucha infraestructura.

Las cabañas tiene hasta 6 camas, baño, aire acondicionado, 2 pisos, una cocina equipada con todos los cubiertos y trastos, heladera, mesa y sillas, parrillas y tele (alguien lo necesita?). Se puede cocinar en la cabaña, pedir comida a la habitación o comer en el comedor del lugar (los sábados a la noche suele haber Cena Show). A la tardecita te dejan en la puerta de la cabaña una canasta con el desayuno para el otro día.

El lugar está muy bueno para descansar, tiene muchas comodidades y se puede hacer de todo:

    <li> Pescar</li>
    
    <li> Cabalgar</li>
    
    <li> Andar en bicicleta</li>
    
    <li> Pileta</li>
    
    <li> Juegos (muy buenos para chicos, desde los típicos de plaza a otros como una casa en el árbol o un laberinto)</li>
    
    <li> Hacer asado</li>
    

    Está a unos minutos del pueblo (Cayastá), por lo que podés comprar ahí lo que te olvides, y a menos de 100 km de Santa Fe, por lo que llegás en una hora.

    También tengo entendido que se suele utilizar para organizar convenciones (tiene un salón para 300 personas).

    Dejo algunas fotos del lugar para entusiasmar:

    [gallery link="file" orderby="title"]


    Fotos del Paque Urquiza, Paraná

    El sábado después de almorzar nos juntamos algunos amigos y fuimos en auto hasta la vecina ciudad de Paraná. El plan fue tomar mates en el Parque Urquiza:

    El Parque Urquiza de Parana, orgullo de los paranaenses, es un extenso balcón al río, decorado con frondosa y colorida vegetación, curvas sinuosas, bajadas y subidas y una vista privilegiada.

    [gallery link="file" orderby="title"]

    Se extiende en 44 hectáreas y se escalona en tres alturas bien definidas: costanera alta, media y baja, unidas ellas por añosas escalinatas de piedras que surgen en medio de cascadas y vertientes, calles pavimentadas que permiten su recorrido en automóvil, senderos peatonales de exuberante vegetación, fuentes, parques infantiles, zonas para ejercicio aeróbico y numerosos monumentos y obras escultóricas. Dentro de la forestación las especies que se destacan son: álamo plateado, laureles de jardín, ciprés calvo, lapacho rosado, jacarandá, palo borracho, chañar, aromo, aguaribay, encina, ceibo, sauce, cedro, paraíso, tipa y pino.

    Fuente


    Charla: Taint Mode en Python

    Estas son los slides (más texto con el grueso de lo que dije) de mi charla en PyCon Argentina 2009. La misma se anunciaba como:

    Taint Mode es una característica implementada en algunos lenguajes con el objetivo de prevenir que usuarios malintencionados alteren entradas al sistema para lograr la ejecución de comandos no permitidos u otros tipos de ataques.

    En esta charla se introducen los conceptos básicos de Taint Mode y se discute la forma de implementarlo en Python mediante el uso de decoradores. Se muestra una implementación concreta y se analizan sus resultados.

    img0

    img1

    Cómo digo ahí, no soy un experto en seguridad aunque es un área que me interesa, sino me considero un desarrollador.

    Cómo desarrollador, muchas veces me encuentro dejando de lado la seguridad por cuestiones más apremiantes.

    Por hacer lo urgente, no hacemos lo importante.

    Entonces las fechas límite para entregas, las presiones por incorporar nuevas características, el pago solo por lo que se ve, hace que mucho software salga a la calle sin los más mínimos recaudos de seguridad.

    Esto trae consecuencias graves para muchas organizaciones y personas, como:

    • Robo o alteración de información
    • Bloqueos en la disponibilidad de un recurso
    • Suplantación de identidad

    Formas de mitigar este problema sin duda hay muchas. Una puede ser contar con herramientas que en tiempo de desarrollo permitan verificar la existencia de vulnerabilidades en el código escrito. ¿Qué vulnerabilidades? ¿Todas? Eso sería seguramente imposible. Pero existen herramientas que se especializan en distintos nichos: buffer overflow en C, XSS en PHP.

    Empecé a prestarle atención a este tipo de cosas cuestiones cuando empecé a participar de un grupo de investigación sobre seguridad en mi facultad. Yo me estaba postulando para obtener una beca de maestría y una de las condiciones era participar de un grupo de investigación.

    Así que empecé a buscar en Internet papers que relacionen cuestiones de  seguridad con Python, como una forma de encontrar algún tema que me interese y pueda profundizar.

    Encontré algunos papers de 2 investigadores de la Universidad Estatal de Moscú, Andrew Petukhov y Dimitry Kozlov en los que discutían cómo implementar Taint Mode en Python. Si bien su enfoque consistía en modificar el intérprete en C de Python para lograrlo, de su trabajo incorporé la mayoría de los conceptos que voy a mencionar en la primer parte de la charla. A diferencia de ellos, mi implementación de Taint Mode para Python está escrita totalmente en Python.

    img2

    img3

    El modelo de las manchas intenta describir cómo se comportan los valores que ingresan a un sistema desde el exterior y tiene 3 componentes fundamentales.

    FUENTES NO CONFIABLES, FUNCIONES LIMPIADORAS Y SUMIDEROS SENSIBLES.

    Todo valor que ingresa a un programa desde el exterior, es considerado por defecto como un valor manchado, ya que no sabemos de su procedencia. Decimos que viene de una fuente no confiable. Los valores recibidos desde el exterior pueden haber sido deliberadamente modificados para causar daño o simplemente por error causar un un problema dentro del sistema.Estas manchas se propagan por el programa mediante operaciones como la asignación o la concatenación.

    Las funciones limpiadoras representan los mecanismos que se pueden utilizar dentro de un programa para convertir un valor manchado en un limpio: escapando, codificando o incluso eliminando caracteres sospechosos.

    Los valores manchados no deben ser utilizados para: generar respuestas hacia los clientes o construir comandos a ser utilizados contra servicios externos, como los provistos por el sistema operativo, motores de bases de datos o el mismo intérprete. A estos componentes a los que no queremos que lleguen valores manchados, los denominamos "sumidero sensible".

    img4

    Si un valor manchado alcanza un sumidero sensible, entonces existe una vulnerabilidad en el programa.

    De esto se deduce que los valores manchados deben ser limpiados antes de que el flujo del programa los lleve hacia un sumidero sensible.

    Esto es correcto, pero debemos preguntarnos: ¿son todas las manchas iguales? ¿Una función limpiadora puede quitar todas las manchas de un valor? ¿Son todos los sumideros sensibles al mismo tipo de mancha? NO.

    • Un valor puede tener más de un tipo de mancha.
    • Una función limpiadora, por lo general, limpia un solo tipo de mancha.
    • Un sumidero es sensible a un solo tipo de mancha.

    Cuando un valor ingresa al programa, no sabemos que manchas tiene ¿Debe un desarrollador aplicar todas las funciones limpiadoras a cada valor que procede de una fuente no confiable? No toda función limpiadora es apropiada para procesar todos los valores manchados e incluso hacerlo consumiría recursos en forma innecesaria.

    Una mejor estrategia es, dado un tipo de mancha determinado, aplicar una función limpiadora de esta mancha solo a aquellos valores que alcanzarán un sumidero sensible a la mancha en cuestión.

    img5

    En concreto. Este valor está manchado con SQL Injection y no deberíamos dejar que forme parte de una sentencia que se va a ejecutar contra una base de datos. Pero, en principio, no habría problemas en que se use para renderizar una página que será devuelta al usuario.

    Algo similar sucede con este valor. Si bien está manchado para XSS. En principio no habría problemas en que se utilice para generar un comando a ejecutar contra el sistema operativo.

    img7

    img8

    Tres menciones sobre la implementación antes de ver ejemplos de uso.

    1) Existen 2 formas generales de implementar este tipo de análisis. De forma estática o de forma dinámica. Una implementación estática realiza la detección analizando el texto de un programa, sin ejecutarlo. Mientras que una implementación dinámica, analiza el coportamiento del programa. Esta es una implementación dinámica, por lo que va a requerir que el programa a evaluar sea ejecutado y utilizado: ejecutando manualmente casos de uso o corriendo tests automatizados.

    2) El uso de módulo requiere que sea importado dentro del programa a evaluar y hacer algunas modificaciones en el código fuente. Es intrusivo.

    3) La implementación se basa en el uso de decoradores. Existen decoradores para marcar dentro del programa los 3 tipos de elementos del modelo de las manchas: FUENTES NO CONFIABLES, FUNCIONES LIMPIADORAS Y SUMIDEROS SENSIBLES.

    img9

    img10

    Cada tipo de mancha con la que va a trabajar el módulo es identificada por un entero. En la lista KEYS que se ve en la pantalla, XSS es identificada con el 0, SQLI con el 1 y así. Esta lista de valores debe ser modificada si se quiere agregar nuevas vulnerabilidades para que sean reconocidas por la herramienta.

    TAINTED es la la estrucutura de datos dónde se lleva el registro de qué variables están manchadas. Es un diccionario dónde las claves son los enteros de la lista KEYS sus valores conjuntos, sets, inicialmente vacíos. Cuando se recibe un valor manchado del exterior, este es almacenado en todos los conjuntos, ya que por defecto tiene todas las manchas y a medida que se va limpiando, es eliminado del conjunto correspondiente.

    STR, en mayúsuculas, es una clase que envuelve a la clase str, en minúsculas, provista por Python. Ya que en Python los strings son inmutables, siempre que se procesa un string, por ejemplo cuando se obtiene un substring, se crea un nuevo objeto. Esta clase es necesaria para sobreescribir los métodos que generan un nuevo string y así hacer que la mancha perdure a lo largo del flujo del programa. Por ejemplo:

    img11

    Si a está manchada, y b está limpia. El string que se obtiene de concatenarlos, también está manchado. Lo mismo sucede con otras operaciones sobre strings: multiplicación, rebanada, formateo, métodos como upper que convierten el string a mayúsculas, o split que devuelve una lista de strings. Por ejemplo, si en este último caso 'a' sería un string de palabras separadas por coma, esta llamada al método split devolvería una lista de palabras y cada una estaría manchada.

    Los siguientes elementos a mostrar son los decoradores necesarios para que los elementos del programa manchen variables, las limpien o se alarmen.

    img12untrusted es un decorador utilizado para indicar que los valores retornados por una función o método no son confiables. Como los valores no confiables pueden contener potencialmente cualquier tipo de mancha, estos valores son marcados como manchados por todos los tipos de machas.

    Si se tiene acceso a la definición de la función o método, se puede utilizar la sintáxis provista por Python para aplicar el decorador.

    Al usar módulos de terceros, podemos aplicar de todas formas el decorador. Este ejemplo es de un programa que utiliza el framework web.py.

    img13

    Algunos frameworks funcionan de una forma diferente: le piden al programador que escriba cierta función o método de forma tal que luego el framework las utiliza para pasarle como parámetro al programa de usuario los valores recibidos desde el exterior. El framework para hacer aplicaciones de red, Twisted, provee un claro ejemplo  cuando se extiende la clase LineOnlyReceiver. Nos pide sobreescribir el método lineReceived, el cual se ejecutará cada vez que se recibe una cadena desde el exterior.

    En estos casos, utilizar el decorador untrusted es engorroso o incluso imposible. En su lugar se debe utilizar el decorador untrusted_args, que recibe 2 argumentos opcionales: una lista de posiciones de argumentos no confiables y una lista de argumentos de palabra clave.

    En el ejemplo se indica que el argumento de posición 1 no es confiable, y debe ser mancado como tal. Entonces cuando se ejecute el método, el valor recibido será manchado.

    Tanto para el decorador untrusted como untrusted_args, se utiliza la siguiente regla para marcar valores:

    1. Si el valor a manchar es un string, se utiliza para crear una instancia de STR y este objeto es guardado en TAINTED.
    2. Si el valor es una lista. Se aplica este algoritmo a todos los elementos de la lista y se retorna una nueva lista con el resultado de cada aplicación.
    3. Si el valor es un diccionario. Se aplica este algoritmo a todos los valores del diccionario y se retorna un nuevo diccionario con las claves originales y los resultados de cada aplicaicón como valores.

    img14

    Una vez que los valores manchados ingresan en el programa, fluirán a lo largo del mismo y en algún momento, puede ser que se encuentren con una función limpiadora como esta. texto_plano elimina las marcas html de un string.

    cleaner es un decorador utilizado para indicar que un método o función tiene la habilidad de limpiar manchas en un valor. Se debe indicar mediante un parámetro el tipo de mancha que la función es capás de limpiar. Como con los otros decoradores, tenemos dos formas de aplicarlo: dependiendo de si tenemos acceso o no a la definición de la función limpiadora.

    Funciona de la siguiente forma: si la función texto_plano decorada se aplica al primer ejemplo, nada cambia. Como el valor retornado es distinto al argumento, un proceso de limpieza fue llevado acabo. El valor argumento sigue en la estructura de datos TAINTED.

    En cambio, si es aplicada al segundo ejemplo, el valor argumento es igual al retornado, no se limpió nada por que no se requería limpiar nada. El valor original, presumido manchado, en realidad no estaba manchado (para XSS) y por eso es removido del conjunto correspondiente.

    img15

    Los últimos elementos a marcar en el programa son los sumideros sensibles.

    Se utiliza el decorador ssink para marcar aquellas funciones o métodos que no queremos sean alcanzadas por valores manchados.

    La función eval de Python es un típico ej. de sumidero sensible a ataques de Interpreter Injection, ya que interpreta ciegamente el string que recibe como  argumento.

    Supongamos q nuestro programa es una calculadora e implementamos la funcionalidad de sumar 2 números evaluando el string formado por: un primer valor recibido del exterior, el signo más y un segundo valor recibido desde el exterior. Si los valores no son apropiadamente validados, un atacante, utilizando nuestra calculadora, podría leer el contenido de archivos locales, borrarlos, colgar el programa o cualquier otra cosa que se pueda hacer desde el intérprete de Python.

    Aplicando el decorador a eval podemos detectar cuando esta función es utilizada con un valor no confiable como parámetro. Otra forma de lograr el mismo efecto en el ejemplo sería aplicando el decorador a la función suma en lugar de a eval.

    img16

    El segundo ejemplo también es tomado del framework web.py y marca como sumideros sensibles a SQL Injection los métodos delete, select e insert del objeto que accede a la base de datos.

    img17

    Con las fuentes inseguras, las funciones limpiadoras y los sumideros sensibles marcados en el programa, podemos ejecutarlo y utilizarlo para ir obteniendo las advertencias sobre posibles problemas de seguridad. Se pueden obtener mensajes de este tipo por la salida estándar, escribir en un archivo o daler cualquier otro destino.

    img18

    Algunas otras cosas que podemos encontrar con/en el módulo:

    • una batería de más de 80 tests que prueban su funcionalidad
    • la posibilidad de definir la función que se ejecutará cuando una variable manchada con X alcanza un sumidero sensible a X
    • la posibilidad de establecer una bandera que indique si la ejecución se debe cortar o no cuando una variable manchada con X alcanza un sumidero sensible a X
    • un nuevo decorador, validator, para marcar funciones que retornan un valor booleano indicando si una variable puede usarse o no
    • funciones auxiliares para manchar un valor o para testear si un valor está manchado

    img19

    Último slide de la charla. Todo lo que mostré hasta ahora es un experimento. Puede haber errores u omisiones, de hecho mientras lo fui desarrollando, al probarlo con aplicaciones reales encontraba errores en la implementación o situaciones en los que no podía aplicarlo, lo que me obligaba a darle una vuelta más de rosca a la implementación: así surgió por ejemplo el decorador untrusted_args.

    La pregunta ahora es cómo seguimos, y el objetivo de la charla era justamente presentar esta idea entre desarrolladores Python para continuarla en conjunto. Hay  muchas que podemos pensar, desde detalles de implementación hasta casos de uso que se pueden lograr, integración con frameworks de desarrollo para que alguien que se sienta a codificar un sistema tenga facilitada la aplicación de esta herramienta.

    Por ejemplo, para web.py sería relativamente sencillo crear un parche para que por defecto los valores recibidos estén manchados. En Django hice el ejercicio de escribir un middleware que haga ese trabajo. Y así, es necesario ir probando cómo se puede adaptar el módulo a herramientas de desarrollo ya conocidas.

    Hace poco cree una lista de correos en Google Groups para charlar estos temas, así que los que estén interesados en discutir al respecto y desarrollar esta herramienta, pueden suscribirse.

    img20

    img21


    Sorry por el SPAM

    Desde el viernes a la noche, cuando alguien recibía actualizaciones de mi blog vía Google Reader, obtenía un pedazo de SPAM en lugar de mis textos:

    Estoy trabajando para solucionarlo.


    Día del Ingeniero

    Ayer se celebró en Argentina el día del Ingeniero, coincidente con la fecha en que egresó el primer ingeniero de una universidad nacional.

    El Colegio de Ingenieros Especialistas celebró el día con un evento realizando en la sede de la Universidad Católica de Santa Fe. El acto tuvo un popurrí interesante; primero hablaron las autoridades y presentaron la segunda edición del libro Medioambiente y normas Ambientales, de los ingenieros María Belén Hammerly y Jorge Hammerly (padre e hija) con prólogo del ingeniero Carlos Mayol. Luego, el ingeniero Marcos Sales (eminencia a todo lo que es ingeniería de voladuras y otras áreas realacionadas y autor de dos libros de estudio) recibió un premdio a su trayectoria.

    El acto tuvo un corte para escuchar cantar al coro de la universidad (quienes están preparando un espectáculo sobre la naturaleza y el canto coral, por lo que presentaron un repertorio muy entretenido que incluía temas como La Puerca y Contrapunto Bestialle alla Mente).

    Finalmente, y casi cerrando el acto se entregaron diplomas de honor a los egresados con los mejores promedios de las carreras de Ingeniería de la ciudad (Felicitaciones Ceci!).

    Maxi Boscovich del LUGLi también recibió un premio. Esta es la foto con todos los homenajeados:

    Luego del acto, hubo un ágape o lunch muy lindo que duró hasta las 4 de la tarde.


    Motorizado

    Hoy lo manejé desde Pellegrini, ya lo tenemos en Santa Fe!



    Pan lactal

    Después de la Rosca de pascua, les presentamos más recetas de pradería. La razón es que compramos levadura en cantidad y para no tirarla preparamos recetas que uno generalmente no hace. Hoy: Pan lactal. Las fotos con las que ilustramos la preparación fueron tomadas por mi hermana con su celular mientras cocinaba (doble mérito!!).

    Ingredientes

    • Levadura fresca 30g
    • Azúcar 1 cucharada
    • Leche 150cc
    • Harina 0000 350g
    • Sal una pizca
    • Manteca 30g

    Preparación

    Primero formar el fermento. Incorporar a la harina en forma de corona la sal, la manteca pomada, el fermento y la leche:

    Formar una masa homogénea y lisa. Dejar levar el doble. Desgasificar. Estirar un rectángulo del largo del molde (tipo budín ingles):

    Enrrollar la masa y colocar en molde enmantecado y enharinado. Dejar levar. Pintar con huevo batido:

    Finalmente, hornear:

    Excelente para el desayuno!

    En la próxima receta, otra idea para aprovechar la levadura: Tortitas negras.