Cuatro Meses y Medio

Una actualización después de mucho: Como varios de los que me conocen en persona o de redes sociales saben, estoy viviendo en Buenos Aires hace un poco más de cuatro meses.

Cuesta dejar el lugarcito que uno se ganó, las comodidades, los amigos, la familia... arriesgar lo ya conquistado para así poder crecer aún más. Es cierto que en Encarnación tenía un buen trabajo, todo cerca y accesible, pero era lo mismo que ya tenía hace mucho y no estaba aprendiendo cosas nuevas. Y charlé con un amigo, me comentó de una oferta de trabajo, de ahí surgió una conversación por email, luego unas entrevistas. Y surgió una propuesta, y me jugué y me vine.

Si bien no tuve que aprender ningún idioma nuevo, me sigo adaptando a la cultura, al ambiente, a los códigos de un nuevo lugar y la forma de hacer las cosas que requiere una ciudad grande. Aprendí a moverme con transporte público, a saber que cualquier trámite puede llevarte la mitad de un día, a que todo está lejos, pero se sobrelleva bien cuando existe infraestructura y un mínimo de organización.

Luego del shock inicial de las primeras semanas, el simple hecho de estar expuesto a nuevos estímulos en un lugar donde requiere toda mi atención resulta una experiencia sumamente gratificante. Estoy trabajando en un proyecto muy diferente a todo lo que hice anteriormente en cualquier otro lugar. Estoy jugando con tecnología nueva, y también resulta que tengo compañeros de trabajo muy copados. Estoy aprendiendo técnicas en un área que siempre me resultó atrapante: todo lo relacionado a lenguajes de programación y análisis de código.

Empezar esta aventura está siendo una de las mejores decisiones que tomé en mi vida.

Why JavaScript is hard

This post is about JavaScript, the language (ie: not the DOM or anything related to quirks of a certain library or browser implementation).

JavaScript was dubbed a long time ago as the world's most misunderstood programming language. It somehows continues to be so for anyone trying to learn it in 2014. Why is that? For me, it all sums to these:

It's a functional language

This is a commonly overlooked feature of the language, also a beautiful one. In JavaScript, functions are first-class objects. That means that you can declare and manipulate functions almost like they were data, and by employing typical functional patterns in your code, you can create software that is both resilient and (most of the time) self explanatory.

At the most basic level, a functional language is one that lets you can declare functions that take other functions as parameters and return another function as a result, combining their behavior. Until you get acquainted with those patterns, there will be a lot of JS code that will seem hard to understand and reason about.

There are a lots of books one can resort to grok functional constructs, but I've found raganwald's JavaScript Allongé one of the most interesting ones. Plus, it's beautifully written, making it a joy to read.

It lacks namespaces

Code that isn't separated in several logical units gets messy fairly soon. Whenever you need to solve something bigger than a toy problem, you'll want to design software components in a way that allows reusing them later.

Using a proper namespace scheme will bring benefits like: performance (only load code that you actually need, saving time and memory), cleanness (don't reserve names for things you aren't using), organization (place your libraries in a specific directory scheme, and resolve their location from the required name, etc).

JavaScript does not bundle native support for namespaces, but it's highly dynamic nature won't stop you implementing them one way or another. A nice, simple example is https://github.com/maximebf/Namespace.js.

Has its share of design errors

A language that was designed in 10 days cannot be without its share of design mistakes. While some of them can be atributed to its dynamic nature, others are a more subtle overlook. Those traps include (but are not limited to):

  • Changes on the value of this inside a function, which depends on how you invoke it, something that can be worked around and also exploited to leverage several patterns.
  • Forgetting to use var when referring to a new variable declares global variables, bound as properties of the global object.
  • Using var in global scope pollutes the global object, so you'll need to create private closure scope with Immediately-invoked Function Expressions (IIFEs) in order to avoid this.
  • Using double-equals (==) to compare variables that may contain objects of different type. You shouldn't do it unless you're absolutely sure of what you do.
  • What undefined is and why you can't rely on it's value being compared to another variables, and how the void operator is useful here.

Implements prototypical inheritance

JavaScript's model of inheritance is frequently misunderstood. There isn't such a thing as a "class". Any function you declare can be used as a constructor (when called with the new keyword) and property lookups are done using the prototype chain of the object. Object "methods" are just properties of the object instance OR somewhere in its prototype chain.

