CodeGym /Cursos /SQL SELF /Errores comunes al configurar la seguridad y cómo evitarl...

Errores comunes al configurar la seguridad y cómo evitarlos

SQL SELF
Nivel 48 , Lección 4
Disponible

La seguridad de la base de datos es como una buena contraseña: puedes inventar la clave más complicada, pero si la apuntas en un post-it y la pegas en el monitor — no sirve de nada. Así que nuestro objetivo es aprender no solo a configurar mecanismos de protección, sino también a evitar los errores típicos que pueden tirar todo el esfuerzo por la borda.

1. Uso de roles con permisos excesivos

Muchas veces los desarrolladores tienen miedo de limitar el acceso y crean roles con privilegios muy amplios, por ejemplo, dando permisos de SUPERUSER o ALL PRIVILEGES. Su argumento suele ser: "Bueno, ¡por si acaso lo necesito!". Pero los roles con permisos de más se convierten en un agujero enorme de seguridad.

Ejemplo de permisos excesivos:

GRANT ALL PRIVILEGES ON DATABASE universidad TO rol_estudiante;

En este caso, rol_estudiante tiene acceso total a todos los datos de la base. Incluso si el rol solo debía leer datos, ahora puede borrar tablas, cambiar la estructura e incluso quitarle el acceso al admin.

¿Cómo evitarlo?

Crea roles con el mínimo de permisos posible. Esto se llama el principio de privilegios mínimos. Por ejemplo, un rol solo para leer datos debería ser así:
GRANT CONNECT ON DATABASE universidad TO rol_estudiante;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO rol_estudiante;

Este enfoque deja claro qué puede hacer el rol rol_estudiante: conectarse a la base y solo leer.

2. Falta de cifrado de datos confidenciales

Imagina una tabla usuarios donde guardamos contraseñas en texto plano:

CREATE TABLE usuarios (
    id SERIAL PRIMARY KEY,
    nombre_usuario TEXT NOT NULL,
    contraseña TEXT NOT NULL
);

Si un atacante consigue acceso a esta tabla, se lleva las contraseñas de todos los usuarios. Es como guardar las llaves de casa debajo del felpudo.

Para evitarlo, usa cifrado de contraseñas con pgcrypto. Por ejemplo:

CREATE EXTENSION IF NOT EXISTS pgcrypto;

INSERT INTO usuarios (nombre_usuario, contraseña)
VALUES ('johndoe', pgp_sym_encrypt('contraseña_segura', 'clave_cifrado'));

Para comprobar la contraseña puedes usar descifrado:

SELECT nombre_usuario
FROM usuarios
WHERE pgp_sym_decrypt(contraseña::BYTEA, 'clave_cifrado') = 'contraseña_segura';

¡Nunca guardes información confidencial en texto plano!

3. Ignorar SQL-injection

Las SQL-injection siguen siendo uno de los métodos de ataque más comunes, y la razón es que los desarrolladores siguen construyendo queries usando interpolación de strings. Mira este ejemplo:

DO $$
DECLARE
    nombre_usuario TEXT := 'John';
    consulta TEXT;
BEGIN
    consulta := 'SELECT * FROM usuarios WHERE nombre_usuario = ''' || nombre_usuario || ''';';
    EXECUTE consulta;
END $$;

Si el atacante en vez del nombre pone John' OR '1'='1, el resultado será que se filtran todos los datos de la tabla usuarios.

¿Cómo evitarlo? Usa consultas parametrizadas:

PREPARE consulta_usuario (TEXT) AS
SELECT * FROM usuarios WHERE nombre_usuario = $1;

EXECUTE consulta_usuario('John');

Aquí la variable se mete de forma segura, sin posibilidad de inyección.

4. Mala configuración de pg_hba.conf

pg_hba.conf es la herramienta principal para controlar el acceso por IP. Los errores aquí pueden hacer que el acceso esté mucho más abierto de lo que debería.

Ejemplo de mala configuración:

host    all     all     0.0.0.0/0       trust

Esta línea permite que cualquier usuario se conecte a cualquier base de datos desde cualquier IP sin poner contraseña.

¿Cómo evitarlo? Configura el acceso solo para IPs concretas y usa métodos de autenticación como md5 o scram-sha-256:

host    universidad    rol_estudiante    192.168.1.0/24    md5

Esto limita el acceso de rol_estudiante solo desde la red local y con contraseña.

Después de cambiar pg_hba.conf, no te olvides de aplicar los cambios con el comando:

pg_ctl reload

5. Uso incorrecto de ROW LEVEL SECURITY

RLS es una herramienta potente, pero no sirve de nada si la configuras mal o te olvidas de activarla. Por ejemplo, aunque escribas la política de acceso, no funcionará si RLS está apagado:

CREATE POLICY mi_politica ON usuarios
USING (nombre_usuario = current_user);

-- ¡Pero RLS no está activado!
SELECT * FROM usuarios; -- ¡Vas a ver todas las filas!

¿Cómo evitarlo? No te olvides de activar RLS:

ALTER TABLE usuarios ENABLE ROW LEVEL SECURITY;

Y revisa cómo se aplica la política:

SET ROLE rol_estudiante;

SELECT * FROM usuarios; -- Solo ves las filas que cumplen la política.

6. Acciones de administradores no controladas

A veces los administradores de la base tienen acceso total a todos los datos, aunque no lo necesiten para su trabajo. Esto crea un riesgo extra de fuga si la cuenta admin se ve comprometida.

¿Cómo evitarlo? Usa separación de roles. Para tareas de administración crea un rol aparte sin acceso a los datos:

CREATE ROLE rol_admin WITH LOGIN CREATEDB CREATEROLE;

Para acceso a datos crea otro rol con permisos mínimos:

CREATE ROLE rol_analista_datos;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO rol_analista_datos;

Asigna los roles al usuario según lo que tenga que hacer:

GRANT rol_admin TO algun_usuario;
GRANT rol_analista_datos TO otro_usuario;

7. Logging insuficiente

Si no configuras el logging, no te vas a enterar de acciones sospechosas hasta que sea demasiado tarde.

Ejemplo de falta de logging:

-- Ninguna configuración en el archivo postgresql.conf
log_statement = 'none';

¿Cómo evitarlo? Activa al menos el logging básico:

log_statement = 'all'
log_connections = on
log_disconnections = on

Así vas a ver todas las queries, conexiones y desconexiones.

También puedes configurar auditoría con la extensión pgAudit para un control más detallado:

CREATE EXTENSION pgaudit;

8. Uso de métodos de autenticación obsoletos

Usar métodos de autenticación antiguos como password no da suficiente protección.

¿Cómo evitarlo? Pásate a métodos más seguros como scram-sha-256:

ALTER SYSTEM SET password_encryption = 'scram-sha-256';

Y actualiza las contraseñas de los usuarios:

ALTER USER rol_estudiante WITH PASSWORD 'contraseña_segura_nueva';

Estos problemas pueden parecer pequeños, pero cualquiera de ellos puede convertirse en un agujero de seguridad serio. Tu tarea es llevar la base de datos como si cada usuario que intenta conectarse fuera sospechoso. Como se suele decir, "confía, pero verifica". Ahora tienes herramientas no solo para configurar la seguridad, sino también para evitar los errores más comunes. ¡Atrapa la suerte por la cola y que tus datos estén siempre seguros!

1
Cuestionario/control
Introducción al cifrado de datos, nivel 48, lección 4
No disponible
Introducción al cifrado de datos
Introducción al cifrado de datos
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION