Segurança em Banco de Dados

Do Banco "Livro Aberto" ao Cofre Inquebrável

Material prático completo para condução em sala de aula. Aprenda a ocultar colunas confidenciais com VIEWS, gerenciar privilégios com DCL (GRANT/REVOKE) e blindar registros no nível de linha com RLS (Row Level Security) no PostgreSQL/Supabase.

PostgreSQL / Supabase 3 Camadas de Defesa 32 Exercícios Individuais

Objetivos da Aula

  • Criar e remover tabelas virtuais (`CREATE VIEW`).
  • Conceder e revogar acessos com DCL (`GRANT/REVOKE`).
  • Ativar RLS nativo e criar políticas (`CREATE POLICY`).
  • Garantir conformidade com a LGPD em APIs Front-End.
Conceito Fundamental

Defesa em Profundidade (Security Funnel)

01

Camada 1: VIEWS

Ocultamento de Colunas

Tabelas virtuais baseadas em seleções. Escondem colunas ultrassensíveis (como hashes de senhas, salários e dados fiscais) antes de expor os dados aos usuários ou sistemas.

02

Camada 2: DCL

GRANT & REVOKE

Linguagem de Controle de Dados. Define quem pode acessar quais objetos físicos (tabelas e views) e proíbe ações destrutivas como `DELETE` ou `DROP` por perfis não autorizados.

03

Camada 3: RLS

Row Level Security

Segurança em Nível de Linha nativa. O SGBD intercepta todas as consultas e injeta dinamicamente regras baseadas no `auth.uid()`, garantindo que um cliente só enxergue suas próprias linhas.

Demonstração ao Vivo

Exemplo Prático Guiado (Para Apresentar aos Alunos)

Cenário do Problema: Sistema Corporativo TechCorp

A empresa contratou um estagiário de RH. Ele precisa acessar a tabela de funcionários para ver os e-mails e cargos, mas nessa *mesma* tabela estão os salários confidenciais dos Diretores. Além disso, no aplicativo de autoatendimento, um funcionário não pode ver o holerite ou pedidos de outro colega.

PASSO 01

Criação das Tabelas de Teste com Dados Mistos

Estrutura Inicial

Executamos a criação da tabela de dados brutos. Observe que dados abertos (`nome`, `email`) residem na mesma tabela que dados sigilosos (`salario`, `cpf`).

-- 1. Tabela Principal de Funcionários (Dados Confidenciais)
CREATE TABLE funcionarios (
    id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    nome VARCHAR(100) NOT NULL,
    email VARCHAR(100) NOT NULL,
    cargo VARCHAR(50) NOT NULL,
    cpf VARCHAR(14) NOT NULL,
    salario DECIMAL(10, 2) NOT NULL
);

-- Inserindo dados de exemplo
INSERT INTO funcionarios (nome, email, cargo, cpf, salario) VALUES
('Carlos Silva', 'carlos@techcorp.com', 'Dev Senior', '123.456.789-00', 12500.00),
('Ana Souza', 'ana@techcorp.com', 'Estagiário RH', '234.567.890-11', 2200.00),
('Roberto Lima', 'roberto@techcorp.com', 'Diretor CTO', '345.678.901-22', 35000.00);

Risco do "Banco Livro Aberto"

Se dermos acesso direto a essa tabela para a API do Front-End ou para o usuário estagiário, um simples SELECT * FROM funcionarios exporá a coluna salario.

Status: ⚠️ Tabela física vulnerável sem restrições.
PASSO 02

Criando a Tabela Virtual (`CREATE VIEW`)

Filtro Estrutural de Colunas

Criamos uma visão chamada vw_funcionarios_rh. Ela projeta somente as colunas não-sensíveis.

-- 2. Criando a Visão para o Setor de RH (Ocultando CPF e Salário)
CREATE VIEW vw_funcionarios_rh AS
SELECT 
    id, 
    nome, 
    email, 
    cargo
FROM funcionarios;

-- Consultando a VIEW como se fosse uma tabela física:
SELECT * FROM vw_funcionarios_rh;

-- Para remover a visão caso necessário:
-- DROP VIEW vw_funcionarios_rh;

O Espelho Seguro

A VIEW funciona como um espelho. Ela não ocupa espaço extra em disco salvando dados duplicados. O usuário consulta a VIEW sem saber que as colunas cpf e salario existem.

✓ Colunas restritas com sucesso!
PASSO 03

Controle de Privilégios com DCL (`GRANT` e `REVOKE`)

Gerenciamento de Chaves

Não adianta criar a VIEW se a role/usuário continuar com permissão de acessar a tabela original. Usamos DCL para confiscar o acesso à tabela bruta e conceder somente a leitura na VIEW.

-- 3. Criando uma Role (Perfil) para o Estagiário
CREATE ROLE perfil_estagiario_rh WITH LOGIN PASSWORD 'SenhaSegura123';

-- Confiscando qualquer acesso direto à tabela confidencial original
REVOKE ALL ON TABLE funcionarios FROM perfil_estagiario_rh;

-- Concedendo permissão APENAS de consulta (SELECT) na VIEW criada
GRANT SELECT ON vw_funcionarios_rh TO perfil_estagiario_rh;

Principio do Menor Privilégio

  • • GRANT: Concede direitos (SELECT, INSERT, UPDATE, DELETE).
  • • REVOKE: Confisca permissões previamente dadas.
Regra: Perfil estagiario não pode fazer DELETE nem ler a tabela original.
PASSO 04

Blindagem de Linha Nátiva com RLS e Supabase Policies

Row Level Security

E quando o usuário precisa ver a tabela completa de pedidos, porém apenas as linhas que pertencem a ele? Ativamos o RLS e criamos uma política validando a ID do usuário logado.

-- 4. Criando tabela de Pedidos associada aos Usuários
CREATE TABLE pedidos (
    id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    id_usuario UUID NOT NULL,
    descricao VARCHAR(200) NOT NULL,
    valor DECIMAL(10, 2) NOT NULL
);

-- PASSO CRÍTICO: Ativando a Segurança em Nível de Linha (RLS)
ALTER TABLE pedidos ENABLE ROW LEVEL SECURITY;

-- Criando a Política (Policy) no PostgreSQL / Supabase:
CREATE POLICY "Usuarios enxergam apenas seus proprios pedidos"
ON pedidos
FOR SELECT
USING (auth.uid() = id_usuario);

Reescrita Silenciosa de Queries

Quando a API envia:
SELECT * FROM pedidos;

O PostgreSQL com RLS reescreve internamente para:
WHERE id_usuario = auth.uid();

Shield Ativado: 0% de risco de vazamento entre clientes!
Recurso Didático para Lousa

Simulador de Visão de Dados (Veja o Efeito da Segurança)

Interativo
Selecione a Visão:
Query em Execução: SELECT * FROM funcionarios;
Vulnerável
ID NOME EMAIL CARGO CPF SALÁRIO
Mostrando todos os registros e colunas sem restrição. Risco alto de vazamento.
32 ALUNOS Atividade Individual de Fixação

32 Exercícios Práticos com Temas Únicos