Proteção de informações sensíveis com UDFs e procedimentos armazenados seguros

Para ajudar a garantir que as informações sensíveis sejam ocultadas de usuários que não deveriam ter acesso a elas, você pode usar a palavra-chave SECURE ao criar uma função definida pelo usuário (UDF) e o procedimento armazenado.

Este tópico descreve como você pode:

Neste tópico:

Limitação da visibilidade de uma definição de UDF ou procedimento

Para um procedimento armazenado ou UDF, você pode impedir que os usuários vejam definições específicas. Quando você especifica que o UDF ou procedimento é seguro, estes detalhes ficam visíveis apenas para usuários autorizados - em outras palavras, para usuários a quem é concedida uma função que possui a função.

Por exemplo, para uma função ou procedimento seguro, as informações omitidas para usuários não autorizados incluem:

  • Seu corpo (o código do manipulador que compreende sua lógica)

  • Sua lista de importações

  • Seu nome do manipulador

  • Sua lista de pacotes

Os usuários não autorizados ainda poderão ver informações que incluam:

  • Seus tipos de parâmetros

  • Seu tipo de retorno

  • Sua linguagem do manipulador

  • Seu tratamento de nulos

  • Sua volatilidade

Para saber mais sobre a concessão de funções, consulte GRANT ROLE e Visão geral do controle de acesso.

Com uma função ou procedimento seguro, um usuário não autorizado - a quem não foi concedida uma função proprietária da função ou procedimento - não pode visualizar a definição da função ou procedimento quando utilizar qualquer uma das seguintes opções:

Observe que funções e procedimentos cujos manipuladores são escritos em Java, Python ou Scala permitem a cláusula IMPORTS, que importa código ou arquivos de dados dos estágios do Snowflake. A utilização da palavra-chave SECURE não tem qualquer efeito sobre a visibilidade ou acesso a esses estágios.

Além disso, para funções e procedimentos cujos manipuladores são escritos em Java, Python ou Scala, tornar as funções e procedimentos seguros garante que eles sejam executados em áreas restritas separadas, de modo que nenhum recurso seja compartilhado entre eles.

Para obter mais informações sobre o uso da palavra-chave SECURE, consulte Criação de um UDF ou procedimento armazenado seguro.

Limitação da visibilidade dos dados sensíveis de um UDF

Em UDFs, você pode evitar que os usuários vejam dados que deveriam estar ocultos tornando o UDF seguro. Você faz isto usando a palavra-chave SECURE ao criar ou alterar o UDF.

Defina um UDF como seguro quando é especificamente designado para a privacidade de dados (ou seja, para limitar o acesso a dados sigilosos que não devem ser expostos a todos os usuários das tabelas subjacentes).

Você não deve tornar um UDF seguro quando ele é definido para conveniência da consulta, como quando ele é criado para simplificar a consulta de dados para os quais os usuários não precisam entender a representação dos dados subjacentes. Isso porque o otimizador de consultas do Snowflake, ao avaliar as UDFs seguras, ignora as otimizações usadas para UDFs regulares. Isso pode reduzir o desempenho de consulta para UDFs seguras.

Para limitar a visibilidade nos dados subjacentes de um UDF, use a palavra-chave SECURE ao criá-lo ou alterá-lo. Para obter mais informações, consulte Criação de um UDF ou procedimento armazenado seguro.

Como os dados podem ficar visíveis

Algumas das otimizações internas para UDFs, incluindo uma otimização chamada pushdown, requerem acesso aos dados subjacentes nas tabelas base. Esse acesso pode permitir que os dados que estão ocultos para os usuários de UDF sejam expostos indiretamente por meio de métodos programáticos. Em certas situações, um usuário pode ser capaz de deduzir informações sobre linhas que o usuário não consegue ver diretamente.

UDFs seguros não utilizam essas otimizações, garantindo que os usuários não tenham nem mesmo acesso indireto aos dados subjacentes. Para obter mais informações sobre pushdown, consulte Otimização de pushdown e visibilidade de dados.

Dica

Para decidir se você deve usar uma UDF segura, você deve considerar a finalidade da UDF e ponderar privacidade/segurança de dados e desempenho da consulta.

Além disso, se seus dados forem suficientemente sigilosos a ponto de exigir que os acessos por meio de um tipo de objeto (como UDFs) sejam seguros, então você deve considerar seriamente garantir que os acessos por meio de outros tipos de objetos (como exibições) também sejam seguros.

Por exemplo, se você permitir apenas o acesso de UDFs seguras a uma determinada tabela, então qualquer exibição que receba o acesso à mesma tabela provavelmente também deverá ser segura.

Como UDFs seguros protegem os dados

Como descrito em Otimização de pushdown e visibilidade de dados, a otimização pushdown pode reordenar os filtros que determinam como uma consulta é processada. Se a otimização reordenar os filtros de forma a permitir que um (ou mais) filtro geral funcione antes que os filtros apropriados utilizados para proteger os dados sejam aplicados, os detalhes subjacentes poderão ser expostos. Portanto, a solução é evitar que o otimizador use o pushdown para certos tipos de filtros (de forma mais geral, para evitar que o otimizador utilize certos tipos de otimizações, incluindo, mas não limitado a, pushdown de filtro) se essas otimizações não forem seguras.

