Algunas estructuras de datos y algoritmos usados en casos reales

Tricas Invaders... En estos tiempos la palabra algoritmo cotiza a la baja: se ha asimilado a decisiones que toma una máquina por nosotros con poca transparencia (ese tufo anti-tecnológico permamente que padecemos). Sin embargo, tan algoritmos es el de la suma como esos otros ‘malvados’. En las clases de algoritmia se explican estrutcturas de datos y algoritmos a los que no siempre se les ve sentido (aunque siempre recordaré a un estudiante que ya tenía su startup y todo y cómo estas clases le abrieron un poco los ojos a lo que era pensar los programas, más allá de resolver su problema). En Data Structures & Algorithms I Used Working at Tech Companies nos habla Gergely Orosz de este tema: estructuras de datos y algoritmos que realmente ha utilizado en empresas tecnológicas.

Habla de los árboles y su recorrido (Trees and tree traversing) que utilizó en Skype y en Uber, por ejemplo. Fundamentalmete, parece, para temas de navegación.

Trees and tree traversing: Skype, Uber and UI frameworks

Grafos con pesos y caminos mínimos (Weighed graphs and shortest paths) en Skyscanner. Al tener que calcular precios de rutas que pasan por distintas ciudades el problema se resulve como un camino mínimo a través de un grafo.

Multi-city was one of the features that took Skyscanner quite a bit of time to build - in all fairness, the difficulty was more on the product side, than anything. The best multi-city deals are calculated by using shortest path algorithms …

Ordenación en Skype. Tenemos una lista de contactos, que además pueden llegar en lotes.

One of the other engineers decided to implement an insertion sort for listing contacts. In 2013, when Skype connected to the network, contacts would arrive in bursts, and it would take some time for all the contacts to arrive. So this engineer thought it’s more performant to build the contact list organized by name, using insertion sort.

Diccionarios (Hashtables and hashing) en muchos sitios. Muy útiles para contar, detectar duplicados…

The most frequent data structure I’ve used regularly was hashtables and the hashing function. It’s such a handy tool from counting, to detecting duplications, to caching, all the way to distributed systems use cases like sharding. After arrays, it’s easily the most common data structure

Pilas y colas (Stacks and queues), de vez en cuando. Se trata de buenas herramientas auxiliares.

Criptografía en Uber. Los usuarios siempre nos proporcionan información que puede ser delicada y que hay que tratar adecuadamente.

User-entered sensitive information coming from mobile or web clients needs to be encrypted before sending through the network, only to be decrypted on a specific service. To do so, a crypto approach needs to be implemented on the client and the backend.

Árboles de decisión en Uber. Cuando nuestra aplicación se hace más compleja, puede ser necesario elegir qué mostrar en función de algunas reglas.

On one of the projects, we had to implement complex business logic in the mobile application. Based on half a dozen rules, we had to display one of several different screens

Mallas hexagonales e índices jerárquicos, también en Uber. Hay que optimizar los precios de los viajes, y el envío de coches, que es algo que se puede resolver con mallas hexagonales y la adecuada jerarquización.

The data - and visualization - structure for this is a hexagonal grid with hierarchical indexes, and a couple of internal visualization tools are built on top of it.

Interesante.

Probando forestry.io

Papeleo. Actualización (2021-02-22): Faltaba una prueba y era editar como texto una entrada para ver qué sucedía. Le hemos añadido la foto de rigor para respetar la homogeneidad del sitio. Este sitio está gestionado con jekyll y GitHub pages. Trabajar con ficheros de texto y git me resulta cómodo. Para otros proyectos he echado de menos un montaje similar pero que también tenga interfaz web.

Decía yo en Twitter:

  • Necesitamos algo como Google Docs pero con markdown o similar.
  • La idea sería poder editar en local o en la web según convenga y tenerlo siempre disponible. Las piezas las tenemos:
    • Markdown como lenguaje de escritura. Puede generar diversos formatos de salida/presentación.
    • git para gestionar la evolución de la información y asegurarnos de que la tenemos bien (actualizada) en donde la usemos.
    • Interfaz web para editar en línea cuando convenga. Tenemos GitHub, gitlab (creo) y otras interfaces que lo permitían pero no están pensadas para eso.

¿Alguien conoce un editor web de texto que pudiera servir? Hace falta que:

  • Genere texto plano (aceptamos WYSIWYG, pero ‘debajo’ hay texto)
  • Permita manejar estos textos con algún API.

He recibido dos respuestas:

Pues eso, he importado el sitio desde GitHub, y me he puesto a editar esta entrada con el móvil.

Estoy impresionado, a falta de darle al botón de publicar.

SSH Agent y las sesiones

Semana Santa. Moto de la policía. Ya nos hemos acostumbrado a utilizar ssh, pero siempre vienen bien entradas como esta que nos explican un poco el entorno: SSH Agent Explained. El SSH Agent es, nos dicen, un gestor de claves para SSH. Está ejecutándose, almacena nuestras claves y nos ahorra teclear la contraseña de acceso cada vez.

ssh-agent is a key manager for SSH. It holds your keys and certificates in memory, unencrypted, and ready for use by ssh. It saves you from typing a passphrase every time you connect to a server. It runs in the background on your system, separately from ssh, and it usually starts up the first time you run ssh after a reboot.

