Este documento descreve como usar visualizações seguras parametrizadas no Cloud SQL para PostgreSQL, que permitem limitar o acesso a dados com base em parâmetros nomeados específicos do aplicativo, como credenciais de usuário. As visualizações seguras parametrizadas melhoram a segurança e o controle de acesso, estendendo a funcionalidade das visualizações do PostgreSQL. Essas visualizações também atenuam os riscos de execução de consultas não confiáveis de aplicativos, aplicando automaticamente várias restrições a qualquer consulta executada.
Para mais informações, consulte Visualizações seguras parametrizadas no Cloud SQL e proteja e controle o acesso aos dados do aplicativo usando visualizações seguras parametrizadas.
Antes de começar
Este documento pressupõe que você já criou uma instância do Cloud SQL para PostgreSQL.
Antes de usar visualizações seguras parametrizadas, faça o seguinte:
Ative a flag de banco de dados
cloudsql.enable_parameterized_viewspara sua instância do Cloud SQL. Essa mudança de flag exige a reinicialização do banco de dados. Para mais informações, consulte Configurar flags de banco de dados.Use Cloud SQL Studio ou psql para criar a extensão
parameterized_viewsem qualquer banco de dados em que uma visualização parametrizada seja criada:-- Requires cloudsql.enable_parameterized_views set to on CREATE EXTENSION parameterized_views;Quando a extensão é criada, um esquema chamado
parameterized_viewstambém é criado pelo sistema para que as APIs sejam contidas no namespace desse esquema e não entrem em conflito com as APIs atuais.
Criar uma visualização segura parametrizada
Para criar uma visualização segura parametrizada, siga estas etapas:
Execute o comando DDL
CREATE VIEWusando a opçãosecurity_barrier:CREATE VIEW VIEW_NAME WITH (security_barrier) AS SELECT COLUMN_NAME, COLUMN_NAME_N FROM TABLE_NAME ALIAS WHERE CONDITION;
Substitua:
VIEW_NAME: o nome da visualização segura parametrizadaTABLE_NAME: o nome da tabela a ser usada na visualização segura parametrizadaALIAS: o alias do nome da tabela a ser usado na visualização segura parametrizadaCOLUMNNAMEouCOLUMN_NAMEN: o nome da coluna ou colunas da tabela a serem usadas na visualização segura parametrizadaCONDITION: a instrução de condição usada para restringir os usuários do aplicativo para que eles só possam visualizar as linhas a que têm permissão de acesso. Adicione os parâmetros necessários usando a sintaxe$@PARAMETER_NAMEna cláusulaWHERE. Um caso de uso comum é verificar o valor de uma coluna usandoWHERE COLUMN = $@PARAMETER_NAME.$@PARAMETER_NAMEindica um parâmetro de visualização nomeado. O valor é fornecido quando você usa a APIexecute_parameterized_query. Os parâmetros de visualização nomeados têm os seguintes requisitos:- Os parâmetros de visualização nomeados precisam começar com uma letra (a-z) ou um sublinhado (
_). - Os caracteres subsequentes podem ser letras, sublinhados ou dígitos (
0-9). - Os parâmetros de visualização nomeados diferenciam maiúsculas de minúsculas. Por exemplo,
$@PARAMETER_NAMEé interpretado de maneira diferente de$@parameter_name.
Confira a seguir um exemplo de criação de uma visualização segura parametrizada que usa um parâmetro de visualização nomeado:
CREATE VIEW user_specific_items WITH (security_barrier) AS SELECT item_id, item_name, description, owner_id FROM items t WHERE owner_id = $@app_user_id;- Os parâmetros de visualização nomeados precisam começar com uma letra (a-z) ou um sublinhado (
Conceda
SELECTna visualização a qualquer usuário do banco de dados que tenha permissão para consultar a visualização.Conceda
USAGEno esquema que contém as tabelas definidas na visualização a qualquer usuário do banco de dados que tenha permissão para consultar a visualização.
Para mais informações, consulte Proteja e controle o acesso aos dados do aplicativo usando visualizações seguras parametrizadas.
Configurar a segurança do aplicativo
Para configurar a segurança dos aplicativos usando visualizações seguras parametrizadas, siga estas etapas:
- Crie a visualização segura parametrizada como um usuário administrativo. Esse é um usuário do banco de dados do Cloud SQL que realiza operações administrativas para o aplicativo.
Crie um novo papel de banco de dados para executar consultas em visualizações seguras parametrizadas. Esse é um papel de banco de dados do Cloud SQL que o aplicativo usa para se conectar e fazer login no banco de dados.
- Conceda permissões ao novo papel para as visualizações seguras, que normalmente incluem privilégios
SELECTpara as visualizações eUSAGEnos esquemas. - Limite os objetos que esse papel pode acessar ao conjunto mínimo necessário de funções e objetos públicos de que o aplicativo precisa. Evite fornecer acesso a esquemas e tabelas que não são públicos.
Ao consultar as visualizações, o aplicativo fornece os valores dos parâmetros de visualização necessários, que estão vinculados à identidade do usuário do aplicativo.
Para mais informações, consulte Criar e gerenciar usuários.
- Conceda permissões ao novo papel para as visualizações seguras, que normalmente incluem privilégios
Consultar uma visualização segura parametrizada
Para consultar uma visualização segura parametrizada, use uma das seguintes opções:
- Baseada em JSON: use essa API para executar a consulta em uma única vez e retornar linhas JSON.
- Baseada em CURSOR: use essa API quando tiver consultas de execução mais longa ou consultas grandes e quiser buscar o resultado em lotes.
- Instrução
PREPARE .. AS RESTRICTED: usePREPARE .. AS RESTRICTEDpara definir o plano de consulta e, em seguida, executeEXECUTE ... WITH VIEW PARAMETERS (...)para executá-lo com parâmetros específicos para a visualização.
API JSON
Execute a função execute_parameterized_query(), que tem a seguinte sintaxe:
SELECT * FROM
parameterized_views.execute_parameterized_query(
query => SQL_QUERY,
param_names => ARRAY [PARAMETER_NAMES],
param_values => ARRAY [PARAMETER_VALUES]
);
A função retorna uma tabela de objetos JSON. Cada linha na tabela é equivalente ao valor row_to_json() da linha de resultado da consulta original.
O uso dessa API limita o tamanho do conjunto de resultados por tamanho (em KB) e pelo número de linhas. É possível configurar esses limites usando parameterized_views.json_results_max_size e parameterized_views.json_results_max_rows.
API CURSOR
Execute a função execute_parameterized_query() com um nome de cursor, que cria e retorna um CURSOR com escopo de transação:
-- Must be in a transaction block
BEGIN;
SELECT * FROM
parameterized_views.execute_parameterized_query(
query => SQL_QUERY,
cursor_name => CURSOR_NAME,
param_names => ARRAY [PARAMETER_NAMES],
param_values => ARRAY [PARAMETER_VALUES]
);
FETCH ALL FROM CURSOR_NAME;
END;
Instruções preparadas
O método de instruções preparadas permite preparar um plano de consulta uma vez e executá-lo várias vezes com valores diferentes para os parâmetros posicionais da consulta e os parâmetros nomeados da visualização.
Para usar uma instrução preparada, faça o seguinte:
Crie a instrução preparada.
-- Prepare the statement PREPARE PREPARED_STATEMENT_NAME (QUERY_PARAM_TYPE_1, QUERY_PARAM_TYPE_N) AS RESTRICTED SQL_QUERY;
Substitua:
PREPARED_STATEMENT_NAME: o nome da instrução preparadaQUERY_PARAM_TYPE_N: o tipo de dados do parâmetro de consulta, comoTEXTSQL_QUERY: a consulta SQL a ser executada como parte da instrução preparada com o valor ou valores fornecidos
Execute a instrução preparada.
-- Execute the statement with query parameters and view parameters EXECUTE PREPARED_STATEMENT_NAME (QUERY_VALUE_1, QUERY_VALUE_N) WITH VIEW PARAMETERS (PARAMETER_NAME_1 := 'PARAMETER_VALUE_1', PARAMETER_NAME_N := 'PARAMETER_VALUE_N');
Substitua:
PREPARED_STATEMENT_NAME: o nome da instrução preparada.QUERY_VALUE_N: o valor ou valores a serem fornecidos como um parâmetro ou parâmetros para a consulta SQLPARAMETER_NAME_N: o nome do parâmetro ou parâmetros de visualização nomeados que você definiu ao criar a visualização segura parametrizada. Você cria o parâmetro de visualização nomeado na coluna da tabela.PARAMETER_VALUE_N: o valor ou valores para o parâmetro de visualização nomeado que restringe a visualização segura parametrizada às linhas associadas ao valor.
Limpe a instrução preparada.
-- Cleanup DEALLOCATE PREPARED_STATEMENT_NAME>;
O exemplo a seguir usa uma visualização segura parametrizada chamada user_specific_items, que exige o parâmetro de visualização nomeado $@app_user_id.
-- Prepare a query with a positional parameter $1 for the item_name pattern
PREPARE get_items_by_name (TEXT) AS RESTRICTED
SELECT item_id, item_name FROM user_specific_items
WHERE item_name LIKE $1;
Depois de criar a instrução preparada, você pode executá-la várias vezes e atribuir valores diferentes para a consulta e o parâmetro de visualização nomeado.
Por exemplo, a primeira execução de consulta:
-- Execute for user 123, looking for items like '%Laptop%'
EXECUTE get_items_by_name ('%Laptop%')
WITH VIEW PARAMETERS (app_user_id := '123');
A segunda execução de consulta:
-- Execute for user 456, looking for items like '%Book%'
EXECUTE get_items_by_name ('%Book%')
WITH VIEW PARAMETERS (app_user_id := '456');
A cláusula WITH VIEW PARAMETERS é onde os parâmetros de visualização nomeados (123, 456) para a visualização segura parametrizada são fornecidos, separados dos parâmetros posicionais para a consulta preparada (%Laptop%, %Book%).
Por fim, limpe a instrução preparada.
-- Clean up the get_item_by_name prepared statement
DEALLOCATE get_items_by_name;
Restrições em consultas
A lista a seguir mostra o conjunto de operações restritas para consultas executadas usando as opções descritas em Consultar uma visualização segura parametrizada:
- Somente leitura: apenas instruções
SELECTsomente leitura são permitidas. DML (INSERT,UPDATE,DELETE) e DDL (CREATE,ALTER) são proibidos. - Sem aninhamento: chamadas recursivas para
execute_parameterized_querysão proibidas. - Limites de extensão: algumas extensões que iniciam novas sessões em segundo plano (por exemplo,
dblink,pg_cron) não são permitidas. - Instruções
EXPLAINnão são permitidas para evitar possíveis vazamentos de informações usando planos de consulta.
Listar todas as visualizações parametrizadas
Use a visualização parameterized_views.all_parameterized_views para listar todas as visualizações parametrizadas (aquelas que contêm pelo menos um parâmetro nomeado $@...).
SELECT * FROM parameterized_views.all_parameterized_views;