Guia de segurança¶
A AMRnet implementa medidas de segurança abrangentes para proteger os dados dos usuários e garantir a integridade da informação de vigilância de resistência antimicrobiana. Este guia abrange políticas de segurança, melhores práticas e detalhes de implementação.
Política de Segurança¶
A AMRnet segue práticas de segurança padrão da indústria para aplicações web que manipulam dados sensíveis de saúde e pesquisa.
Relatório de vulnerabilidades¶
🚨 Processo de Divulgação Responsável
Se você descobrir uma vulnerabilidade de segurança, por favor, siga estes passos:
NÃO crie uma issue pública no GitHub
Relatório de segurança do e-mail para: amrnetdashboard@gmail.com
Incluir informações detalhadas: - Descrição da vulnerabilidade - Etapas para reproduzir o problema - Avaliação de impacto potencial - Correções sugeridas (se disponível)
Linha do tempo de resposta:
24 horas: Confirmação inicial
72 horas: Classificação preliminar de avaliação e gravidade
7 dias: resposta detalhada com correção da linha do tempo
30 dias: Resolução de alvos para vulnerabilidades críticas
Versões suportadas¶
Atualizações de segurança fornecidas para:
Versão |
Suportado |
|---|---|
1.1.x |
✅ Sim |
1.0.x |
✅ Sim |
< 1.0 |
❌ Não |
Segurança do Aplicativo¶
O AMRnet implementa várias camadas de controles de segurança:
Segurança do Ambiente¶
Proteção de Variável de Ambiente:
# Never commit sensitive environment variables
# Use .env.example as template, create .env locally
# Production secrets management
NODE_ENV=production
MONGODB_URI=mongodb+srv://[REDACTED]
SESSION_SECRET=[GENERATED_SECRET]
# Security headers
ENABLE_SECURITY_HEADERS=true
CORS_ORIGIN=https://amrnet.org
Exemplo de configuração segura:
// config/security.js
const securityConfig = {
// HTTPS enforcement
httpsOnly: process.env.NODE_ENV === 'production',
// Security headers
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
fontSrc: ["'self'", "https://fonts.gstatic.com"],
imgSrc: ["'self'", "data:", "https:"],
scriptSrc: ["'self'"]
}
},
// Rate limiting
rateLimit: {
windowMs: 15 * 60 * 1000, // 15 minutes
max: 1000 // limit each IP to 1000 requests per windowMs
}
};
Segurança da base¶
Configuração de Segurança do MongoD:
// Secure MongoDB connection
const mongoOptions = {
useNewUrlParser: true,
useUnifiedTopology: true,
// Authentication
authSource: 'admin',
// SSL/TLS
ssl: true,
sslValidate: true,
// Connection limits
maxPoolSize: 10,
minPoolSize: 5,
// Timeouts
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 45000,
// Security options
bufferMaxEntries: 0,
bufferCommands: false
};
Sanitização de Dados:
const sanitize = require('mongo-sanitize');
const validator = require('validator');
// Input sanitization middleware
const sanitizeInput = (req, res, next) => {
// Sanitize against NoSQL injection
req.body = sanitize(req.body);
req.query = sanitize(req.query);
req.params = sanitize(req.params);
// Additional validation
Object.keys(req.query).forEach(key => {
if (typeof req.query[key] === 'string') {
req.query[key] = validator.escape(req.query[key]);
}
});
next();
};
Segurança da API¶
Autenticação e Autorização:
const jwt = require('jsonwebtoken');
const rateLimit = require('express-rate-limit');
// API rate limiting
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 1000, // limit each IP to 1000 requests per windowMs
message: 'Too many requests from this IP',
standardHeaders: true,
legacyHeaders: false,
});
// JWT authentication for protected endpoints
const authenticateToken = (req, res, next) => {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (!token) {
return res.sendStatus(401);
}
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
if (err) return res.sendStatus(403);
req.user = user;
next();
});
};
Configuração CORS:
const cors = require('cors');
const corsOptions = {
origin: function (origin, callback) {
const allowedOrigins = [
'https://amrnet.org',
'https://www.amrnet.org',
process.env.NODE_ENV === 'development' && 'http://localhost:3000'
].filter(Boolean);
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true,
optionsSuccessStatus: 200
};
Segurança no Frontend¶
Política de Segurança de Conteúdo:
<!-- Security headers in HTML -->
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
font-src 'self' https://fonts.gstatic.com;
img-src 'self' data: https:;">
Prevenção XSS:
import DOMPurify from 'dompurify';
// Sanitize user input before rendering
const SafeHTML = ({ content }) => {
const cleanHTML = DOMPurify.sanitize(content);
return <div dangerouslySetInnerHTML={{ __html: cleanHTML }} />;
};
// Input validation
const validateInput = (input) => {
if (typeof input !== 'string') return false;
if (input.length > 1000) return false;
// Check for malicious patterns
const maliciousPatterns = [
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
/javascript:/gi,
/on\w+\s*=/gi
];
return !maliciousPatterns.some(pattern => pattern.test(input));
};
Privacidade de Dados¶
A AMRnet implementa princípios de privacidade por design para lidar com dados de vigilância:
Classificação de Dados¶
Dados públicos: - Estatísticas agregadas de vigilância - Dados de prevalência a nível do país - Dados de pesquisa disponíveis publicamente
Dados restritos: - Amostra individual (quando presente) - Coordenadas geográficas detalhadas - Dados de pesquisa não publicados
Dados proibidos: - Informações pessoais de saúde (PHI) - Identificadores pacientes - Detalhes clínicos além dos padrões de resistência
Controles de Privacidade¶
Minimização de Dados:
// Example: Remove sensitive fields before transmission
const sanitizeDataForPublic = (data) => {
return data.map(record => ({
// Include only necessary fields
country: record.COUNTRY_ONLY,
year: record.YEAR,
genotype: record.GENOTYPE,
resistance: record.RESISTANCE_PROFILE,
// Exclude: individual IDs, precise coordinates, etc.
}));
};
Anonimização:
// Geographic aggregation for privacy
const aggregateByRegion = (data) => {
const aggregated = {};
data.forEach(record => {
const region = getRegionFromCountry(record.country);
if (!aggregated[region]) {
aggregated[region] = {
count: 0,
resistanceProfiles: {}
};
}
aggregated[region].count++;
// Aggregate resistance data without individual records
});
return aggregated;
};
Desenvolvimento Seguro¶
Práticas de segurança para o desenvolvimento e implantação:
Segurança do Código¶
Gerenciamento de Dependência:
# Regular security audits
npm audit
# Update vulnerable dependencies
npm audit fix
# Use lock files to prevent supply chain attacks
npm ci # Use exact versions from package-lock.json
Ligação de segurança:
# ESLint security plugin
npm install --save-dev eslint-plugin-security
# .eslintrc.js
module.exports = {
plugins: ['security'],
extends: ['plugin:security/recommended'],
rules: {
'security/detect-object-injection': 'error',
'security/detect-non-literal-regexp': 'error',
'security/detect-unsafe-regex': 'error'
}
};
Segurança Git¶
Práticas de Repositório Seguras:
# Git hooks for security
# pre-commit hook
#!/bin/sh
# Check for secrets in commits
git diff --cached --name-only | xargs grep -l "password\|secret\|key\|token" && {
echo "Potential secret detected! Commit aborted."
exit 1
}
# Run security linting
npm run lint:security
Gerenciamento de Segredos:
# .gitignore - Never commit sensitive files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# Security credentials
*.pem
*.key
*.crt
# Database dumps
*.sql
*.dump
Segurança de implantação¶
Configurações de segurança para a implantação da produção:
Segurança do Servidor¶
Cabeçalhos de Segurança:
const helmet = require('helmet');
app.use(helmet({
// Content Security Policy
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
fontSrc: ["'self'", "https://fonts.gstatic.com"],
imgSrc: ["'self'", "data:", "https:"],
scriptSrc: ["'self'"],
connectSrc: ["'self'", "https://api.amrnet.org"]
}
},
// Other security headers
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
},
frameguard: { action: 'deny' },
noSniff: true,
xssFilter: true,
referrerPolicy: { policy: 'same-origin' }
}));
Segurança de infraestrutura¶
Configuração HTTPS:
# Nginx SSL configuration
server {
listen 443 ssl http2;
server_name amrnet.org www.amrnet.org;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
# Security headers
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
}
Resposta Monitorada e de Incidente¶
Monitoramento contínuo de segurança e procedimentos de resposta ao incidente:
Monitoramento de Segurança¶
Registro e Alerta:
const winston = require('winston');
// Security event logging
const securityLogger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.File({ filename: 'logs/security.log' })
]
});
// Failed authentication attempts
const logFailedAuth = (req, ip, reason) => {
securityLogger.warn('Failed authentication attempt', {
ip: ip,
userAgent: req.get('User-Agent'),
reason: reason,
timestamp: new Date().toISOString()
});
};
Detecção de Intrusão:
// Suspicious activity detection
const suspiciousActivityDetector = {
failedAttempts: new Map(),
checkFailedLogins: (ip) => {
const attempts = this.failedAttempts.get(ip) || 0;
this.failedAttempts.set(ip, attempts + 1);
if (attempts > 5) {
// Trigger security alert
this.triggerSecurityAlert(`Multiple failed login attempts from ${ip}`);
}
},
triggerSecurityAlert: (message) => {
securityLogger.error('Security Alert', { message });
// Send notification to security team
}
};
Resposta do incidente¶
Procedimentos de Resposta:
Detecção: Equipe de segurança de alertas automatizada
Avaliação: Determine a gravidade e o âmbito do incidente
Investigação: Analise logs e determine a causa raiz
Recuperação: Restaurar operações normais
Lições aprendidas: Atualize as medidas de segurança com base nas descobertas
Teste de Segurança¶
Teste de segurança regular garante a proteção em andamento:
Teste Automatizado¶
Teste de Segurança Suite:
// __tests__/security.test.js
describe('Security Tests', () => {
it('should prevent SQL injection in API endpoints', async () => {
const maliciousInput = "'; DROP TABLE users; --";
const response = await request(app)
.get(`/api/organisms?country=${maliciousInput}`)
.expect(400);
expect(response.body.error).toContain('Invalid input');
});
it('should enforce rate limiting', async () => {
const requests = Array(1001).fill().map(() =>
request(app).get('/api/organisms')
);
const responses = await Promise.all(requests);
const rateLimited = responses.filter(r => r.status === 429);
expect(rateLimited.length).toBeGreaterThan(0);
});
});
Teste de Penetração¶
Avaliação de segurança regular:
Varredura trimestral de vulnerabilidades
Teste anual de penetração por empresas de segurança de terceiros
Monitoramento contínuo de segurança
Programa de recompensa de bugs para divulgação responsável
Checklist das Melhores Práticas¶
Checklist de Segurança de Desenvolvimento:
✅ Segurança do Ambiente - [ ] Nunca commit segredos para controle de versão - [ ] Usar gerenciamento de variáveis de ambiente seguro - [ ] Implementação de rotação secreta adequada
✅ Aplicação de Segurança - [ ] Validação de entrada e sanitização - [ ] Codificação de saída para evitar XSS - [ ] Prevenção de injeção de SQL - [ ] Autenticação e autorização
✅ Segurança de Infraestrutura - [ ] Execução de HTTPS - [ ] Implementação de cabeçalhos de segurança - [ ] Atualizações regulares de dependência - [ ] Controles de acesso da base de dados
✅ Monitoramento e resposta - [ ] Registro de eventos de segurança - [ ] Sistema de detecção de intrusão - [ ] Processos de resposta de incidente - [ ] Avaliações regulares de segurança
Informação do Contato¶
Contato do Time de Segurança:
Email: amrnetdashboard@gmail.com
Chave PG: Disponível mediante pedido
Tempo de resposta: 24 horas para confirmação inicial
Para perguntas gerais de segurança:
Discussões no GitHub: https://github.com/amrnet/amrnet/discussions
Documentação: https://amrnet.readthedocs.io