En esta página se describe cómo usar vistas seguras parametrizadas en AlloyDB 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 parametrizadas mejoran la seguridad y el control de acceso al ampliar la funcionalidad de las vistas de PostgreSQL. Estas vistas también mitigan los riesgos de ejecutar consultas no fiables desde aplicaciones, ya que aplican automáticamente restricciones a cualquier consulta que se ejecute.
Para obtener más información, consulta Información general sobre las vistas seguras parametrizadas y Proteger y controlar el acceso a los datos de las aplicaciones mediante vistas seguras parametrizadas.
Antes de empezar
En esta página se da por hecho que ya ha creado un clúster y una instancia de AlloyDB. Para obtener más información, consulta Crear una base de datos.
Antes de usar vistas seguras parametrizadas, debe hacer lo siguiente:
Habilita la marca de base de datos
parameterized_views.enabled
, que carga las bibliotecas de extensiones necesarias. Debes habilitar esta marca, aunque el equipo de AlloyDB la haya habilitado anteriormente. Para obtener más información sobre cómo habilitar la marca de la base de datos, consulta el artículo Configurar las marcas de la base de datos de una instancia.Usa AlloyDB Studio o psql para crear la extensión
parameterized_views
en cualquier base de datos en la que quieras crear una vista parametrizada:-- Requires parameterized_views.enabled set to true CREATE EXTENSION parameterized_views;
Cuando se crea la extensión, el sistema también crea un esquema llamado
parameterized_views
para que las APIs se incluyan en el espacio de nombres de ese esquema y no entren en conflicto con las APIs que ya existen.
Crear una vista segura parametrizada
Para crear una vista segura parametrizada, siga estos pasos:
Ejecuta el comando
CREATE VIEW
DDL, como se muestra en el siguiente ejemplo:CREATE VIEW secure_checked_items WITH (security_barrier) AS SELECT bag_id, timestamp, location FROM checked_items t WHERE customer_id = $@app_end_userid;
En el ejemplo anterior, la vista segura parametrizada permite acceder a tres columnas de una tabla llamada
checked_items
. La vista limita los resultados a las filas en las quechecked_items.customer_id
coincide con un parámetro obligatorio.Utilice los siguientes atributos:
- Crea la vista con la opción
security_barrier
. - Para restringir los usuarios de la aplicación de forma que solo puedan ver las filas a las que tienen acceso, añada los parámetros necesarios en la definición de la vista mediante la sintaxis
$@PARAMETER_NAME
. Un caso práctico habitual es comprobar el valor de una columna en la cláusulaWHERE
medianteCOLUMN = $@PARAMETER_NAME
. $@PARAMETER_NAME
indica un parámetro de vista con nombre. Su valor se proporciona cuando usas la APIexecute_parameterized_query
. Los parámetros de vista con nombre deben cumplir los siguientes requisitos:- Los parámetros de las vistas con nombre deben empezar por una letra (de la a a la z).
- Puedes usar letras con signos diacríticos y letras no latinas, así como el guion bajo (
_
). - Los caracteres posteriores pueden ser letras, guiones bajos o dígitos (
0
-9
). - Los parámetros de vista con nombre no pueden contener
$
. - En los parámetros de las vistas con nombre se distingue entre mayúsculas y minúsculas. Por ejemplo,
$@PARAMETER_NAME
se interpreta de forma diferente a$@parameter_name
.
- Crea la vista con la opción
Concede
SELECT
en la vista a cualquier usuario de la base de datos que tenga permiso para consultar la vista.Concede
USAGE
en 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 el artículo Proteger y controlar el acceso a los datos de las aplicaciones mediante vistas seguras parametrizadas.
Configurar la seguridad de tu aplicación
Para configurar la seguridad de tus aplicaciones mediante vistas seguras parametrizadas, sigue estos pasos:
- Crea las vistas parametrizadas seguras como usuario administrador. Este usuario es un usuario de la base de datos de AlloyDB que realiza operaciones administrativas para la aplicación, como la configuración de la base de datos y la administración de la seguridad.
Crea un rol de base de datos para ejecutar consultas en vistas seguras con parámetros. Se trata de un rol de base de datos de AlloyDB que la aplicación usa para conectarse e iniciar sesión en la base de datos, así como para ejecutar consultas en vistas parametrizadas.
- Concede los permisos del nuevo rol a las vistas seguras, que normalmente incluyen privilegios
SELECT
en las vistas yUSAGE
en los esquemas. - Limita los objetos a los que puede acceder este rol al conjunto mínimo necesario de funciones y objetos públicos que necesita la aplicación. No proporciones acceso a esquemas y tablas que no sean públicos.
Cuando consulta 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 Crear un usuario de base de datos.
- Concede los permisos del nuevo rol a las vistas seguras, que normalmente incluyen privilegios
Consultar una vista segura parametrizada
Para consultar una vista segura parametrizada, usa una de las siguientes opciones que mejor se adapte a tu caso práctico:
- Basada en JSON: usa esta API para ejecutar la consulta de una sola vez y devolver filas JSON.
- Basada en CURSOR: usa esta API cuando tengas consultas de larga duración o consultas grandes y quieras obtener el resultado en lotes. La función
execute_parameterized_query
proporcionada por la extensiónparameterized_views
acepta un nombre de cursor. - Declaración
PREPARE EXECUTE
: úsala para las declaraciones preparadas que se pueden ejecutar varias veces con diferentes valores de parámetros.
Para consultar vistas seguras parametrizadas, se usa la función execute_parameterized_query()
proporcionada por la extensión parameterized_views
.
API JSON
Esta API tiene limitaciones porque declara un cursor para la consulta dada. Por lo tanto, la consulta debe ser compatible con los cursores de PostgreSQL.
Por ejemplo, la API CURSOR no admite las instrucciones DO
ni SHOW
.
Esta API tampoco restringe los resultados por tamaño ni por el número de filas devueltas.
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]
)
Haz los cambios siguientes:
SQL_QUERY
: una consulta de SQL cuya cláusulaFROM
hace referencia a una o varias vistas seguras parametrizadas.PARAMETER_NAMES
: una lista de nombres de parámetros que se deben incluir como cadenas.PARAMETER_VALUES
: una lista de valores de parámetros que se van a enviar.- Esta lista debe tener el mismo tamaño que la lista
param_names
, y el orden de los valores debe coincidir con el orden de los nombres. - El tipo exacto de los valores se deduce de la consulta y de la definición de la vista parametrizada. Las conversiones de tipo se realizan cuando es necesario y cuando es posible para el valor de parámetro dado. En caso de que los tipos no coincidan, se produce un error.
- Esta lista debe tener el mismo tamaño que la lista
La función devuelve una tabla de objetos JSON. Cada fila de la tabla equivale al valor ROW_TO_JSON()
de la fila de resultados de la consulta original.
Usa el siguiente ejemplo para consultar una vista segura parametrizada:
SELECT * FROM
parameterized_views.execute_parameterized_query(
query => 'SELECT * FROM secure_checked_items',
param_names => ARRAY ['app_end_userid'],
param_values => ARRAY ['40']
)
El uso de esta API limita el tamaño del conjunto de resultados por el tamaño expresado en kilobytes (KB) de los resultados y por el número de filas. Puedes configurar estos límites mediante parameterized_views.json_results_max_size
y parameterized_views.json_results_max_rows
.
API CURSOR
Ejecuta la función execute_parameterized_query()
, que crea y devuelve un CURSOR con ámbito de transacción que se usa para obtener los resultados de la consulta:
SELECT * FROM
parameterized_views.execute_parameterized_query(
query => SQL_QUERY,
cursor_name => CURSOR_NAME,
param_names => ARRAY [PARAMETER_NAMES],
param_values => ARRAY [PARAMETER_VALUES]
)
Haz los cambios siguientes:
SQL_QUERY
: una consulta de SQL cuya cláusulaFROM
hace referencia a una o varias vistas seguras parametrizadas.CURSOR_NAME
: nombre del cursor que se va a declarar.PARAMETER_NAMES
: una lista de nombres de parámetros que se deben incluir como cadenas.PARAMETER_VALUES
: una lista de valores de parámetros que se van a enviar. Esta lista debe tener el mismo tamaño que la listaparam_names
, donde el orden de los valores coincide con el orden de los nombres. El tipo exacto de los valores se infiere a partir de la consulta y de la definición de la vista parametrizada. Las conversiones de tipo se realizan cuando es necesario y cuando es posible para el valor del parámetro dado. Si los tipos no coinciden, se produce un error.
Usa el siguiente ejemplo para consultar una vista segura parametrizada:
-- start a transaction as the that is the default lifetime of a CURSOR
BEGIN;
-- create a cursor called 'mycursor'
SELECT * FROM parameterized_views.execute_parameterized_query(
query => 'SELECT * FROM secure_checked_items',
cursor_name => 'mycursor'
param_names => ARRAY ['app_end_userid'],
param_values => ARRAY ['40']
);
-- then, to actually fetch the results
FETCH ALL FROM mycursor;
-- end the transaction, which will clean up the cursor
END;
El cursor devuelto es un NO SCROLL
cursor WITHOUT HOLD
. No puedes usar el cursor para recuperar filas de forma no secuencial, por ejemplo, hacia atrás. No puedes usar el cursor fuera de la transacción que lo ha creado.
Instrucción PREPARE
Usa el comando PREPARE .. AS RESTRICTED
para crear una instrucción preparada
que haga referencia a vistas con parámetros. Estas instrucciones preparadas admiten parámetros posicionales y aplican varias restricciones cuando las ejecutas.
Para obtener más información, consulta Mecanismo de seguridad.
Esta función amplía PREPARE
y EXECUTE commands
para admitir parámetros de vista con nombre. Usa instrucciones preparadas para evitar la sobrecarga de analizar y reescribir cada vez que se ejecute la instrucción, lo que puede dar lugar a mejoras significativas del rendimiento, especialmente en el caso de las consultas complejas o que se ejecutan con frecuencia. Una sentencia preparada es un objeto del lado del servidor que puede optimizar el rendimiento precompilando y almacenando una sentencia SQL parametrizada para ejecutarla más adelante.
Esta API tiene limitaciones porque la instrucción debe permitirse en una instrucción PREPARE
, lo que significa que solo se admiten las instrucciones SELECT
y VALUES
.
Esta API tampoco restringe los resultados por tamaño ni por número de filas devueltas.
Para crear una instrucción preparada que haga referencia a vistas parametrizadas, ejecuta el comando PREPARE .. AS RESTRICTED
:
PREPARE pquery (/POSITIONAL_PARAM_TYPES/)
AS RESTRICTED query % a query that may refer to parameterized views
EXECUTE pquery (/POSITIONAL_PARAM_VALUES/)
WITH VIEW PARAMETERS (VIEW_PARAM_NAME1 = VIEW_PARAM_VALUE1[, ...]);
Haz los cambios siguientes:
POSITIONAL_PARAM_TYPES
: uno o varios parámetros posicionales que se usan en la consultaRESTRICTED
.POSITIONAL_PARAM_VALUES
: los valores reales que se sustituyen por los parámetros posicionales definidos en la instrucciónPREPARE
.VIEW_PARAM_NAME
: el nombre del parámetro que esperan las vistas parametrizadas a las que se hace referencia en la consultaRESTRICTED
.VIEW_PARAM_VALUE
: los valores reales que se transfieren a los parámetrosviewParamName
correspondientes de las vistas parametrizadas.
Para incluir parámetros en una instrucción preparada, debe proporcionar una lista de tipos de datos en la instrucción PREPARE
. En la instrucción que prepares, harás referencia a los parámetros por posición usando, por ejemplo, $1
y $2
.
Usa el comando EXECUTE .. WITH VIEW PARAMETERS
para ejecutar una instrucción preparada que hayas creado con el comando PREPARE .. AS RESTRICTED
.
Si la instrucción PREPARE
que creó la instrucción especificó parámetros posicionales, debes pasar un conjunto de parámetros compatibles a la instrucción EXECUTE
. Debe transferir los parámetros de vista con nombre que requieran las vistas parametrizadas en la cláusula WITH VIEW PARAMETERS
.
Usa el siguiente ejemplo para consultar una vista segura parametrizada:
PREPARE pquery (timestamp) AS RESTRICTED SELECT * FROM secure_checked_items WHERE timestamp > $1;
EXECUTE pquery (current_date - 1) WITH VIEW PARAMETERS (app_end_userid = 40);
EXECUTE pquery (current_date - 30) WITH VIEW PARAMETERS (app_end_userid = 40);
Restricciones implementadas en las consultas
A continuación, se muestra la lista de operaciones restringidas para las consultas que ejecutas con las opciones descritas en Consultar una vista segura con parámetros:
- Se prohíbe cualquier invocación recursiva de cualquier API (
execute_parameterized_query
oEXECUTE .. WITH VIEW PARAMETERS
) para que solo se usen los valores especificados por la aplicación. Esta restricción también impide que la consulta se utilice para eludir el envoltorio de seguridad del conjunto de valores de parámetros proporcionado. - No se permiten algunas extensiones que inician una nueva sesión en segundo plano, como las extensiones
dblink
,pg_cron
ypg_background
. - A continuación, se muestra la lista de elementos de consulta permitidos que están restringidos:
- Se permiten instrucciones
SELECT
de solo lectura. - Se permiten las instrucciones
SHOW
,CALL
yDO
de solo lectura. - No se permiten instrucciones DML como
INSERT
,UPDATE
yDELETE
. - No se permiten instrucciones DDL como
CREATE TABLE
yALTER TABLE
. - No se permiten otros tipos de instrucciones, como
LOAD
,SET
,CLUSTER
,LOCK
,CHECKPOINT
yEXPLAIN
.
- Se permiten instrucciones
- No se permiten las instrucciones
EXPLAIN
para evitar la posibilidad de que se produzcan ataques de canal encubierto mediante planes de consulta. Para obtener más información, consulta Canal encubierto. - Las vistas seguras parametrizadas proporcionan ajustes que le ayudan a gestionar los recursos que usan las APIs para consultar vistas parametrizadas, como
parameterized_views.statement_timeout
. Para obtener más información, consulta Marcas de bases de datos admitidas.
Mostrar todas las vistas parametrizadas
Usa la extensión parameterized_views
para enumerar todas las vistas parametrizadas de la base de datos con la vista all_parameterized_views
. El resultado de esta vista es el mismo que el de la vista de catálogo pg_views
, pero all_parameterized_views
solo muestra las vistas con parámetros de vista con nombre.
Para enumerar las vistas parametrizadas, utilice el siguiente ejemplo:
postgres=# select * from parameterized_views.all_parameterized_views ;
schemaname | viewname | viewowner | definition
-----------+--------------------+-----------+---------------------------------------------------------
public | checked_items_view | postgres | SELECT checked_items.bag_id, +
| | | checked_items."timestamp", +
| | | checked_items.location +
| | | FROM checked_items +
| | | WHERE (checked_items.customer_id = $@app_end_userid);
Para enumerar una vista parametrizada en all_parameterized_views
, asegúrese de que la vista parametrizada contenga al menos un parámetro de vista con nombre en su definición.
Siguientes pasos
- Consulta información sobre las vistas seguras parametrizadas.
- Consulta cómo proteger y controlar el acceso a los datos de las aplicaciones mediante vistas seguras parametrizadas.