vendredi 28 août 2009

Postgresql Full Text Search - Planquez ces chiffres!

Admettons que l'on veuille sauver des textes cryptés dans la colonne d'une table Postgresql. Rien de plus facile en utilisant les fonctions pgp_sym_encrypt et pgp_sym_decrypt. Jusque là, tout va bien.

Mais admettons maintenant que l'on veuille également pouvoir faire des recherches rapides sur ces textes en utilisant le Full Text Search. L'on rajoute une colonne de type tsvector, et l'on parse le texte là dedans. Patatras, votre vilain espion peut maintenant recréer le document en regardant ce champ, qui, lui, ne peut pas être crypté!

L'on peut bien sûr monter ses données sur une partition cryptée. Mais c'est compliqué, et pas facile à installer chez l'utilisateur, sans compter que tout est en clair tant que la machine est allumée.

Cependant, admettons encore (ça fait beaucoup, je sais!) que les données sensibles soient plutôt des nombres (codes secrets, identification, numéros de compte, sommes d'argent). Sans ces nombres, les documents deviennent plutôt inoffensifs. Et de plus, il est peu probable que l'on aie besoin de ces nombres pour faire des recherches. C'est parfois utile, certes ("quels sont les documents qui contiennent mon numéro de compte?"), mais on pourra s'en passer.

Ça tombe bien, il est possible de créer une nouvelle configuration qui escamotera ce genre de données. Il suffit d'enlever la correspondance entre les types de tokens et le parseur.

Ajoutons donc la configuration french_safe:

create text search configuration french_safe ( copy = pg_catalog.french );
alter text search configuration french_safe drop mapping for int;
alter text search configuration french_safe drop mapping for uint;
alter text search configuration french_safe drop mapping for float;
alter text search configuration french_safe drop mapping for numword;

Alors que de la configuration de base, tout un tas de données sensibles auraient pu être extraites:


select * from to_tsvector(
'french',
'mon code secret est le 12345 et j''ai 217.45 € sur mon compte')
=> "'12345':6 '217.45':10 'cod':2 'compt':13 'secret':3"


la nouvelle configuration, elle, garde nos petits secrets bien au chaud!

select * from to_tsvector(
'french_safe',
'mon code secret est le 12345 et j''ai 217.45 € sur mon compte')
=> "'cod':2 'compt':11 'secret':3"


Faites donc un peu tourner des phrases sous ts_debug, et voyez comment les nombres et les mélanges chiffres lettres (mots de passes!) sont gentiment effacés.

Aucun commentaire: