Ce document explique comment utiliser des vues sécurisées paramétrées dans Cloud SQL pour PostgreSQL. Elles vous permettent de limiter l'accès aux données en fonction de paramètres nommés spécifiques à l'application, comme les identifiants des utilisateurs de l'application. Les vues sécurisées paramétrées améliorent la sécurité et le contrôle des accès en étendant la fonctionnalité des vues PostgreSQL. Ces vues atténuent également les risques d'exécution de requêtes non fiables à partir d'applications en appliquant automatiquement un certain nombre de restrictions à toute requête exécutée.
Pour en savoir plus, consultez la présentation des vues sécurisées paramétrées et le tutoriel sur les vues sécurisées paramétrées.
Avant de commencer
Ce document suppose que vous avez créé une instance Cloud SQL pour PostgreSQL.
Avant de pouvoir utiliser des vues sécurisées paramétrées, vous devez effectuer les opérations suivantes :
Activez l'option de base de données
cloudsql.enable_parameterized_viewspour votre instance Cloud SQL. La modification de cette option nécessite un redémarrage de la base de données. Pour en savoir plus, consultez Configurer des options de base de données.Utilisez Cloud SQL Studio ou psql pour créer l'extension
parameterized_viewsdans n'importe quelle base de données où une vue paramétrée est créée :-- Requires cloudsql.enable_parameterized_views set to on CREATE EXTENSION parameterized_views;Lorsque l'extension est créée, un schéma nommé
parameterized_viewsest également créé par le système afin que les API soient contenues dans l'espace de noms de ce schéma et qu'elles n'entrent pas en conflit avec les API existantes.
Créer une vue sécurisée paramétrée
Pour créer une vue sécurisée paramétrée, procédez comme suit :
Exécutez la commande LDD
CREATE VIEWavec l'optionsecurity_barrier:CREATE VIEW VIEW_NAME WITH (security_barrier) AS SELECT COLUMN_NAME, COLUMN_NAME_N FROM TABLE_NAME ALIAS WHERE CONDITION;
Remplacez les éléments suivants :
VIEW_NAME: nom de la vue sécurisée paramétréeTABLE_NAME: nom de la table à utiliser dans la vue sécurisée paramétréeALIAS: alias du nom de la table à utiliser dans la vue sécurisée paramétréeCOLUMNNAMEouCOLUMN_NAMEN: nom de la ou des colonnes de table à utiliser dans la vue sécurisée paramétréeCONDITION: instruction de condition utilisée pour restreindre les utilisateurs de l'application afin qu'ils ne puissent afficher que les lignes auxquelles ils sont autorisés à accéder. Ajoutez les paramètres requis à l'aide de la syntaxe$@PARAMETER_NAMEdans la clauseWHERE. Un cas d'utilisation courant consiste à vérifier la valeur d'une colonne à l'aide deWHERE COLUMN = $@PARAMETER_NAME.$@PARAMETER_NAMEindique un paramètre de vue nommée. Sa valeur est fournie lorsque vous utilisez l'APIexecute_parameterized_query. Les paramètres de vue nommée doivent respecter les exigences suivantes :- Les paramètres de vue nommée doivent commencer par une lettre (a-z) ou un trait de soulignement (
_). - Les autres caractères peuvent être des lettres, des traits de soulignement ou des chiffres (
0-9). - Les paramètres des vues nommées sont sensibles à la casse. Par exemple,
$@PARAMETER_NAMEest interprété différemment de$@parameter_name.
Voici un exemple de création d'une vue sécurisée paramétrée qui utilise un paramètre de vue nommé :
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;- Les paramètres de vue nommée doivent commencer par une lettre (a-z) ou un trait de soulignement (
Accordez
SELECTsur la vue à tout utilisateur de la base de données autorisé à interroger la vue.Accordez
USAGEsur le schéma contenant les tables définies dans la vue à tout utilisateur de base de données autorisé à interroger la vue.
Pour en savoir plus, consultez Sécuriser et contrôler l'accès aux données d'application à l'aide de vues sécurisées paramétrées (tutoriel).
Configurer la sécurité pour votre application
Pour configurer la sécurité de vos applications à l'aide de vues sécurisées paramétrées, procédez comme suit :
- Créez la vue sécurisée paramétrée en tant qu'utilisateur avec accès administrateur. Il s'agit d'un utilisateur de base de données Cloud SQL qui effectue des opérations administratives pour l'application.
Créez un rôle de base de données pour exécuter des requêtes sur des vues sécurisées paramétrées. Il s'agit d'un rôle de base de données Cloud SQL que l'application utilise pour se connecter et se connecter à la base de données.
- Accordez au nouveau rôle des autorisations sur les vues sécurisées, qui incluent généralement les droits
SELECTsur les vues etUSAGEsur les schémas. - Limitez les objets auxquels ce rôle peut accéder à l'ensemble minimal requis de fonctions et d'objets publics dont l'application a besoin. Évitez d'accorder l'accès à des schémas et des tables qui ne sont pas publics.
Lorsque vous interrogez les vues, l'application fournit les valeurs des paramètres de vue requis, qui sont liés à l'identité de l'utilisateur de l'application.
Pour en savoir plus, consultez Créer et gérer des utilisateurs.
- Accordez au nouveau rôle des autorisations sur les vues sécurisées, qui incluent généralement les droits
Interroger une vue sécurisée paramétrée
Pour interroger une vue sécurisée paramétrée, utilisez l'une des options suivantes :
- Basée sur JSON : utilisez cette API pour exécuter la requête en une seule fois et renvoyer des lignes JSON.
- CURSOR : utilisez cette API lorsque vous avez des requêtes de longue durée ou volumineuses et que vous souhaitez récupérer les résultats par lots.
- Instruction
PREPARE .. AS RESTRICTED: utilisezPREPARE .. AS RESTRICTEDpour définir le plan de requête, puis exécutezEXECUTE ... WITH VIEW PARAMETERS (...)pour l'exécuter avec des paramètres spécifiques pour la vue.
API JSON
Exécutez la fonction execute_parameterized_query(), dont la syntaxe est la suivante :
SELECT * FROM
parameterized_views.execute_parameterized_query(
query => SQL_QUERY,
param_names => ARRAY [PARAMETER_NAMES],
param_values => ARRAY [PARAMETER_VALUES]
);
La fonction renvoie une table d'objets JSON. Chaque ligne de la table équivaut à la valeur row_to_json() de la ligne de résultat de la requête d'origine.
L'utilisation de cette API limite la taille de l'ensemble de résultats par taille (en Ko) et par nombre de lignes. Vous pouvez configurer ces limites à l'aide de parameterized_views.json_results_max_size et parameterized_views.json_results_max_rows.
API CURSOR
Exécutez la fonction execute_parameterized_query() avec un nom de curseur, ce qui crée et renvoie un CURSEUR à portée de transaction :
-- 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;
Instructions préparées
La méthode des instructions préparées vous permet de préparer un plan de requête une seule fois, puis de l'exécuter plusieurs fois avec différentes valeurs pour les paramètres positionnels de la requête et les paramètres nommés de la vue.
Pour utiliser une instruction préparée, procédez comme suit :
Créez l'instruction préparée.
-- Prepare the statement PREPARE PREPARED_STATEMENT_NAME (QUERY_PARAM_TYPE_1, QUERY_PARAM_TYPE_N) AS RESTRICTED SQL_QUERY;
Remplacez les éléments suivants :
PREPARED_STATEMENT_NAME: nom de l'instruction préparéeQUERY_PARAM_TYPE_N: type de données du paramètre de requête, tel queTEXTSQL_QUERY: requête SQL à exécuter dans l'instruction préparée avec la ou les valeurs indiquées
Exécutez l'instruction préparée.
-- 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');
Remplacez les éléments suivants :
PREPARED_STATEMENT_NAME: nom de l'instruction préparée.QUERY_VALUE_N: valeur ou valeurs à fournir en tant que paramètre ou paramètres à la requête SQLPARAMETER_NAME_N: nom du ou des paramètres de la vue nommée que vous avez définis lorsque vous avez créé la vue sécurisée paramétrée. Vous créez le paramètre de vue nommée à partir de la colonne de la table.PARAMETER_VALUE_N: valeur ou valeurs du paramètre de vue nommée qui limite la vue sécurisée paramétrée aux lignes associées à la valeur.
Nettoyez l'instruction préparée.
-- Cleanup DEALLOCATE PREPARED_STATEMENT_NAME>;
L'exemple suivant utilise une vue sécurisée paramétrée nommée user_specific_items, qui nécessite le paramètre de vue nommé $@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;
Une fois l'instruction préparée créée, vous pouvez l'exécuter plusieurs fois et attribuer différentes valeurs aux paramètres de requête et de vue nommée.
Par exemple, la première exécution de la requête :
-- Execute for user 123, looking for items like '%Laptop%'
EXECUTE get_items_by_name ('%Laptop%')
WITH VIEW PARAMETERS (app_user_id := '123');
La deuxième exécution de la requête :
-- Execute for user 456, looking for items like '%Book%'
EXECUTE get_items_by_name ('%Book%')
WITH VIEW PARAMETERS (app_user_id := '456');
La clause WITH VIEW PARAMETERS est l'endroit où les paramètres de vue nommée (123, 456) pour la vue sécurisée paramétrée sont fournis, séparément des paramètres positionnels pour la requête préparée (%Laptop%, %Book%).
Enfin, nettoyez l'instruction préparée.
-- Clean up the get_item_by_name prepared statement
DEALLOCATE get_items_by_name;
Restrictions appliquées aux requêtes
Vous trouverez ci-dessous la liste des opérations restreintes pour les requêtes que vous exécutez à l'aide des options décrites dans Interroger une vue sécurisée paramétrée :
- Lecture seule : seules les instructions
SELECTen lecture seule sont autorisées. Les instructions LMD (INSERT,UPDATE,DELETE) et LDD (CREATE,ALTER) sont interdites. - Pas d'imbrication : les appels récursifs à
execute_parameterized_querysont interdits. - Limites des extensions : certaines extensions qui démarrent de nouvelles sessions en arrière-plan (par exemple,
dblink,pg_cron) ne sont pas autorisées. - Les instructions
EXPLAINne sont pas autorisées pour éviter toute fuite d'informations potentielle à l'aide des plans de requête.
Lister toutes les vues paramétrées
Utilisez la vue parameterized_views.all_parameterized_views pour lister toutes les vues paramétrées (celles contenant au moins un paramètre nommé $@...).
SELECT * FROM parameterized_views.all_parameterized_views;