En este documento, se describe cómo usar vistas seguras con parámetros en Cloud SQL para PostgreSQL, que te permiten limitar el acceso a los datos en función de parámetros con nombre específicos de la aplicación, como las credenciales de usuario de la aplicación. Las vistas seguras con parámetros mejoran la seguridad y el control de acceso, ya que extienden la funcionalidad de las vistas de PostgreSQL. Estas vistas también mitigan los riesgos de ejecutar consultas no confiables desde las aplicaciones, ya que aplican automáticamente una serie de restricciones en cualquier consulta que se ejecute.
Para obtener más información, consulta la descripción general de las vistas seguras con parámetros y el instructivo sobre las vistas seguras con parámetros.
Antes de comenzar
En este documento, se supone que creaste una instancia de Cloud SQL para PostgreSQL.
Antes de que puedas usar vistas seguras con parámetros, debes hacer lo siguiente:
Habilita la marca de base de datos
cloudsql.enable_parameterized_viewspara tu instancia de Cloud SQL. Este cambio de marca requiere que se reinicie la base de datos. Para obtener más información, consulta Configura marcas de bases de datos.Usa Cloud SQL Studio o psql para crear la extensión
parameterized_viewsen cualquier base de datos en la que se cree una vista con parámetros:-- Requires cloudsql.enable_parameterized_views set to on CREATE EXTENSION parameterized_views;Cuando se crea la extensión, el sistema también crea un esquema llamado
parameterized_viewspara que las APIs se incluyan en el espacio de nombres de ese esquema y no entren en conflicto con las APIs existentes.
Crea una vista segura con parámetros
Para crear una vista segura con parámetros, sigue estos pasos:
Ejecuta el comando DDL
CREATE VIEWcon la opciónsecurity_barrier:CREATE VIEW VIEW_NAME WITH (security_barrier) AS SELECT COLUMN_NAME, COLUMN_NAME_N FROM TABLE_NAME ALIAS WHERE CONDITION;
Reemplaza lo siguiente:
VIEW_NAME: el nombre de la vista segura con parámetrosTABLE_NAME: el nombre de la tabla que se usará en la vista segura con parámetrosALIAS: el alias del nombre de la tabla que se usará en la vista segura con parámetrosCOLUMNNAMEoCOLUMN_NAMEN: el nombre de la columna o las columnas de la tabla que se usarán en la vista segura con parámetrosCONDITION: la instrucción de condición que se usa para restringir a los usuarios de la aplicación de modo que solo puedan ver las filas a las que tienen permiso para acceder. Agrega los parámetros obligatorios con la sintaxis$@PARAMETER_NAMEen la cláusulaWHERE. Un caso de uso común es verificar el valor de una columna conWHERE COLUMN = $@PARAMETER_NAME.$@PARAMETER_NAMEindica un parámetro de vista con nombre. Su valor se proporciona cuando usas la API deexecute_parameterized_query. Los parámetros de vista con nombre tienen los siguientes requisitos:- Los parámetros de vista con nombre deben comenzar con una letra (a-z) o un guion bajo (
_). - Los caracteres posteriores pueden ser letras, guiones bajos o dígitos (
0-9). - Los parámetros de vista con nombre distinguen mayúsculas de minúsculas. Por ejemplo,
$@PARAMETER_NAMEse interpreta de manera diferente que$@parameter_name.
A continuación, se muestra un ejemplo de cómo crear una vista segura con parámetros que usa un parámetro de vista con nombre:
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;- Los parámetros de vista con nombre deben comenzar con una letra (a-z) o un guion bajo (
Otorga
SELECTen la vista a cualquier usuario de la base de datos que tenga permiso para consultar la vista.Otorga
USAGEen el esquema que contiene las tablas definidas en la vista a cualquier usuario de la base de datos que tenga permiso para consultar la vista.
Para obtener más información, consulta Protege y controla el acceso a los datos de la aplicación con vistas seguras con parámetros (instructivo).
Configura la seguridad de tu aplicación
Para configurar la seguridad de tus aplicaciones con vistas seguras con parámetros, sigue estos pasos:
- Crea la vista segura con parámetros como usuario administrador. Este es un usuario de la base de datos de Cloud SQL que realiza operaciones administrativas para la aplicación.
Crea un rol de base de datos nuevo para ejecutar consultas en vistas seguras con parámetros. Este es un rol de base de datos de Cloud SQL que usa la aplicación para conectarse y acceder a la base de datos.
- Otorga permisos del rol nuevo a las vistas seguras, que suelen incluir privilegios
SELECTpara las vistas yUSAGEen los esquemas. - Limita los objetos a los que puede acceder este rol al conjunto mínimo requerido de funciones y objetos públicos que necesita la aplicación. Evita proporcionar acceso a esquemas y tablas que no sean públicos.
Cuando consultas las vistas, la aplicación proporciona los valores de los parámetros de vista obligatorios, que están vinculados a la identidad del usuario de la aplicación.
Para obtener más información, consulta Crea y administra usuarios.
- Otorga permisos del rol nuevo a las vistas seguras, que suelen incluir privilegios
Consulta una vista segura con parámetros
Para consultar una vista segura con parámetros, usa una de las siguientes opciones:
- Basada en JSON: Usa esta API para ejecutar la consulta de una sola vez y mostrar filas JSON.
- Basada en CURSOR: Usa esta API cuando tengas consultas de ejecución más larga o cuando tengas consultas grandes y quieras recuperar el resultado en lotes.
- Instrucción
PREPARE .. AS RESTRICTED: UsaPREPARE .. AS RESTRICTEDpara definir el plan de consulta y, luego, ejecutaEXECUTE ... WITH VIEW PARAMETERS (...)para ejecutarlo con parámetros específicos para la vista.
API de JSON
Ejecuta la función execute_parameterized_query(), que tiene la siguiente sintaxis:
SELECT * FROM
parameterized_views.execute_parameterized_query(
query => SQL_QUERY,
param_names => ARRAY [PARAMETER_NAMES],
param_values => ARRAY [PARAMETER_VALUES]
);
La función muestra una tabla de objetos JSON. Cada fila de la tabla equivale al valor row_to_json() de la fila de resultado de la consulta original.
El uso de esta API limita el tamaño del conjunto de resultados por tamaño (en KB) y por la cantidad de filas. Puedes configurar estos límites con parameterized_views.json_results_max_size y parameterized_views.json_results_max_rows.
API de CURSOR
Ejecuta la función execute_parameterized_query() con un nombre de cursor, que crea y muestra un CURSOR con alcance de transacción:
-- 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;
Instrucciones preparadas
El método de instrucciones preparadas te permite preparar un plan de consulta una vez y, luego, ejecutarlo varias veces con diferentes valores para los parámetros posicionales de la consulta y los parámetros con nombre de la vista.
Para usar una instrucción preparada, haz lo siguiente:
Crea la instrucción preparada.
-- Prepare the statement PREPARE PREPARED_STATEMENT_NAME (QUERY_PARAM_TYPE_1, QUERY_PARAM_TYPE_N) AS RESTRICTED SQL_QUERY;
Reemplaza lo siguiente:
PREPARED_STATEMENT_NAME: el nombre de la instrucción preparadaQUERY_PARAM_TYPE_N: el tipo de datos del parámetro de consulta, comoTEXTSQL_QUERY: la consulta en SQL que se ejecutará como parte de la instrucción preparada con el valor o los valores proporcionados
Ejecuta la instrucción 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');
Reemplaza lo siguiente:
PREPARED_STATEMENT_NAME: el nombre de la instrucción preparada.QUERY_VALUE_N: el valor o los valores que se proporcionarán como parámetro o parámetros a la consulta en SQLPARAMETER_NAME_N: el nombre del parámetro o los parámetros de vista con nombre que definiste cuando creaste la vista segura con parámetros. Creas el parámetro de vista con nombre a partir de la columna de la tabla.PARAMETER_VALUE_N: el valor o los valores para el parámetro de vista con nombre que restringe la vista segura con parámetros a las filas asociadas con el valor.
Limpia la instrucción preparada.
-- Cleanup DEALLOCATE PREPARED_STATEMENT_NAME>;
En el siguiente ejemplo, se usa una vista segura con parámetros llamada user_specific_items que requiere el parámetro de vista con nombre $@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;
Después de crear la instrucción preparada, puedes ejecutarla varias veces y asignar diferentes valores para la consulta y el parámetro de vista con nombre.
Por ejemplo, la primera ejecución de la consulta:
-- Execute for user 123, looking for items like '%Laptop%'
EXECUTE get_items_by_name ('%Laptop%')
WITH VIEW PARAMETERS (app_user_id := '123');
La segunda ejecución de la consulta:
-- Execute for user 456, looking for items like '%Book%'
EXECUTE get_items_by_name ('%Book%')
WITH VIEW PARAMETERS (app_user_id := '456');
La cláusula WITH VIEW PARAMETERS es donde se proporcionan los parámetros de vista con nombre (123, 456) para la vista segura con parámetros, separados de los parámetros posicionales para la consulta preparada (%Laptop%, %Book%).
Por último, limpia la instrucción preparada.
-- Clean up the get_item_by_name prepared statement
DEALLOCATE get_items_by_name;
Restricciones aplicadas en las consultas
En la siguiente lista, se incluye el conjunto de operaciones restringidas para las consultas que ejecutas con las opciones descritas en Consulta una vista segura con parámetros:
- Solo lectura: Solo se permiten las instrucciones
SELECTde solo lectura. Se prohíben DML (INSERT,UPDATE,DELETE) y DDL (CREATE,ALTER). - Sin anidación: Se prohíben las llamadas recursivas a
execute_parameterized_query. - Límites de extensión: No se permiten ciertas extensiones que inician sesiones nuevas en segundo plano (p.ej.,
dblink,pg_cron). - No se permiten las instrucciones
EXPLAINpara evitar posibles filtraciones de información con planes de consulta.
Enumera todas las vistas con parámetros
Usa la vista parameterized_views.all_parameterized_views para enumerar todas las vistas con parámetros (las que contienen al menos un parámetro con nombre $@...).
SELECT * FROM parameterized_views.all_parameterized_views;