Skip to content

Security: amaurell/refund

Security

SECURITY.md

🔒 Documentação de Segurança (OWASP)

Visão Geral

Este documento detalha todas as medidas de segurança implementadas no sistema Refund, seguindo as diretrizes do OWASP Top 10 2021.


🛡️ OWASP Top 10 - Implementações

A01:2021 - Broken Access Control

Risco: Usuários podem acessar recursos não autorizados.

Mitigações Implementadas:

  • ✅ Validação de IDs antes de operações
  • ✅ Confirmação de ações destrutivas (remoção)
  • ✅ Sem exposição de dados sensíveis no localStorage

Código:

// ExpenseListController.js
handleRemove(id) {
  const confirmed = confirm('Deseja realmente remover esta despesa?');
  if (!confirmed) return;
  // ...
}

Recomendações Futuras:

  • Implementar autenticação de usuários
  • Controle de acesso baseado em roles (RBAC)
  • Auditoria de ações

A02:2021 - Cryptographic Failures

Risco: Dados sensíveis expostos ou mal protegidos.

Mitigações Implementadas:

  • ✅ Dados armazenados localmente (sem transmissão)
  • ✅ Sem armazenamento de dados sensíveis (senhas, tokens)
  • ✅ Preparado para HTTPS em produção

Recomendações Futuras:

  • Criptografia de dados no localStorage
  • HTTPS obrigatório
  • Hashing de dados sensíveis

A03:2021 - Injection

Risco: Injeção de código malicioso (XSS, SQL Injection).

Mitigações Implementadas:

1. Sanitização de Inputs

// InputValidator.js
static sanitizeString(input) {
  // Remove tags HTML
  let sanitized = input.replace(/<[^>]*>/g, '');
  
  // Remove caracteres de controle
  sanitized = sanitized.replace(/[\x00-\x1F\x7F]/g, '');
  
  // Normaliza espaços
  sanitized = sanitized.trim().replace(/\s+/g, ' ');
  
  return sanitized;
}

2. Validação com Whitelist

// InputValidator.js
static validateCategory(categoryId, allowedCategories = []) {
  // Apenas categorias na whitelist são aceitas
  if (!allowedCategories.includes(sanitized)) {
    return { valid: false, error: 'Categoria inválida' };
  }
}

3. Manipulação Segura do DOM

// DOMHelper.js
static setTextContent(element, text) {
  // Usa textContent ao invés de innerHTML
  element.textContent = text;
}

static setInnerHTML(element, html) {
  // Remove scripts e eventos inline
  const sanitized = html
    .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
    .replace(/on\w+="[^"]*"/gi, '');
  element.innerHTML = sanitized;
}

Proteções:

  • ✅ XSS (Cross-Site Scripting)
  • ✅ HTML Injection
  • ✅ Script Injection

A04:2021 - Insecure Design

Risco: Falhas fundamentais de design de segurança.

Mitigações Implementadas:

  • ✅ Arquitetura em camadas com separação de responsabilidades
  • ✅ Validação em múltiplas camadas (UI, Service, Model)
  • ✅ Princípio do menor privilégio
  • ✅ Fail-safe defaults (validação rejeita por padrão)

Design Seguro:

// Validação em camadas
1. UI: Validação básica
2. Service: Validação de negócio
3. Model: Validação de integridade
4. Repository: Validação de persistência

A05:2021 - Security Misconfiguration

Risco: Configurações inseguras ou padrões.

Mitigações Implementadas:

1. Content Security Policy (CSP)

// app.js
setupSecurityHeaders() {
  const cspMeta = document.createElement('meta');
  cspMeta.httpEquiv = 'Content-Security-Policy';
  cspMeta.content = "default-src 'self'; script-src 'self'; ...";
  document.head.appendChild(cspMeta);
}

2. Security Headers

<!-- index.html -->
<meta http-equiv="X-Content-Type-Options" content="nosniff" />
<meta http-equiv="X-Frame-Options" content="DENY" />
<meta name="referrer" content="strict-origin-when-cross-origin" />

