SecStoreAcademic Lab
Relatório Acadêmico de Segurança da Informação

Arquitetura de Segurança & Manual de Testes de Penetração

Esta documentação detalha os controles de segurança implementados na aplicação SecStore para a disciplina de Segurança da Informação, cobrindo o modelo de ameaças, salvaguardas técnicas e o roteiro de testes de auditoria.

1. Arquitetura da Aplicação

A aplicação adota uma arquitetura Serverless baseada em Next.js App Router executada sobre o runtime global da Cloudflare Workers / Pages, integrado ao banco de dados relacional Cloudflare D1 (SQLite distribuído na borda).

Runtime Edge (Cloudflare)

Execução server-side rápida, isolada V8 isolates sem dependências nativas legadas, reduzindo a superfície de ataque no servidor.

Zero Third-Party Backend

Toda a regra de negócio, autenticação e recálculo de checkout ocorrem dentro do próprio contorno de segurança da aplicação.

2. Autenticação e Hash de Senhas

Senhas nunca são armazenadas ou trafegadas em texto puro. Utiliza-se o algoritmo padrão da indústria PBKDF2-HMAC-SHA256 com 100.000 iterações e um salt aleatório de 16 bytes gerado individualmente por usuário via crypto.getRandomValues().

Exemplo Inseguro (Vulnerável a Leitura de Banco e Rainbow Tables)✕ Vulnerável (Exemplo Acadêmico)
// ✕ VULNERÁVEL: Armazenar senha em MD5 ou texto puro
const query = `INSERT INTO users (email, password) VALUES ('${email}', '${password}')`;
// Se o banco for vazado, todas as senhas ficam expostas instantaneamente.
Implementação Segura (Implementada na SecStore)✓ Implementação Segura
// ✓ SEGURANÇA: Web Crypto API PBKDF2 (100.000 iterações + Salt de 16 bytes)
const keyMaterial = await crypto.subtle.importKey('raw', encoder.encode(password), { name: 'PBKDF2' }, false, ['deriveBits']);
const derivedBits = await crypto.subtle.deriveBits({ name: 'PBKDF2', salt, iterations: 100000, hash: 'SHA-256' }, keyMaterial, 256);
const storedHash = `pbkdf2:100000:${saltHex}:${hashHex}`;

3. Autorização e Prevenção de IDOR (Broken Access Control)

A vulnerabilidade IDOR (Insecure Direct Object Reference) ocorre quando uma aplicação confia no ID do recurso enviado na requisição pelo cliente sem verificar os direitos de propriedade da sessão.

Exemplo Inseguro (Vulnerável a IDOR / Broken Access Control)✕ Vulnerável (Exemplo Acadêmico)
// ✕ VULNERÁVEL: Qualquer usuário logado pode ler pedidos de terceiros trocando o ID na URL
app.get('/api/orders/:id', async (req, res) => {
  const order = await db.query('SELECT * FROM orders WHERE id = ?', [req.params.id]);
  return res.json(order); // Retorna dados sensíveis do pedido de outro usuário!
});
Implementação Segura (Implementada na SecStore)✓ Implementação Segura
// ✓ SEGURANÇA: Validação estrita de escopo (user_id === session.user_id) no banco D1
export async function getOrderByIdForUser(orderId: string, userId: string) {
  const order = await db
    .prepare('SELECT * FROM orders WHERE id = ? AND user_id = ?')
    .bind(orderId, userId)
    .first();
  if (!order) return null; // Retorna 404 neutro se não pertencer ao usuário
  return order;
}

4. Prevenção Contra SQL Injection (Prepared Statements)

