Pular para o conteúdo principal

✍️ Boas Práticas de Escrita de Código Seguro

💡 Nota prática:
Muitas ferramentas de análise estática e linters modernos - como ESLint, Pylint, SonarQube, Checkmarx, Semgrep, entre outras - já incluem por omissão regras de segurança essenciais que cobrem várias das práticas aqui descritas.
Essas regras podem (e devem) ser customizadas, auditadas e alinhadas com o contexto técnico da organização.
A adoção destas ferramentas não dispensa a definição destas boas práticas, mas facilita significativamente a sua verificação e operacionalização.


Este documento estabelece o conjunto mínimo de boas práticas para a escrita de código seguro, que devem ser seguidas por todas as equipas de desenvolvimento e validadas durante o processo de desenvolvimento, revisão e release.

Estas práticas devem estar integradas nas guidelines técnicas da organização e nas rotinas de revisão de código.


📌 Objetivos

  • Reduzir a introdução de vulnerabilidades comuns (ex: CWE Top 25)
  • Aumentar a legibilidade, manutenibilidade e segurança do código
  • Padronizar comportamentos entre equipas
  • Integrar segurança desde o primeiro commit

👥 Quem deve aplicar

  • Desenvolvedores: durante a escrita e refatoração do código.
  • Revisores técnicos (peer reviewers, tech leads): durante a análise de PRs.
  • Equipas de segurança / AppSec: como critério de validação transversal.

⏱️ Quando aplicar

  • Sempre que se inicia ou altera código-fonte de produção.
  • Durante revisões técnicas de PRs.
  • Em auditorias internas ou revisões de segurança.
  • Durante o onboarding técnico de novos programadores.

🧱 Práticas essenciais

  1. Evitar cópia de código da internet sem validação

    • Justificar e rever trechos copiados (StackOverflow, GitHub, etc.)
    • Validar segurança e licenciamento
  2. Separar lógica de negócio da lógica de apresentação

    • Minimiza risco de injection (ex: XSS)
    • Melhora testabilidade e segurança por camada
  3. Evitar duplicação de código (DRY)

    • Aumenta rastreabilidade
    • Reduz inconsistências de segurança
  4. Evitar uso de funções perigosas ou depreciadas

    • Ex: eval, exec, system, strcpy, innerHTML sem sanitização
    • Substituir por alternativas seguras
  5. Usar nomes significativos e expressivos

    • Aumenta compreensibilidade e reduz erros lógicos
  6. Manter comentários úteis e atualizados

    • Comentários desatualizados induzem a erros críticos
  7. Eliminar código morto ou comentado antes de commits finais

    • Código obsoleto é fonte frequente de falhas de segurança

🚨 Práticas proibidas

  • Uso de secrets hardcoded (ex: tokens, passwords)
  • Inclusão de debug code ou console logging em produção
  • Acesso direto a request sem validação/sanitização
  • Query strings construídas por concatenação
  • Commit de dependências alteradas sem revisão formal

✅ Como validar

Estas práticas devem ser validadas através de:

  • Checklists de revisão de código (ver addon/08-validacoes-codigo.md)
  • Linters automáticos com regras mínimas obrigatórias (ver addon/02-linters-validacoes.md)
  • PRs com reviewers obrigatórios e anotação semântica (ver addon/09-anotacoes-evidencia.md)

🧾 Como evidenciar

A evidência da aplicação destas práticas pode ser:

  • Presença de anotação no código (@sec:checked, @sec:input-validated)
  • Validação explícita no template de PR
  • Logs de execução de linters no CI/CD
  • Inclusão no relatório de revisão técnica

🔄 Ligação a outras práticas

TemaFicheiro associado
Linters e validações automáticasaddon/02-linters-validacoes.md
Gestão de dependências segurasaddon/03-seguranca-dependencias.md
Revisões de código com checklistaddon/08-validacoes-codigo.md
Rastreabilidade no códigoaddon/09-anotacoes-evidencia.md
Justificação de exceçõesaddon/05-excecoes-e-justificacoes.md

📌 Esta prática é transversal e deve ser aplicada em todas as stacks técnicas e linguagens da organização. A sua ausência compromete a eficácia das validações automáticas e torna a base de código vulnerável a falhas triviais.