Personal tools
Security through obscurity: come offuscare id interi in Python

Security through obscurity

Jul 22, 2013

Security through obscurity: come offuscare id interi in Python

Vi presento opaque-id, una libreria Pythonica snella, potente ed efficiente disegnata per nascondere gli id di una base di dati negli URL

Mi sono trovato a dover affrontare un caso d'uso abbastanza ricorrente: generare un URL che consenta l'accesso alle righe di una base di dati relazionale la cui chiave primaria è un numero intero, senza che sia evidente come accedere alle altre righe del database.

Questo caso d'uso è analogo a quello di bit.ly, TinyURL, goo.gl o simili.

Il problema

Supponiamo di appoggiarci a una base di dati che contiene una tabella fatta così:

id | url
---+----------------
 1 | http://blog.redturtle.it
 2 | http://www.redturtle.it

Se servissimo un URL del tipo http://nohost.com/1, dove “1” è la chiave primaria (id) della riga, sarebbe veramente semplice ricostruire il contenuto della tabella andando a cambiare la parte finale dell’indirizzo.

Se per voi questo rappresenta un problema, quello che vi serve è un URL "meno chiacchierone": bit.ly proporrebbe http://bit.ly/1bqZRgn.

La soluzione

Con la libreria opaque-id sono riuscito a replicare un comportamento simile.

Grazie ad essa è possibile trasformare un numero intero in una stringa che apparentemente non ha senso, ma:

  1. nasconde il numero originale
  2. impedisce di prevedere l’URL che corrisponde ad altri id
  3. è generata con un algoritmo reversibile: data la stringa riusciamo a recuperare l’intero.

Fatto!

Nonostante la base di codice sia a malapena una ventina di righe, opaque-id è estremamente efficace nel conseguire gli scopi per cui è stata disegnata.

Ci sono metodi alternativi, magari più veloci o più sicuri per ottenere lo stesso risultato.

Ad esempio, si possono utilizzare interi offuscati come chiave primaria del dato, ma questo intervento potrebbe richiedere un lavoro non banale.

Oppure si possono utilizzare algoritmi di cifratura più robusti a spese della velocità computazionale e della compattezza degli URL.

Bonus tracks

Sei interessato a vedere quanto è comodo e pratico usare questa libreria? Prenditi due minuti di orologio e fai come me!

[ale@padme ~]$ cd /tmp
[ale@padme /tmp]$ wget https://raw.github.com/marekweb/opaque-id/master/opaque.py
[ale@padme /tmp]$ python -i opaque.py 
>>> # Inventiamoci una chiave che dobbiamo tenere segreta
>>> # La chiave deve essere un numero intero 
>>> # (0x mi dice che è un numero esadecimale)
>>> key = 0x12345678
>>> # Instanziamo un oggetto OpaqueEncoder
>>> # usando questa chiave
>>> encoder = OpaqueEncoder(key)
>>> # Facciamo qualche prova di offuscamento
>>> encoder.encode_base64(1)
'wzDTfA'
>>> # Senza conoscere la chiave è impossibile prevedere 
>>> # quale stringa corrisponderà al numero 2
>>> encoder.encode_base64(2)
'Qmr9vA'
>>> # Ovviamente possiamo riottenere il numero originale
>>> encoder.decode_base64('wzDTfA')
1L
>>> # Se cambiamo un carattere nella stringa
>>> # ad esempio la prima ‘w’ la mettiamo maiuscola
>>> # il risultato è completamente differente
>>> encoder.decode_base64('WzDTfA')
2600507393L
>>> # Cambiando la chiave i risultati ottenuti 
>>> # sono totalmente differenti
>>> new_encoder = OpaqueEncoder(42)
>>> new_encoder.encode_base64(1)
'F.kNSQ'
>>> new_encoder.decode_base64('wzDTfA')
1242706180L

Credits

Siete arrivati fino a qui? Allora vi siete meritati qualche risata!

Filed under: , ,
comments powered by Disqus