100% das operações no Cloudflare D1 utilizam Prepared Statements (Queries Parametrizadas). A injeção de caracteres SQL especiais em campos de formulário (como ' OR 1=1 --) é tratada estritamente como literal de texto pela engine do banco.

Exemplo Inseguro (Vulnerável a SQL Injection)✕ Vulnerável (Exemplo Acadêmico)
// ✕ VULNERÁVEL: Concatenar strings permite alteração da lógica da instrução SQL
const sql = "SELECT * FROM users WHERE email = '" + req.body.email + "' AND password_hash = '" + hash + "'";
db.execute(sql); // Entrada "admin@test.com' --" anula a verificação de senha
Implementação Segura (Implementada na SecStore)✓ Implementação Segura
// ✓ SEGURANÇA: Cloudflare D1 Prepared Statement com vinculação de parâmetros
const user = await db
  .prepare('SELECT * FROM users WHERE email = ?')
  .bind(email.toLowerCase().trim())
  .first<User>();

5. Segurança do Checkout (Zero-Trust Client Pricing)

O navegador do cliente é um ambiente não confiável. O cliente envia unicamente a lista de { productId, quantity }. O servidor consulta o banco D1 para recuperar o preço unitário e o estoque atualizado antes de efetuar a cobrança e criar o pedido.

Segurança da API de Checkout (/api/checkout)✓ Implementação Segura
let serverCalculatedTotal = 0;
for (const item of items) {
  const product = await getProductById(item.productId); // Busca valor direto no D1
  if (product.stock < item.quantity) throw new Error('Estoque insuficiente');
  
  const realUnitPrice = Number(product.price); // Descarta o preço enviado pelo navegador
  serverCalculatedTotal += realUnitPrice * item.quantity;
}

6. Headers de Segurança HTTP

Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' ...

X-Content-Type-Options: nosniff

X-Frame-Options: DENY

Referrer-Policy: strict-origin-when-cross-origin

Permissions-Policy: camera=(), microphone=(), geolocation=()

Roteiro Prático de Auditoria

Guia de Testes de Segurança (Penetration Testing)

Instruções passo a passo para alunos realizarem testes controlados com ferramentas gratuitas (OWASP ZAP, Burp Suite, DevTools e cURL).

TESTE 01Acesso Não Autorizado a Pedido (IDOR / Broken Access Control)

  1. Faça login com o usuário Aluno (aluno@universidade.edu.br).
  2. Acesse o pedido de demonstração ord_aluno_demo_01 na página /orders/ord_aluno_demo_01.
  3. Abra uma janela anônima e faça login com o usuário Professor (professor@universidade.edu.br).
  4. Na sessão do Professor, tente acessar diretamente /orders/ord_aluno_demo_01 ou faça GET /api/orders/ord_aluno_demo_01.
  5. Resultado Esperado: O servidor responde com HTTP 404 (Not Found), impedindo o vazamento de dados do Aluno.

TESTE 02Manipulação de Preço no Cliente (Parameter Tampering)

  1. Adicione a YubiKey 5 NFC (R$ 350,00) ao carrinho e vá ao Checkout.
  2. Intercepte a requisição POST /api/checkout no Burp Suite ou DevTools Network.
  3. Injete o campo manipulado "price": 0.01 ou "total": 0.01 no JSON enviado.
  4. Submeta a requisição.
  5. Resultado Esperado: O servidor ignora o valor enviado, consulta o preço de R$ 350,00 no D1 e registra o pedido com o valor total real correto.

TESTE 03Injeção SQL (SQL Injection)

  1. Acesse a página de login em /login.
  2. No campo de e-mail, informe payloads de SQLi como admin@test.com' OR '1'='1 ou ' UNION SELECT NULL--.
  3. Submeta a autenticação.
  4. Resultado Esperado: A consulta parametrizada busca literalmente a string do e-mail. A aplicação responde 401 Credenciais inválidas sem disparar exceção SQL.

TESTE 04Ataque de Força Bruta (Rate Limiting Test)

  1. Execute 6 requisições de login consecutivas em menos de 1 minuto contra POST /api/auth/login.
  2. Resultado Esperado: A 6ª requisição é bloqueada com status HTTP 429 Too Many Requests.

Ferramentas Recomendadas para Auditoria Acadêmica

OWASP ZAP (Zed Attack Proxy)

Scanner gratuito para análise automatizada de headers, CSRF e varredura de vulnerabilidades web.

Burp Suite Community Edition

Proxy de interceptação HTTP para inspecionar e alterar requisições antes que cheguem ao servidor.