Declarar uma UDF como “segura” diz ao otimizador para não aplicar pushdown a certos filtros (de forma mais geral, para não usar certas otimizações). Entretanto, evitar certos tipos de otimizações pode ter impacto no desempenho.

Práticas recomendadas para a proteção do acesso a dados sensíveis

UDFs seguras evitam que os usuários sejam possivelmente expostos a dados de linhas de tabelas que são filtradas pela função. Entretanto, ainda há maneiras de um proprietário de dados inadvertidamente expor informações sobre os dados subjacentes se as UDFs não forem construídas com cuidado. Esta seção descreve algumas armadilhas potenciais a serem evitadas.

Como evitar expor valores de colunas geradas por sequência

Uma prática comum para gerar chaves alternativas é usar uma sequência ou coluna de incremento automático. Se essas chaves forem expostas a usuários que não têm acesso a todos os dados subjacentes, um usuário poderá conseguir adivinhar detalhes da distribuição dos dados subjacentes.

Por exemplo, imagine que temos uma função get_widgets_function() que expõe a coluna ID. Se a ID for gerada a partir de uma sequência, um usuário de get_widgets_function() poderia deduzir o número total de widgets criados entre os carimbos de data/hora de criação de dois widgets aos quais o usuário tem acesso. Considere a seguinte consulta e resultado:

select * from table(get_widgets_function()) order by created_on;

------+-----------------------+-------+-------+-------------------------------+
  ID  |         NAME          | COLOR | PRICE |          CREATED_ON           |
------+-----------------------+-------+-------+-------------------------------+
...
 315  | Small round widget    | Red   | 1     | 2017-01-07 15:22:14.810 -0700 |
 1455 | Small cylinder widget | Blue  | 2     | 2017-01-15 03:00:12.106 -0700 |
...
Copy

Com base no resultado, o usuário pode suspeitar que 1139 widgets (1455 - 315) foram criados entre 7 e 15 de janeiro. Se essa informação for sigilosa demais para expor aos usuários de uma função, você pode usar uma das alternativas a seguir:

  • Não expor a coluna gerada por sequências como parte da função.

  • Usar identificadores aleatórios (como os gerados por UUID_STRING) em vez de valores gerados por sequência.

  • Ofuscar programaticamente os identificadores.

Limitação da visibilidade no tamanho dos dados verificados

Para consultas contendo funções seguras, o Snowflake não expõe a quantidade de dados verificados (seja em termos de bytes ou micropartições) ou a quantidade total de dados. Isso é feito para proteger as informações dos usuários que só têm acesso a um subconjunto dos dados.

Entretanto, os usuários ainda podem conseguir fazer suposições sobre a quantidade de dados subjacentes com base nas características de desempenho das consultas. Por exemplo, uma consulta executada no dobro do tempo pode processar o dobro de dados. Embora tais observações sejam aproximadas no melhor dos casos, em alguns casos, pode ser indesejável que até mesmo esse nível de informação seja exposto.

Nesses casos, você deve materializar os dados por usuário/função em vez de expor funções dos dados de base aos usuários. No caso da tabela widgets descrita neste tópico, seria criada uma tabela para cada função que tenha acesso a widgets. Cada uma dessas tabelas conteria apenas os widgets acessíveis por essa função, e uma função teria acesso à sua tabela. Isso é muito mais trabalhoso do que usar uma única função, mas para situações de segurança extremamente alta, isso pode ser justificado.

Autorização do acesso à tabela base para usuários de uma conta específica

Ao utilizar UDFs seguras com compartilhamento de dados, a função CURRENT_ACCOUNT pode ser usada para autorizar usuários de uma conta específica a acessar linhas em uma tabela base.

Nota

Ao usar as funções CURRENT_ROLE e CURRENT_USER com UDFs seguras que serão compartilhadas com contas Snowflake, o Snowflake retorna um valor NULL para essas funções. A razão é que o proprietário dos dados que estão sendo compartilhados geralmente não controla os usuários ou funções na conta com a qual a UDF está sendo compartilhada.

UDFs seguras e políticas de mascaramento

Se utilizar uma UDF, independentemente de a UDF ser uma UDF segura ou não, em uma política de mascaramento, certifique-se de que o tipo de dados da coluna, a UDF e a política de mascaramento sejam correspondentes.

Para obter mais informações, consulte Funções definidas pelo usuário em uma política de mascaramento.

Criação de um UDF ou procedimento armazenado seguro

Você pode tornar um UDF ou procedimento seguro usando a palavra-chave SECURE ao criá-lo ou alterá-lo.

Para criar ou converter um UDF para que seja seguro, especifique SECURE ao usar o seguinte:

Para criar um procedimento para que seja seguro, especifique SECURE ao utilizar o seguinte:

Como determinar se um UDF ou procedimento é seguro

Você pode determinar se uma função ou procedimento é seguro usando o comando SHOW FUNCTIONS ou SHOW PROCEDURES. Os comandos retornam uma tabela com uma coluna IS_SECURE cujo valor é Y para seguro e N para não seguro.

O código no exemplo a seguir retorna uma tabela de propriedades para uma função MYFUNCTION.

show functions like 'MYFUNCTION';
Copy

Como ver detalhes de funções seguras no perfil de consulta

Os dados internos de uma função segura não são expostos no Perfil de consulta (na interface da Web). Esse é o caso até mesmo para o proprietário da função segura, pois não proprietários podem ter acesso ao Perfil de consulta de um proprietário.