Este documento descreve as medidas de segurança implementadas no projeto ICTI Share.
- Sanitização de Inputs
- Rate Limiting
- Proteção CSRF
- Headers de Segurança
- Validação de Arquivos
- Proteção contra SQL Injection
- Configurações
Todos os inputs do usuário são sanitizados antes de serem processados ou armazenados no banco de dados.
Localização: lib/security/sanitize.ts
sanitizeString(input: string): Remove caracteres perigosos e tags HTMLsanitizeObject<T>(obj: T): Sanitiza todos os campos string de um objetosanitizeFilename(filename: string): Sanitiza nomes de arquivosanitizeEmail(email: string): Normaliza e sanitiza emails
- ✅ Formulários de autenticação (signup/login)
- ✅ Upload de materiais
- ✅ Edição de materiais
- ✅ Edição de perfil
import { sanitizeString } from "@/lib/security/sanitize";
const userInput = formData.get("title") as string;
const sanitized = sanitizeString(userInput); // Remove caracteres perigososSistema de rate limiting em memória para prevenir abuso de endpoints críticos.
Localização: lib/security/rate-limit.ts
AUTH: {
windowMs: 15 * 60 * 1000, // 15 minutos
maxRequests: 5, // 5 tentativas
}
DOWNLOAD: {
windowMs: 60 * 1000, // 1 minuto
maxRequests: 20, // 20 downloads
}
UPLOAD: {
windowMs: 60 * 60 * 1000, // 1 hora
maxRequests: 5, // 5 uploads
}- ✅
/app/actions/auth.ts- Login e Signup (5 tentativas / 15 min) - ✅
/app/material/download/[id]/route.ts- Downloads (20 / minuto) - ✅
/app/actions/upload.ts- Uploads (5 / hora)
O rate limiting identifica usuários por:
- IP (para usuários não autenticados)
- User ID (para usuários autenticados - mais restritivo)
{
"error": "Muitas requisições. Tente novamente mais tarde.",
"status": 429
}Headers incluídos:
Retry-After: Tempo em segundos até poder tentar novamenteX-RateLimit-Remaining: Requisições restantesX-RateLimit-Reset: Timestamp de reset
O rate limiting atual usa armazenamento em memória (Map). Para produção com múltiplos servidores, considere usar:
- Redis para armazenamento distribuído
- Upstash Rate Limit (solução gerenciada)
- Vercel Edge Config (se hospedado na Vercel)
A proteção CSRF é gerenciada automaticamente pelo NextAuth v5.
- NextAuth gera tokens CSRF únicos por sessão
- Tokens são validados automaticamente em todas as requisições autenticadas
- Server Actions do Next.js têm proteção CSRF nativa
✅ Não é necessário implementar manualmente - NextAuth cuida disso automaticamente.
Headers de segurança são aplicados em todas as respostas via middleware.
Localização: lib/security/headers.ts e middleware.ts
| Header | Valor | Descrição |
|---|---|---|
X-Frame-Options |
DENY |
Previne clickjacking |
X-Content-Type-Options |
nosniff |
Previne MIME type sniffing |
X-XSS-Protection |
1; mode=block |
Habilita proteção XSS (legado) |
Referrer-Policy |
strict-origin-when-cross-origin |
Controla informações de referrer |
Permissions-Policy |
camera=(), microphone=(), ... |
Desabilita recursos sensíveis |
Content-Security-Policy |
(ver abaixo) | Política de segurança de conteúdo |
default-src 'self';
script-src 'self' 'unsafe-eval' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self' data:;
connect-src 'self';
frame-ancestors 'none';
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self' data:;
connect-src 'self';
frame-ancestors 'none';
base-uri 'self';
form-action 'self';
Para ajustar os headers, edite lib/security/headers.ts:
export function getSecurityHeaders(): SecurityHeaders {
const headers: SecurityHeaders = {
// Adicione ou modifique headers aqui
"X-Custom-Header": "value",
};
return headers;
}Validação multi-camada para prevenir upload de arquivos maliciosos.
Localização: lib/security/file-validation.ts
-
Tamanho do Arquivo
- Máximo: 25 MB
- Mínimo: > 0 bytes
-
Nome do Arquivo
- Remove caracteres perigosos (
<>:"|?*e caracteres de controle) - Previne path traversal (
..,/,\) - Limita tamanho (255 caracteres)
- Remove caracteres perigosos (
-
Extensão
- Apenas
.pdfpermitido - Case-insensitive
- Apenas
-
MIME Type
- Apenas
application/pdfpermitido - Validado do header do arquivo
- Apenas
-
Magic Bytes (Conteúdo)
- Verifica os primeiros bytes do arquivo
- PDF deve começar com
%PDF(hex:25504446) - Previne arquivos com extensão falsa
import { validateFile } from "@/lib/security/file-validation";
const result = await validateFile(file);
if (!result.valid) {
return { error: result.error };
}- ✅ Upload de materiais (
app/actions/upload.ts)
Prisma ORM previne SQL injection automaticamente usando prepared statements.
- Prisma usa parameterized queries por padrão
- Todos os valores são escapados automaticamente
- Não é necessário sanitizar manualmente para queries Prisma
// ✅ Seguro - Prisma escapa automaticamente
await prisma.user.findUnique({
where: { email: userInput }, // Prisma escapa isso
});
// ❌ NUNCA faça isso (não é necessário com Prisma)
// const query = `SELECT * FROM users WHERE email = '${userInput}'`;- ✅ Sempre use Prisma para queries
- ✅ Valide inputs com Zod antes de usar no Prisma
- ✅ Sanitize inputs para prevenir XSS (mesmo que Prisma proteja contra SQL injection)
Nenhuma variável de ambiente adicional é necessária para as funcionalidades de segurança básicas.
Se usar múltiplos servidores, configure Redis:
REDIS_URL=redis://localhost:6379E atualize lib/security/rate-limit.ts para usar Redis em vez de Map.
Para HTTPS em produção, configure HSTS no servidor/proxy:
# Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;# Apache
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"| Medida | Status | Localização |
|---|---|---|
| Sanitização de Inputs | ✅ | lib/security/sanitize.ts |
| Rate Limiting | ✅ | lib/security/rate-limit.ts |
| CSRF Protection | ✅ | NextAuth (automático) |
| Security Headers | ✅ | lib/security/headers.ts |
| Validação de Arquivos | ✅ | lib/security/file-validation.ts |
| SQL Injection Protection | ✅ | Prisma ORM (automático) |
- Verificar que todas as variáveis de ambiente estão configuradas
- Revisar CSP para garantir que não bloqueia recursos necessários
- Testar rate limiting em ambiente de staging
- Verificar que uploads de arquivos estão sendo validados corretamente
- Confirmar que headers de segurança estão sendo aplicados
- Testar proteção CSRF (NextAuth)
- Verificar logs de segurança
- Monitorar tentativas de rate limiting (429 errors)
- Logs de uploads rejeitados
- Tentativas de login falhadas
- Anomalias em downloads
Ajuste os limites em lib/security/rate-limit.ts:
export const RATE_LIMIT_CONFIGS = {
AUTH: {
windowMs: 15 * 60 * 1000,
maxRequests: 10, // Aumentar limite
},
// ...
};Ajuste em lib/security/headers.ts:
function getCSP(): string {
return [
"default-src 'self'",
"script-src 'self' https://cdn.example.com", // Adicionar origem permitida
// ...
].join("; ");
}Verifique:
- Tamanho do arquivo (máx. 25 MB)
- Tipo MIME (
application/pdf) - Extensão (
.pdf) - Magic bytes (arquivo deve ser PDF válido)
Última atualização: 2024