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:
Limitar a visibilidade de definições de UDF ou procedimentos armazenados.
Limitar a visibilidade dos dados sensíveis que podem ser expostos por UDFs.
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:
Para UDFs
Comandos SHOW FUNCTIONS e SHOW USER FUNCTIONS
Comando DESCRIBE FUNCTION
Exibição Information Schema FUNCTIONS
Para procedimentos
Comando SHOW PROCEDURES
Comando DESCRIBE PROCEDURE
Exibição Information Schema PROCEDURES
Para ambos
Perfil de consulta (na interface da Web)
Função utilitária GET_DDL
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 |
...
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.
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';
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.