A nice guide on how the prototype chain works is the one at Object Playground. There are also libraries you can use to implement a more typical class system, if that suits your fancy.

Has an asynchronous nature

While JavaScript is single-threaded, to do anything meaningful your app will resort to APIs which don't block the execution of the invoking code, but instead execute callbacks signaling the completion of tasks, whether on success or failure. Probably the most typical case is when doing network calls using some wrapper to XMLHttpRequest.

That's why the newbie JS programmer soon realizes that this won't work the way he wants it to:

function foo() {
  doAjax();
  createUI();
}

As a consequence of that, he'll probably begin to nest callbacks to make possibly-failing invocations chained as a series of steps, in the infamously named Pyramid of Doom:

/* shamelessly copied from https://github.com/kriskowal/q */
doAjax(function (value1) {
    step2(value1, function(value2) {
        step3(value2, function(value3) {
            step4(value3, function(value4) {
                // Do something with value4
            });
        });
    });
});

Not only quirky, but also obscures the flow and the intent of the code, and gets a lot messier if you try to make anything more interesting, like executing some code regardless of the failure of any step.

This is where things like Deferred and Promises are helpful. Make yourself a favor and learn to use them properly.

Idioms are everywhere

The dynamic nature of JavaScript's expression evaluation is frequently exploited to write clever code that may confuse junior programmers who probably won't grok them on a first sight. Some of them exploit the notion that variables on JavaScript have an implicit value of being either truthy or falsy. Examples follow:

  • Double negation (!!) used to coerce variables to booleans. Use it to return true on truthy values, and false otherwise.
  • The double bitwise not (~~) trick that can be used to perform floor on positive numbers.
  • The reference || [] idiom, used to have a valid empty list/object whenever the first variable is indeed falsy.
  • The property-testing chain idiom, to test for a truthy property in a safe way, such as if (obj && obj.prop && obj.prop.method)

While this doesn't try to be a comprehensive list, I've found these particular issues the most important ones to master on the road to improve my understanding of JS code, something that will be useful regardless of the browser you use, and whether your code is client or server-side.

Hackeo a NIC.PY

Sorry, this post is spanish only.

En la tarde de hoy jueves, un compañero de trabajo me comenta que la página principal del sitio www.google.com.py fue modificada. Descartando algún problema con Google en sí (en donde trabajan algunos de los mejores expertos en seguridad del mundo), mi primer sospecha fue que el servicio DNS a nivel Paraguay fue comprometido. Lo cual es evidente siguiendo el enlace a la página de los "hackers" iraníes, que relata el detalle del ataque realizado: http://ha.cker.ir/2014/02/www-nic-py-py-registrar-rce-vulnerablity/.

DN... ¿qué?

El sistema de DNS (Domain Name System o Sistema de Nombres de Dominio) es un componente crucial en el funcionamiento de Internet. Su tarea principal es la de poder traducir nombres legibles para seres humanos, como google.com, www.mibanco.com.py, etc, en direcciones numéricas de cuatro números separados por puntos, como 201.217.0.176 o 201.217.19.9.

Estos números tienen por nombre "dirección IP" y sirven para que una máquina pueda establecer una conexión con otra dentro de Internet. Básicamente, cada equipo conectado a la red tiene asignado una dirección IP. Cuando una computadora (de escritorio, tablet o celular) desea acceder a un sitio web por su nombre, si o si debe realizar una consulta DNS para convertir el nombre consultado en una dirección IP.

¿Y cómo me afectaría algo así?

La clave para entender la gravedad de lo que ocurrió, es que el sistema DNS funciona de manera jerárquica. La jerarquía comienza por los Servidores Raíz DNS, que delegan la respuesta de consultas por sitios con la terminación '.py', a los servidores DNS de NIC.PY, que pueden responder con autoridad por CUALQUIER sitio que termine en .PY. Esto hace posible que alguien que llegue a tener acceso a NIC.PY, pueda alterar a qué servidor físico se accede cuando se ingresa una dirección cualquiera que termine en .PY, simplemente respondiendo con una dirección IP diferente a la auténtica, para una determinada consulta.

Esto permitiría a un atacante realizar una copia de un sitio web de algún banco local y alojarlo en un servidor de su propiedad que automáticamente almacene las credenciales para los usuarios que intenten acceder a la banca web del mismo. Un usuario no técnico difícilmente tenga posibilidad de darse cuenta de que no está accediendo al sitio que desea, ya que la barra de direcciones del browser mostraría una dirección correcta. Lo del banco es sólo un ejemplo, pero practicamente cualquier sitio con la terminación .PY puede verse afectado por un ataque así.

Esto es alarmante, no sólo por el abanico de posibilidades que abre el ataque que se realizó, sino por lo relativamente sencillo que les fue a los atacantes realizar las alteraciones de dominio, evidenciados en los siguientes motivos:

Técnicamente hablando, el servidor de NIC.PY:

  1. Usa un Sistema Operativo muy desactualizado. Día a día se descubren errores en muchos componentes de software que forman parte de un servidor, desde el componente principal (kernel) del sistema operativo, y varios de los componentes que brindan servicios de red, como por ejemplo, la posibilidad de servir páginas Web. El sitio de los "hackers" mostraba claramente que varios de los componentes del servidor de NIC.PY no habían sido actualizados desde 2010.
  2. Utiliza una aplicación web vulnerable a ejecución remota de código. Esto significa que una persona, virtualmente desde cualquier parte del mundo, puede enviar una combinación especial de texto a la web del NIC.PY usando únicamente su navegador web, con lo cual se pueden ejecutar comandos que resulten en exposición de información confidencial del equipo de NIC.PY, alteración de datos, destrucción de información, y un sinnúmero de actos que ponen en riesgo el funcionamiento correcto de los servicios que brinda.
  3. No poseía un esquema mínimo de hardening. Se llama "hardening" a una práctica correspondiente a ocultar información de los servicios que se ejecutan en un servidor, y en el caso de una intrusión, dificultar que el atacante pueda lograr privilegios que le permitan alterar información en el equipo atacado. Por la facilidad con la que los intrusos detallan su ataque, nada de eso fue realizado.

A todos estos factores, hay que sumar a que ya fueron explotados previamente (al menos 5 años atrás!), y nuevamente en el 2012, sin siquiera tomarse la molestia de 'limpiar' el equipo de los rastros de ataque. Y que varias de las falencias técnicas comentadas aquí ya fueron expuestas en ocasiones previas: http://ticpy.blogspot.com/2008/11/el-cnc-y-una-nueva-negligencia_4917.html.

Para un país con una brecha digital inmensa, con deficiencias de infraestructura enormes en los servicios más básicos, esto constituye una muestra más de la desidia y falta de capacidad de quienes nos gobiernan, que con su inacción no solamente nos siguen sumiendo en el atraso, sino que también ponen en riesgo nuestras actividades diarias.

A self contained SQL parser/pretty printer

For a great part of the day, I work as an backend developer, dealing with writing and reviewing all kinds of SQL to move data in commercial(a.k.a. enterprise) applications. For that purpose, using a tool that formats SQL statements is essential, in order to keep your code as neat as possible and easier to mantain.

I've used some commercial and freemium applications such as SQLInform, and also sites like http://sqlformat.org/ and http://www.dpriver.com/pp/sqlformat.htm from time to time. But always felt that there is no need to use this kind of "heavy" applications for something that could be done entirely in JavaScript, self-contained, and possibly, evolving through Open Source.

So I ended up writing a simple SQL formatter/pretty printer that works in a browser, with no need for server-side processing.

You can find it here: http://codespeak.cc/sequeljs

Working entirely on the browser, SequelJS has the additional benefit that developers aren't forced to disclose details of schema design or business issues to third parties, because there isn't any data transferred through the ether when formatting statements.

Currently, the formatter still lacks important features (like parsing comments or establishing a max line width), but can handle an nice subset of SELECT queries, with joins, subquerys, expressions, function calls, etc. The current style of indentation is just what I'm accustomed to, but is something that will be possible to tune in future releases.

When building a program to process SQL statements, it's important to settle on which set of possible statements are accepted as valid, and also recognize their structure. In compilers jargon, this is called a grammar.

Some SQL grammars can get tough quickly. Parsing real-life SQL statements (like PostgreSQL/MSSQL ones) —even if only to format them— is a difficult task. So I started from scratch, using the H2 SQL grammar as a foundation, which I believe is a really nice basis for a design that can be evolved organically.

SequelJS uses the great Jison library, which is a JavaScript port of the Bison LALR parser. Color formatting is done with the prettify library.

I plan to keep adding new features in the following days. If you want to contribute, feel free to fork the project on GitHub.