Proteger nuestras APIs de ataques de CSRF

Príncipe Felipe. Engaño visual El ataque de Cross Site Request Forgery (CSRF) consiste en engañar al usuario para que pinche en un enlace que provoca alguna acción en nuestro sitio (de ahí la idea de ataque cruzado). Es un fallo que se puede aprovechar cuando nuestra aplicación web no verifica que las peticiones vienen de donde deben.

The basic idea behind a CSRF attack is this; you have a user that uses their browser to login to your website (let’s say “awesomebank.com” as an example). Now that same user uses the same browser to visit a malicious website, and that malicious website sends a request to your website. In certain cases, the browser will send cookies for your website along with that request, even though it came from the malicious website. From your server’s perspective, you get an API call from an authenticated user, so you’ll probably end up doing what the malicious site wants you to do.

En Avoiding CSRF Attacks with API Design se refieren a un caso particular y es el de las APIs.

Los sitios web van teniendo protecciones y los navegadores también ayudan pero, aún así, hay algunas precauciones que podemos tomar.

La primera, no utilizar GET para modificar estados. Esto es, en general, una mmala idea, pero desde el punto de vista de seguridad puede ser muy grave. Bastaría que alguien cargue una imagen con el enlace (o intente cargar) y se ejecutaría la acción.

Fortunately, it’s easy to avoid this; just don’t let GET requests modify state.

Utilizar `tokens’ anti-CSRF.

Cuando le enviamos un formulario a alguien generamos un identificador y lo guardamos con la sesión. Cuando nos responden, lo que venga tiene que llevar el identificador y nosotros verificamos que coincide con el generado antes de ejecutar la acción.

One way to secure yourself here is to use something called a CSRF token. The basic idea is to generate a random token and store it in your user session, then make it so the CSRF token is either submitted by forms in a hidden field or added as an extra “x-csrf-token” header in each API call. Server side, you can check to make sure the CSRF token matches the one stored in the session. Since it should be impossible for an attacker to get the CSRF token (the same origin policy does protect javascript from reading the contents of a response) it makes it much more difficult for an attacker.

Un problema de estos tokens es cuando la interacción no se realiza con un navegador, y habrá que contemplar este caso si es necesario. O, si confiamos en este tipo de interacciones (al fin y al cabo, ya no es tan sencillo que un usuario reciba estas peticiones) incluir las excepciones adecuadas (pero mejor tenerlo en cuenta y no bajar la guardia).

There are a few ways around this. First, note that really only POST requests with a content-type of “application/x-www-form-urlencoded”, “multipart/form-data”, or “text/plain” need a CSRF token, because of the same origin policy. So you could not require a CSRF token for posts with a content-type of “application/json” (although some would caution against relying on content-type as your only layer of protection against CSRF). Also, if you are using this strategy, pay special attention to endpoints which do not require a body.

Comprobar la cabecera de origen. ¿Desde dónde nos puede llegar una petición?

To protect against this; if you do need to allow cross-domain requests, instead of allowing access to “*”, pick a whitelist of origins that are allowed to access your API and only allow those in.

Escribir casos de prueba negativos. Esto es, incluir en nuestras pruebas intentos maliciosos y verificar que generan los errores adecuados.

Write some test cases that try sending an OPTIONS request to your API with an `origin: evilcorp.com” header, and make sure you get back an error, or at least don’t get back an “Access-Control-Allow-Origin” header. Try sending data encoded as “application/x-www-form-urlencoded” to an endpoint that is expecting “application/json” (or to an endpoint that doesn’t expect a body) and make sure this fails.

Utilizar la política de cookies del mismo sitio. Esto es, si la petición viene del sitio incorrecto, ¿para qué le vamos a enviar las cookies?

One thing you might be wondering - when evilcorp.com sends a request to awesomebank.com, why are the awesomebank.com cookies being sent at all? Doesn’t this seem very insecure by design? Well, there’s a relatively new standard called “SameSite” cookies which will stop those cookies from being sent.

Finalmente, cuando vayamos a realizar operaciones destructivas o delicadas podemos solicitar una nueva autentificación. Si la contraseña es necesaria, el enlace con el ataque CSRF no funcionará.

If you have an especially destructive operation, such as deleting an account or sending all of your money to the Cayman Islands, consider requiring your user to re-authenticate. If the password is a required field in the request, then a CSRF attack can’t succeed, since the attacking website has no way of knowing the user’s password.

Cadenas de caracteres que pueden ser peligrosas

Palabras

Una de las cosas en las que no solemos fijarnos son los datos que pueden recibir como entrada nuestros programas. En algunos casos esto puede suponer una molestia, y en otros un auténtico peligro. Para ayudarnos con ello podemos echar un vistazo a Big List of Naughty Strings que justanmente nos proporciona una lista de cadenas que pueden ser delicadas como datos de entrada:

The Big List of Naughty Strings is an evolving list of strings which have a high probability of causing issues when used as user-input data.

Se proporcionan como un fichero de texto, y también algunas implementaciones en diferentes lenguajes para facilitar la realización de pruebas automatizadas.