Headers Implementados:

  • X-Content-Type-Options: nosniff - Previne MIME sniffing
  • X-Frame-Options: DENY - Previne clickjacking
  • Referrer-Policy - Controla informações de referrer
  • Content-Security-Policy - Restringe recursos

A06:2021 - Vulnerable and Outdated Components

Risco: Uso de bibliotecas vulneráveis.

Mitigações Implementadas:

  • ✅ Sem dependências externas (Vanilla JS)
  • ✅ Código próprio e auditável
  • ✅ Uso apenas de APIs nativas do navegador

Recomendações Futuras:

  • Auditoria regular de dependências (se adicionar)
  • Uso de ferramentas como npm audit
  • Manter dependências atualizadas

A07:2021 - Identification and Authentication Failures

Risco: Falhas em autenticação e gerenciamento de sessão.

Status Atual:

  • ⚠️ Sem autenticação (aplicação local)

Preparação para Autenticação:

// Estrutura preparada para adicionar autenticação
class AuthService {
  login(credentials) {
    // Validação robusta
    // Hash de senha
    // Geração de token seguro
  }
  
  logout() {
    // Limpeza de sessão
  }
}

Recomendações Futuras:

  • Implementar autenticação JWT
  • Rate limiting para login
  • Bloqueio após tentativas falhadas
  • Senhas com requisitos mínimos
  • MFA (Multi-Factor Authentication)

A08:2021 - Software and Data Integrity Failures

Risco: Código ou dados comprometidos.

Mitigações Implementadas:

1. Validação de Dados

// Expense.js
validate() {
  const errors = [];
  
  if (!this.expense || this.expense.trim().length === 0) {
    errors.push('Nome da despesa é obrigatório');
  }
  
  if (this.amount <= 0) {
    errors.push('Valor deve ser maior que zero');
  }
  
  return { valid: errors.length === 0, errors };
}

2. Tratamento de Erros

// LocalStorageAdapter.js
save(key, data) {
  try {
    const serializedData = JSON.stringify(data);
    localStorage.setItem(key, serializedData);
  } catch (error) {
    console.error('Erro ao salvar:', error);
    throw new Error('Não foi possível salvar os dados');
  }
}

Proteções:

  • ✅ Validação antes de persistir
  • ✅ Tratamento de erros de serialização
  • ✅ Verificação de integridade de dados

Recomendações Futuras:

  • Subresource Integrity (SRI) para CDNs
  • Assinatura digital de dados
  • Versionamento de dados

A09:2021 - Security Logging and Monitoring Failures

Risco: Falta de logging e monitoramento.

Implementações Atuais:

// Logging de erros
console.error('Erro ao criar despesa:', error);
console.warn('Evento desconhecido:', event);

Recomendações Futuras:

  • Sistema de logging estruturado
  • Monitoramento de erros (Sentry, LogRocket)
  • Auditoria de ações do usuário
  • Alertas de segurança
  • Retenção de logs

Exemplo de Implementação Futura:

class Logger {
  static log(level, message, context) {
    const entry = {
      timestamp: new Date().toISOString(),
      level,
      message,
      context,
      userId: getCurrentUser()?.id
    };
    
    // Enviar para servidor de logs
    sendToLogServer(entry);
  }
}

A10:2021 - Server-Side Request Forgery (SSRF)

Risco: Servidor faz requisições não autorizadas.

Status Atual:

  • ✅ Aplicação client-side apenas
  • ✅ Sem requisições a servidores externos
  • ✅ Sem processamento de URLs fornecidas pelo usuário

Preparação para Backend:

// Validação de URLs (quando implementar backend)
class URLValidator {
  static isAllowed(url) {
    const allowedDomains = ['api.example.com'];
    const parsed = new URL(url);
    return allowedDomains.includes(parsed.hostname);
  }
}

🔐 Práticas Adicionais de Segurança

1. Input Validation

