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:

  1. NÃO crie uma issue pública no GitHub

  2. Relatório de segurança do e-mail para: amrnetdashboard@gmail.com

  3. 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:

Suporte à Versão

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:

  1. Detecção: Equipe de segurança de alertas automatizada

  2. Avaliação: Determine a gravidade e o âmbito do incidente

  3. **Contenção **: Isolar sistemas afetados, se necessário

  4. Investigação: Analise logs e determine a causa raiz

  5. Recuperação: Restaurar operações normais

  6. 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: