NoSQL Injection (NoSQLi): Cómo funcionan y cómo defenderte

NoSQL Injection (NoSQLi): Com funcionen i com defensar-te

Celia Catalán



Injeccions NoSQL (NoSQLi)

Les bases de dades NoSQL són sistemes d'emmagatzematge de dades dissenyats amb l'objectiu de gestionar grans volums d'informació no estructurada (o semiestructurada), a diferència de la informació que gestionen les bases de dades relacionals del model tradicional (SQL o Structured Query Language).

Tipus de bases de dades NoSQL més emprades

D'acord amb les diferents utilitats de la informació, es classifiquen les bases de dades en:

  • Bases de dades de Documents: La informació s'emmagatzema en forma de documents JSON -JavaScript Object Notation, un format lleuger de serialització i intercanvi de dades- o BSON -Binary JSON, format JSON binari, codificat en binari en comptes de en format text, com el primer). En aquesta categoria, destacarien CouchDB (JSON) o MongoDB (BSON).
  • Bases de dades clau-valor: Les dades s'emmagatzemen com a parells de clau-valor. En aquest sentit, són referents Redis o DynamoDB.
  • Bases de dades de grafos: Es caracteritzen perquè la informació s'empra per prioritzar el modelatge de relacions entre les dades. Les més emprades per a aquest tipus són Neo4j o ArangoDB.
  • Bases de dades en format de columnes: Es prioritza l'emmagatzematge de la informació en format de columnes. Exemples d'aquest tipus serien Apache Cassandra o HBase.

Què és la injecció NoSQL (NoSQLi)?

Una injecció de tipus NoSQL, ocorre quan un atacant manipula consultes de tipus NoSQL, aprofitant-se d'una incorrecta validació de les entrades o paràmetres d'usuari, permetent així l'execució de sentències no desitjades, diferents de les específiques per a les quals s'ha creat la funcionalitat explotada, igual que passava amb les injeccions de tipus SQL. La diferència principal amb aquest tipus d'estructures típiques de models relacionals rau en què aquí no es treballarà amb estructures de taules organitzades en files i columnes, com s'ha vist en l'apartat anterior, ni amb el llenguatge SQL, sinó amb llenguatges específics de cada sistema de gestió NoSQL (JSON, BSON, CQL, etc.). Generalment s'interactuarà amb formats diferents, generalment mitjançant l'ús de consultes dinàmiques, menys rígides, que permetin manipular la informació amb l'obtenció d'explotar la vulnerabilitat present a l'aplicació.

Exemples d'atacs NoSQLi en diferents SGBD NoSQL

A continuació, s'analitzaran possibles escenaris d'explotació típics depenent de les diferents configuracions en els Sistemes de Gestió de Bases de Dades o gestors de bases de dades NoSQL emprats.

1. MongoDB

MongoDB utilitza JSON per realitzar consultes. En emmagatzemar el document JSON es convertirà al seu format BSON (binari) corresponent. Una consulta típica per verificar credencials podria ser:

db.users.find({ username: "admin", password: "Passw0rd!"});

Atac bàsic

Si l'entrada no està sanititzada, un atacant podria enviar:

{ "username": { "$ne": null }, "password": { "$ne": null } }

Això genera la consulta:

db.users.find({ username: { $ne: null }, password: { $ne: null } })

Així doncs, el resultat ometrà la validació de credencials i l'atacant obtindrà accés al sistema, de manera similar a com es podria evadir amb un SQLi tradicional els mecanismes d'autenticació d'un formulari amb la injecció clàssica ' OR 1=1 -- o similar.

Cal tenir en compte que si s'utilitzés db.users.findOne recuperaria el primer usuari de la base de dades, que generalment sol ser l'administrador.

2. Redis

Redis és una base de dades clau-valor que permet comandes com GET i SET. Un atac típic podria involucrar la manipulació de claus per obtenir informació diferent de la que es pretén recuperar.

Suposem que una aplicació consulta claus amb:

GET usuari:administrador

Atac bàsic

Un atacant podria injectar:

GET usuari:*

Mitjançant l'ús del comodí o wildcard '*' es tornaran totes les claus que coincideixin amb el patró i, per tant, enumerar tots els usuaris de l'aplicació.

3. Apache Cassandra

Cassandra utilitza CQL (Cassandra Query Language), similar a SQL, però adaptat al seu model de columnes. És per això que potser els atacs NoSQLi relacionats amb aquest sistema de consultes recorden més al tradicional SQLi que la resta dels analitzats en aquest post.

Una consulta típica per buscar usuaris pot ser:

SELECT * FROM users WHERE username = 'admin' AND password = 'Passw0rd!';

Atac bàsic

D'aquesta forma, un atacant podria injectar:

' O '1'='1

 El que generaria:

SELECT * FROM users WHERE username = '**' OR '1'='1**' AND password = ''

... accedint d'aquesta manera a tots els usuaris del sistema.

4. Neo4j

Neo4j utilitza Cypher com a llenguatge de consulta. Una consulta típica per buscar nodes podria ser:

MATCH (u:User {username: 'admin', password: 'Passw0rd!'}) RETURN u;

Atac bàsic

Un atacant podria injectar:

MATCH (u) RETURN u //

... i, en conseqüència, es podrien tornar tots els nodes de la base de dades.

Tècniques d'ofuscació i evasió

Els sistemes de detecció com WAF (Web Application Firewall) solen bloquejar patrons comuns d'injecció. No obstant això, els atacants poden utilitzar tècniques avançades per evadir-los, tal com ja es va veure en els atacs de SQLi, i altres tipus d'injeccions. De manera anàloga a les bases de dades SQL, però aplicat a aquest tipus de bases de dades, es poden emprar les següents tècniques:

1. Codificació

Codificar els caràcters especials pot ajudar a evitar que els WAF detectin patrons sospitosos.

Codificació hexadecimal

Convertir caràcters a la seva representació en hexadecimal:

{ "$ne": null } → %7B%20%22%24ne%22%3A%20null%20%7D


Codificació Base64

Codificar el payload complet en base64 (i decodificar després al client):

{ "$ne": null } → eyAiJG5lIjogbnVsbCB9Cg==

2. Comentaris

Aquesta tècnica consisteix a inserir comentaris per evitar regles de detecció. Per exemple, a Neo4j, es pot injectar el codi vist abans per recuperar tots els usuaris, però inserint prèviament un comentari:

MATCH /* loquesea */ (u) RETURN u

3. Concatenació

Emprant la concatenació (+), igual que passava amb l'evasió en SQLi, es poden fragmentar cadenes per separar el payload i així evitar deteccions directes. Per exemple, en el cas de MongoDB:

{ "username": { "$n" + "e": null } }

4. Ús de caràcters de control o espais Unicode (caràcters invisibles)

A vegades l'ús de certs caràcters que no modifiquen realment la consulta, poden emprar-se en les injeccions per trencar els patrons de detecció dels WAF. Per exemple, en el cas vist per Redis, incorporar abans de l'ús del comodí (*) el caràcter Unicode equivalent a "espai d'ample zero" (caràcter unicode 200B).

OBTENIR usuari:\\u200B*

Mesures de prevenció

1. Validació i sanejament

Utilització de validacions estrictes al costat del servidor.

Rebuig de caràcters especials o estructures no esperades per a la realització de la funcionalitat específica. Millor fer-ho acotant pels valors desitjats que s'espera rebre que per valors més "oberts" que puguin ser aprofitats per un atacant o funcions d'escapament que puguin ser incompletes. En aquest últim cas, i si fos necessari, emprar l'ús de biblioteques i funcionalitats preexistents. Sempre s'ha de buscar "no reinventar la roda" en aquest sentit.

2. Ús de biblioteques segures

Establir l'ús d'operadors segurs. Per exemple, emprar $eq, a MongoDB:

db.users.find({ username: { $eq: "admin" }, password: { $eq: "Passw0rd!" } });

D'aquesta manera s'evitaria la construcció de consultes dinàmiques, massa "obertes". Caldria tenir això en compte també per aquells casos on s'empren expressions regulars.

3. Principi de Mínims Privilegis o limitació dels permisos de l'usuari.

Sempre es recomana limitar els permisos de l'usuari empleat per accedir únicament a la informació a la qual li és necessari accedir i a cap altra, estant limitat a l'àmbit de la base de dades en qüestió.

4. Ús de WAF (Web Application Firewall)

S'hauria d'emprar el WAF per bloquejar patrons específics de NoSQLi, però sense oblidar mai de seguir bones pràctiques de desenvolupament segur per evitar que l'evasió d'aquests patrons pugui derivar en un atac exitós contra l'aplicació. 

Conclusió

En considerar les bases de dades NoSQL per l'avantatge competitiu que ofereixen pel que fa a flexibilitat, escalabilitat i gestió de grans volums d'informació, també s'obre la porta a noves superfícies d'atac, amb mètodes similars als tradicionals SQLi, com és el cas de les NoSQLi. A diferència d'aquests atacs tradicionals, aquí s'aprofita la naturalesa no estructurada de la informació, generalment mitjançant la manipulació dels fitxers JSON/BSON associats.

És fonamental que, tant els desenvolupadors com els administradors de sistemes i els administradors de bases de dades, realitzin un enfocament de seguretat multicapa, que passi des d'una correcta validació i sanejament dels paràmetres d'entrada (adaptat als nous sistemes de gestió emprats), l'ús de biblioteques segures i una configuració adequada (i limitada) pel que fa al sistema i els permisos emprats.

A més, la compressió de les tècniques d'evasió utilitzades pels atacants, i la realització de proves periòdiques de seguretat poden ajudar a millorar les defenses contra aquest tipus de amenaça.

Per últim, tot i que NoSQLi comparteix similituds amb SQLi, les diferències entre els llenguatges i estructures NoSQL emprats requeriran enfocaments diferents i únics per assegurar aquests sistemes davant de diferents atacs.

Roberto Trigo, Consultor de ciberseguretat a Zerolynx.

Tornar al bloc

Deixa un comentari

Tingueu en compte que els comentaris s'han d'aprovar abans que es publiquin.