Este documento estabelece as diretrizes e práticas fundamentais para a codificação segura, de acordo com normas e regulamentações de segurança reconhecidas internacionalmente. A proposta é assegurar que o desenvolvimento de software no ambiente siga as melhores práticas de segurança, minimizando vulnerabilidades e atendendo aos requisitos de conformidade, especialmente com as normativas ISO/IEC (27001, 27002, 27034, entre outras), OWASP, NIST e legislações como a LGPD e o GDPR.
Objetivos do Documento
Definir práticas de codificação seguras para linguagens e frameworks homologados: Angular, Vue, Java, Node e Python.
Estabelecer diretrizes para integração das práticas de segurança durante o ciclo de vida do desenvolvimento seguro de software (SSDLC).
Fornecer orientação sobre ferramentas e frameworks para garantir a segurança de código e dados no processo de desenvolvimento.
Descrever um processo para a análise e aplicação das práticas de segurança em conformidade com a LGPD e GDPR.
Público-Alvo
Implantação do Processo de Práticas Gerais de Codificação Segura
Boas Práticas Gerais de Codificação Segura
Desenvolvedores de software e engenheiros de segurança
Arquitetos de software e segurança
Gerentes de projeto e equipes de DevOps (Infraestrutura e Operações)
Identifique requisitos de segurança e privacidade desde o início, com base nos princípios da ISO/IEC 27001, NIST e frameworks como o OWASP ASVS e a LGPD. Este levantamento deve:
Definir níveis de privilégio de usuários.
Garantir que a coleta de dados pessoais seja minimizada e os dados sensíveis sejam armazenados e tratados adequadamente.
Integre práticas de segurança desde o início do design de software, conforme orientações da ISO/IEC 27034 e do NIST Secure Software Development Framework. As diretrizes incluem:
Modelagem de ameaças (Threat Modeling) para identificar e mitigar riscos antes da implementação.
Adoção de arquiteturas seguras e segmentação de componentes críticos.
Durante o desenvolvimento, utilize padrões de codificação segura para prevenir vulnerabilidades comuns, considerando as práticas gerais de codificação segura descritas na seção 5 deste documento.
Realize testes de segurança contínuos para identificar e remediar vulnerabilidades. As práticas recomendadas incluem:
Realizar verificação automatizada de segurança de código (SAST) e análise dinâmica de segurança (DAST) com ferramentas como SonarQube, OWASP ZAP e Burp Suite.
Executar testes de invasão (pentests) regularmente, conforme práticas da ISO/IEC 29147 e 30111 para tratamento de vulnerabilidades.
¶4.1.5 Gerenciamento, Monitoramento e Proteção de Dados Pessoais
Aplique controles de monitoramento para rastrear atividades suspeitas e gerencie dados sensíveis conforme regulamentações (LGPD, GDPR). As práticas devem garantir:
Monitoramento contínuo de segurança e aplicação de correções rapidamente.
Controles rigorosos para garantir a segurança e privacidade de dados pessoais e processos de coleta, armazenamento e descarte de dados.
Abaixo estão descritas as práticas principais e como elas devem ser aplicadas:
Descrição: Empregar módulos e bibliotecas que já tenham sido amplamente testados e aprovados pela comunidade de segurança. Evite o uso de bibliotecas pouco conhecidas ou não mantidas, pois isso pode introduzir vulnerabilidades.
Exemplo: Em um projeto Node.js, ao escolher uma biblioteca de criptografia, prefira o crypto (padrão no Node.js) em vez de uma biblioteca externa desconhecida.
Ferramentas: Utilize ferramentas de verificação de dependências como npm audit (Node.js) ou pip-audit (Python) para verificar se as bibliotecas utilizadas têm vulnerabilidades conhecidas.
¶ 2. Utilizar APIs Específicas para Operações do Sistema Operacional
Descrição: Ao realizar operações de baixo nível, utilize APIs de alto nível do sistema operacional, que já vêm com verificações de segurança integradas. Evitar chamadas diretas a comandos do sistema ou execuções não seguras que possam abrir portas para ataques de injeção.
Exemplo: Em Node.js, ao precisar acessar o sistema de arquivos, utilize a biblioteca fs que oferece métodos seguros para leitura e escrita, em vez de comandos como exec para acessar o sistema diretamente.
Ferramentas: Dependendo do ambiente, utilize wrappers e módulos de sistema seguro. Em Python, subprocess permite chamadas seguras ao sistema quando bem configurado (subprocess.run com check=True para erros controlados).
¶ 3. Verificação de Integridade com Checksums ou Hashes
Descrição: A verificação de integridade garante que o conteúdo de um arquivo ou dado não foi alterado. Use algoritmos de hashing seguros (ex.: SHA-256) para verificar a integridade de arquivos críticos ou dados sensíveis, especialmente em comunicações ou atualizações.
Exemplo: Ao fazer download de uma dependência crítica, calcule e compare o hash SHA-256 do arquivo baixado com o valor de hash oficial, garantindo que não houve alterações.
Ferramentas: shasum (CLI para sistemas Unix), crypto.createHash('sha256') no Node.js, ou hashlib.sha256 em Python podem ser usados para calcular e verificar hashes.
Descrição: Ao lidar com operações concorrentes, implemente mecanismos de bloqueio para proteger contra condições de corrida e garantir que apenas um processo por vez acesse recursos compartilhados.
Ferramentas: Em Python, a biblioteca threading e, em Node.js, utilize async-mutex para gerenciamento de bloqueios assíncronos.
Proteger Variáveis e Recursos Compartilhados
Descrição: Controle o acesso a variáveis e recursos compartilhados para impedir que dados sensíveis sejam acessados ou modificados por diferentes partes do programa de maneira insegura.
Exemplo: Em aplicações Node.js, evite variáveis globais para dados sensíveis. Em Python, use armazenamento seguro para credenciais e informações confidenciais, como bibliotecas específicas para variáveis de ambiente seguras (ex.: dotenv).
Ferramentas: Em ambos ambientes, ferramentas como dotenv (Node.js e Python) protegem variáveis sensíveis, enquanto redis ou memcached podem ser usados para armazenar dados compartilhados com segurança.
Descrição: Evite variáveis não declaradas, que podem levar a comportamentos inesperados e introduzir vulnerabilidades. Sempre inicialize variáveis com um valor explícito.
Exemplo: Em JavaScript, prefira let e const para declaração de variáveis em vez de declarar sem var ou usar variáveis não inicializadas.
Ferramentas: Linters como ESLint (JavaScript) e flake8 (Python) ajudam a identificar variáveis não declaradas ou mal inicializadas.
Descrição: Adote o princípio de privilégio mínimo para limitar o acesso a dados e funções críticos. Usuários e processos devem ter apenas as permissões estritamente necessárias para suas funções.
Exemplo: Em um servidor Node.js, evite rodar a aplicação com privilégios de administrador (root). Use um usuário dedicado com permissões limitadas.
Ferramentas: Em ambientes de nuvem, o AWS IAM e o Azure Active Directory oferecem controles de privilégios. Para Linux, configure o uso de sudo com cautela.
¶ 8. Evitar Erros de Cálculo devido à Representação Interna
Descrição: Para cálculos precisos, como operações financeiras, evite erros causados pela representação interna dos números. Use bibliotecas de precisão estendida para valores decimais.
Exemplo: Em JavaScript, use a biblioteca big.js para evitar problemas de precisão com números de ponto flutuante em operações financeiras.
Ferramentas: decimal em Python e big.js em JavaScript ajudam a lidar com precisão em cálculos sensíveis.
¶ 9. Tratar Dados de Usuários antes da Execução Dinâmica
Descrição: Valide e sanitize todos os dados fornecidos pelo usuário antes de usar esses dados em operações dinâmicas (como execuções SQL ou scripts) para evitar injeções.
Exemplo: Em Node.js, use express-validator para verificar e sanitizar entradas do usuário em APIs.
Ferramentas: express-validator para Node.js, Bleach para Python, e sanitize-html para sanitar HTML no Node.js.
¶ 10. Restringir Geração e Alteração de Código por Usuários
Descrição: Evite permitir que usuários ou dados de entrada gerem ou alterem código dinamicamente. Essa prática impede ataques como injeção de código e execução remota de código.
Exemplo: Em JavaScript, evite o uso de eval() com dados de entrada do usuário, pois isso pode permitir que scripts maliciosos sejam executados.
Ferramentas: Ferramentas de linters como ESLint para JavaScript e boas práticas no Python (ast.literal_eval em vez de eval) podem auxiliar na prevenção de uso indevido de funções dinâmicas.
¶ 11. Revisar Aplicações e Bibliotecas de Terceiros
Descrição: Realize auditorias periódicas em bibliotecas de terceiros para identificar vulnerabilidades conhecidas e confirmar que estão sendo mantidas e atualizadas regularmente.
Exemplo: Em um projeto Python, verifique regularmente a segurança de pacotes com pip-audit e mantenha as dependências atualizadas.
Ferramentas: npm audit (Node.js), pip-audit (Python), e ferramentas de análise de dependências como Snyk ou Dependabot para repositórios GitHub.
¶ 12. Gerenciar e Aplicar Atualizações de Modo Seguro
Descrição: Mantenha o software, as bibliotecas e os pacotes atualizados. Aplique patches de segurança e atualizações em um ambiente controlado e seguro para evitar interrupções inesperadas.
Exemplo: Utilize uma esteira de integração contínua (CI/CD) para garantir que as atualizações sejam testadas antes da aplicação em produção.
Ferramentas: Dependabot (GitHub), Renovate para automatização de atualizações de dependências, e sistemas de CI/CD como Jenkins ou GitLab CI para integração e testes de atualizações.
Validação Estrita de Entrada
Descrição: Todos os dados de entrada, incluindo dados de usuários e dados externos, devem ser rigorosamente validados.
Exemplo: Para entradas numéricas, assegure-se de que o valor esteja dentro dos limites aceitáveis, evitando ataques de overflow ou underflow.
Ferramentas: Em JavaScript, utilize bibliotecas como validator.js para entradas específicas.
Descrição: Desative componentes, módulos ou plugins que não são utilizados para reduzir a superfície de ataque.
Exemplo: Em um ambiente de desenvolvimento web, desative a listagem de diretórios e funções de depuração em produção.
¶ 21. Proteção Contra Manipulação de Requisições (CSR e SSRF)
Descrição: Realizar verificações de origem de requisição e tokens anti-CSRF para evitar ataques de falsificação de requisição (CSRF) e ataques de Server-Side Request Forgery (SSRF).
Ferramentas: Utilizar tokens CSRF em frameworks como Django e Express para proteger endpoints contra requisições maliciosas.
Descrição: Armazene chaves de criptografia, tokens de acesso e outros segredos de forma segura, utilizando cofres de segredos como o HashiCorp Vault ou AWS Secrets Manager.
Exemplo: Nunca armazene segredos no código-fonte ou em repositórios; use variáveis de ambiente seguras e sistemas de gerenciamento de segredos.
¶ 23. Utilizar Ferramentas de Logging e Auditoria Segura
Descrição: Realize registros de eventos críticos, como falhas de autenticação e acessos não autorizados, para auxiliar na auditoria de segurança.
Ferramentas: Soluções como ELK Stack (Elastic, Logstash, Kibana) podem ser usadas para gerenciar logs de segurança e facilitar a detecção de incidentes.
¶ 24. Proteção Contra Manipulação de Requisições API (Rate Limiting e Anti-DDoS)
Descrição: Limite o número de requisições para endpoints críticos e utilize proteção contra ataques de negação de serviço distribuída (DDoS).
Ferramentas: Para Node.js, utilize express-rate-limit para limitar o número de requisições por IP.
Descrição: Isolar os microsserviços e containers com controles de segurança rígidos, restringindo permissões e monitorando os acessos.
Ferramentas: Utilizar ferramentas como Docker Bench Security e Kubernetes Pod Security Policies.
¶ 28. Práticas de Codificação Baseadas em Zero-Trust
Descrição: Utilize abordagens de segurança em que nenhum elemento é automaticamente confiável. Adote controles de autenticação, autorização e monitoramento rigorosos.
Aplicação: Valide todas as requisições, independentemente da origem ou identidade, em conformidade com os princípios de Zero-Trust.
Monitoramento de rede para descoberta de vulnerabilidades.
Monitoramento e Proteção de Dados
GitHub Dependabot
Gerenciamento automático de dependências e atualizações de segurança.
Gerenciamento e Atualizações Seguras
Sanitize-html (Node.js)
Biblioteca para sanitização de entradas de usuário.
Execução Segura
Bleach (Python)
Sanitização de entradas para proteger contra ataques de injeção.
Execução Segura
Abordagem DevSecOps no Ministério da Saúde - DATASUS
Para utilizar uma abordagem DevSecOps nas práticas de codificação segura para o Ministério da Saúde, o foco deve estar em integrar segurança em todas as fases do ciclo de desenvolvimento de software, promovendo uma cultura de segurança contínua e colaborativa. Isso envolve capacitar as equipes de desenvolvimento e operações a compartilhar a responsabilidade pela segurança, ao mesmo tempo em que atende a requisitos de conformidade específicos para proteger dados sensíveis e pessoais, especialmente em um contexto regulamentado como o da LGPD. Abaixo, descrevo como cada prática de codificação segura pode ser ampliada para adotar a abordagem DevSecOps no ambiente do Ministério da Saúde:
Utilizar Código Testado e Aprovado com Integração Contínua
Utilizar APIs Específicas para Operações do Sistema Operacional com Monitoramento
Verificação de Integridade com Checksums ou Hashes Automatizada
Mecanismos de Bloqueio e Sincronização com Revisão Automatizada
Proteger Variáveis e Recursos Compartilhados com Gestão Centralizada
Aplicação DevSecOps: Configure uma esteira de Integração Contínua/Entrega Contínua (CI/CD) para automatizar verificações de segurança no código. A cada alteração de código, ferramentas como SonarQube, Snyk e OWASP Dependency-Check podem verificar vulnerabilidades em bibliotecas e pacotes.
Exemplo Prático: Toda vez que um desenvolvedor adiciona uma biblioteca ou dependência, uma análise de segurança é realizada automaticamente na pipeline CI/CD para verificar a conformidade e segurança das novas dependências.
Aplicação DevSecOps: Adicione verificações para garantir que somente APIs autorizadas e seguras sejam utilizadas, minimizando as chamadas diretas ao sistema. Monitore a utilização das APIs através de soluções de Application Performance Monitoring (APM), como Dynatrace ou New Relic.
Exemplo Prático: Caso o sistema detecte tentativas de chamadas inseguras, um alerta pode ser enviado para a equipe de segurança para análise e correção antes que uma possível vulnerabilidade seja explorada.
Aplicação DevSecOps: Automatize a verificação de integridade de arquivos e pacotes de terceiros na pipeline CI/CD. Assegure que todo o software que é baixado ou transferido de um ambiente para outro passe por verificação de integridade.
Ferramenta: Ferramentas como Trivy e Anchore para validação de integridade e segurança de imagens de contêineres, assegurando que não haja alterações não autorizadas nos pacotes durante o processo.
Aplicação DevSecOps: Integre verificações para detectar e corrigir problemas de sincronização e condições de corrida diretamente no código, antes de subir para o ambiente de produção.
Ferramenta: Utilize CodeQL do GitHub para identificar automaticamente condições de corrida e problemas de bloqueio durante o processo de desenvolvimento.
DevSecOps Aplicação: Gerencie variáveis e recursos sensíveis usando um gerenciador de segredos integrado na pipeline DevSecOps, como HashiCorp Vault ou AWS Secrets Manager. Esses gerenciadores permitem a rotação de segredos automaticamente e protegem dados sensíveis em tempo de execução.
Exemplo Prático: Ao realizar um novo deploy, o sistema automaticamente acessa os segredos através do Vault, assegurando que informações críticas, como credenciais de banco de dados, nunca sejam expostas no código.
Instanciar Variáveis Explicitamente com Linters e Análise de Código
Gerenciar Privilégios de Maneira Segura com Controle de Acesso Centralizado
Evitar Erros de Cálculo devido à Representação Interna com Testes Automatizados
Tratar Dados de Usuários antes da Execução Dinâmica com Proteções na Pipeline
Restringir Geração e Alteração de Código por Usuários com Monitoramento Contínuo
Revisar Aplicações e Bibliotecas de Terceiros com Verificações Automatizadas
Gerenciar e Aplicar Atualizações de Modo Seguro com Automatização de Patches
Aplicação DevSecOps: Utilize linters e verificações automáticas que garantem a declaração explícita de variáveis, identificando riscos de escopo e minimizando ambiguidades no código.
Ferramentas: Linters como ESLint e Pylint podem ser configurados na pipeline para assegurar que variáveis não declaradas sejam identificadas e corrigidas durante o desenvolvimento. Ferramentas que padronizam eventos e processos nos códigos.
Aplicação DevSecOps: Integre a gestão de acessos mínimos e controle de privilégios em sistemas de CI/CD, garantindo que apenas componentes e serviços autorizados tenham permissão para acessar dados sensíveis.
Ferramenta: Ferramentas como IAM (Identity and Access Management) da AWS ou do Azure permitem criar políticas de acesso dinâmicas e de menor privilégio.
Aplicação DevSecOps: Automate testes de unidade e testes de precisão para cálculos críticos, verificando que não há perdas ou erros devido a limitações de representação de números.
Ferramenta: Jest para Node.js e pytest para Python podem ser integrados na pipeline CI/CD para garantir que cálculos estejam corretos antes de cada lançamento.
Aplicação DevSecOps: Integre ferramentas de sanitização e validação de entrada no processo DevSecOps, automatizando o escaneamento e bloqueando entradas não confiáveis antes de serem processadas no sistema.
Ferramenta: Ferramentas como express-validator e sanitize-html para Node.js podem ser integradas na pipeline CI/CD, assegurando que dados não confiáveis sejam filtrados antes de serem armazenados.
Aplicação DevSecOps: Monitore o sistema para detectar e alertar automaticamente sobre qualquer tentativa de injeção de código ou modificação não autorizada em tempo real.
Ferramentas: WAF (Web Application Firewall) como AWS WAF ou Cloudflare, que bloqueiam tentativas de injeção e execução de código malicioso no ambiente de produção.
Aplicação DevSecOps: Implemente verificações automáticas de segurança para bibliotecas de terceiros e componentes externos a cada atualização, integrando a ferramenta na pipeline de CI/CD.
Ferramentas: Ferramentas como Snyk ou Dependabot (para GitHub) que analisam a segurança das dependências de bibliotecas e alertam sobre vulnerabilidades antes da implementação.
Aplicação DevSecOps: Automatize a aplicação de patches de segurança e atualizações críticas, garantindo que a pipeline CI/CD teste e implemente as atualizações em ambientes controlados antes de disponibilizar em produção.
Ferramentas: Ansible para automatização de patches e Dependabot para monitoramento de atualizações de dependências em repositórios de código.
Implementação do DevSecOps no Ministério da Saúde
Para aplicar a abordagem DevSecOps no Ministério da Saúde, as seguintes etapas são recomendadas:
Criação de Esteiras CI/CD Seguras: Desenvolver pipelines de integração e entrega contínua que integrem automaticamente verificações de segurança e conformidade. Esse processo assegura que as práticas de segurança sejam implementadas desde a fase de desenvolvimento até o lançamento.
Capacitação das Equipes em Segurança: Treinamentos em segurança para desenvolvedores e operadores, incluindo sessões de atualização nas regulamentações de LGPD, padrões ISO, e boas práticas de segurança específicas para DevSecOps.
Automação de Detecção e Resposta a Incidentes: Configurar um sistema de monitoramento e resposta a incidentes, automatizado para detectar e reagir rapidamente a atividades suspeitas e anomalias, protegendo dados sensíveis e garantindo conformidade.
Monitoramento Contínuo e Auditoria de Conformidade: Garantir que as implementações estão em conformidade com as regulamentações e normas aplicáveis (ISO/IEC 27001, LGPD), realizando auditorias contínuas através de ferramentas integradas na esteira DevSecOps.
Uso de Ferramentas de Gestão de Vulnerabilidades: Aplicar políticas de resposta e tratamento de vulnerabilidades, conforme as diretrizes ISO/IEC 29147 e 30111, com ferramentas de gestão de vulnerabilidades integradas para facilitar o ciclo de identificação, priorização e remediação.
Considerações Finais
A utilização de práticas gerais de codificação segura visa criar um ambiente de desenvolvimento robusto, em que a segurança seja uma preocupação intrínseca ao longo de todo o ciclo de vida do software. Este guia deve ser revisado periodicamente para garantir a conformidade com as novas ameaças e as atualizações das normas e regulamentações.
Referências
ISO/IEC 27001 - SGSI - Sistema de Gestão de Segurança da Informação
ISO/IEC 27034 - Segurança em Processos de Desenvolvimento de Aplicações
NIST Secure Software Development Framework - Diretrizes de desenvolvimento seguro
OWASP ASVS - Padrões de verificação de segurança de aplicações
LGPD e GDPR - Regulamentações de proteção de dados pessoais