Princípios:

  • ✅ Validar no cliente E servidor (quando implementar)
  • ✅ Whitelist ao invés de blacklist
  • ✅ Validação de tipo, tamanho e formato
  • ✅ Rejeitar por padrão

Exemplo:

// Whitelist de categorias
const ALLOWED_CATEGORIES = ['food', 'accommodation', 'services', 'transport', 'others'];

if (!ALLOWED_CATEGORIES.includes(category)) {
  throw new Error('Categoria inválida');
}

2. Output Encoding

Princípios:

  • ✅ Usar textContent ao invés de innerHTML
  • ✅ Escapar HTML quando necessário
  • ✅ Sanitizar antes de renderizar

Exemplo:

// Seguro
element.textContent = userInput;

// Inseguro
element.innerHTML = userInput; // ❌ Vulnerável a XSS

3. Error Handling

Princípios:

  • ✅ Não expor detalhes técnicos ao usuário
  • ✅ Logar erros para debug
  • ✅ Mensagens genéricas para o usuário

Exemplo:

try {
  // Operação
} catch (error) {
  console.error('Erro técnico:', error); // Para debug
  alert('Não foi possível completar a operação'); // Para usuário
}

4. Rate Limiting (Preparação)

class RateLimiter {
  constructor(maxAttempts, windowMs) {
    this.maxAttempts = maxAttempts;
    this.windowMs = windowMs;
    this.attempts = new Map();
  }
  
  isAllowed(key) {
    const now = Date.now();
    const userAttempts = this.attempts.get(key) || [];
    
    // Remove tentativas antigas
    const recentAttempts = userAttempts.filter(
      time => now - time < this.windowMs
    );
    
    if (recentAttempts.length >= this.maxAttempts) {
      return false;
    }
    
    recentAttempts.push(now);
    this.attempts.set(key, recentAttempts);
    return true;
  }
}

📋 Checklist de Segurança

Implementado ✅

  • Sanitização de inputs
  • Validação com whitelist
  • Proteção contra XSS
  • Content Security Policy
  • Security Headers
  • Manipulação segura do DOM
  • Validação em múltiplas camadas
  • Tratamento de erros
  • Confirmação de ações destrutivas
  • Sem dependências vulneráveis

Recomendado para Produção 🔮

  • HTTPS obrigatório
  • Autenticação de usuários
  • Autorização baseada em roles
  • Rate limiting
  • Logging estruturado
  • Monitoramento de segurança
  • Criptografia de dados sensíveis
  • Backup e recuperação
  • Testes de penetração
  • Auditoria de segurança

🧪 Testes de Segurança

Testes Manuais

  1. XSS Testing
// Tentar injetar script
Nome: <script>alert('XSS')</script>
Resultado esperado: Script não executado, texto sanitizado
  1. HTML Injection
// Tentar injetar HTML
Nome: <img src=x onerror=alert('XSS')>
Resultado esperado: Tags removidas
  1. SQL Injection (N/A - sem banco de dados)

  2. CSRF (N/A - sem autenticação)

Testes Automatizados (Futuro)

describe('Security Tests', () => {
  it('should sanitize XSS attempts', () => {
    const malicious = '<script>alert("XSS")</script>';
    const sanitized = InputValidator.sanitizeString(malicious);
    expect(sanitized).not.toContain('<script>');
  });
  
  it('should reject invalid categories', () => {
    const result = InputValidator.validateCategory('invalid');
    expect(result.valid).toBe(false);
  });
});

📚 Referências


🎓 Educação em Segurança

Princípios Fundamentais

  1. Defense in Depth - Múltiplas camadas de segurança
  2. Least Privilege - Mínimo acesso necessário
  3. Fail Secure - Falhar de forma segura
  4. Don't Trust User Input - Nunca confiar em dados do usuário
  5. Security by Design - Segurança desde o início

Recursos de Aprendizado


Última atualização: 2026-02-16

Nível de Segurança Atual: 🟢 Bom (para aplicação client-side)

Próximos Passos: Implementar autenticação e backend seguro

There aren’t any published security advisories