Uma solicitação frequente dos clientes é uma maneira de identificar PII em seus bancos de dados. Pensei em mostrar um breve exemplo de como isso pode ser feito.
História do usuário: "Quero identificar números de cartão de crédito não criptografados e números de previdência social em documentos para que eu possa garantir que os desenvolvedores não estejam armazenando coisas que não deveriam no banco de dados."
Histórico: N1QL tem um "tokenizador" a partir da versão 4.6. Combine isso com funções regex no N1QL, índices secundários específicos e temos um conjunto de ferramentas poderoso à nossa disposição para identificar padrões no banco de dados.
Exemplo de solução: Criei uma consulta para identificar números de previdência social não criptografados armazenados em um compartimento (o compartimento "padrão", neste caso). Estou procurando qualquer padrão de dígitos que corresponda a xxx-xx-xxxx ou xxxxxxxxx. A função TOKENS me permite tratar um documento como uma matriz de cadeias de caracteres. Usei o sinalizador "specials" para dizer ao N1QL para manter essas cadeias intactas. Se eu não usasse esse sinalizador, ele removeria os espaços e traços e ignoraria os itens após esses caracteres. Em seguida, procuro qualquer expressão regular que corresponda a um elemento dentro da matriz de tokens.
|
1 2 3 4 5 |
SELECT * FROM default WHERE ANY v IN TOKENS(default, {"specials":true}) SATISFIES REGEXP_LIKE(TOSTRING(v),'(\\d{3}-\\d{2}-\\d{4})|(\\b\\d{9}\\b)') END |
A identificação de números de cartão de crédito não criptografados armazenados em um bucket usa a mesma abordagem:
|
1 2 3 4 5 |
SELECT * FROM default WHERE ANY v IN TOKENS(default, {"specials":true}) SATISFIES REGEXP_LIKE(TOSTRING(v),'(\\d{4}-\\d{4}-\\d{4}-\\d{4}))|(\\b\\d{16}\\b)') END |
Para acelerar meu tempo de processamento, uso índices secundários otimizados para memória (MOI) para as consultas acima. Toda mutação no Couchbase é enviada de forma assíncrona para o projetor do índice. Os MOIs têm o benefício adicional de atualizar as informações contidas no índice a cada 20 ms. Os índices também fazem uso da tokenização.
|
1 2 3 4 5 6 |
CREATE INDEX `find_pii_ssn` ON `default`( (DISTINCT (ARRAY `v` FOR `v` IN TOKENS(self, {"specials": true}) END))) WHERE ANY `v` IN TOKENS(self, {"specials": true}) SATISFIES REGEXP_LIKE(TO_STRING(`v`), "(\\d{3}-\\d{2}-\\d{4})|(\\b\\d{9}\\b)") END |
...e para cartões de crédito não criptografados
|
1 2 3 4 5 6 |
CREATE INDEX `find_pii_ccn` ON `default`( (DISTINCT (ARRAY `v` FOR `v` IN TOKENS(self, {"specials": true}) END))) WHERE any `v` IN TOKENS(self, {"specials": true}) SATISFIES REGEXP_LIKE(TO_STRING(`v`), "(\\d{4}-\\d{4}-\\d{4}-\\d{4}))|(\\b\\d{16}\\b)") END |
Experimente: O Docker é minha maneira favorita de criar um ambiente de desenvolvimento. Um repositório fácil de usar para os exemplos acima está no github: n1ql-query-nodejs . Ele usa o docker-compose para criar dois serviços:
- Um serviço de cluster do Couchbase de nó único.
- Um serviço nodejs para provisionar o cluster do Couchbase com 250.000 perfis de usuários e índices para vários exemplos, incluindo a localização de PII não criptografadas.