Weber Ress
Maio, 2008
O
desenvolvimento de software é uma arte que muitos fazem, mas poucos conseguem
atingir o nível de mestre como o de um Michelangelo ou Leonardo da Vinci. Com a
pressão corporativa por prazos curtos e entregas rápidas de código, muitas
vezes somos obrigados a esquecer a técnica e a arte e simplesmente “codificar,
codificar e codificar”, como máquinas de digitação; Agindo desta forma, os
prazos são cumpridos, nossos chefes ficam contentes e os clientes satisfeitos. Mas
será que realmente fizemos um bom trabalho? Um código seguro?
Sem repetir o
que é óbvio, a segurança é um dos itens mais importantes no desenvolvimento de
um software (o primeiro sem dúvida é a performance); mas devido à grande
pressão os desenvolvedores simplesmente ignoram ou realmente desconhecem a arte
para criar um código seguro. No decorrer da minha experiência profissional,
notei que o principal problema para os desenvolvedores criarem um código seguro
é simplesmente a falta de conhecimento de como fazer e “sentir” quais são as
ameaças. A culpa desta situação não é dos desenvolvedores e sim do processo de
formação educacional que eles são submetidos durante os cursos de graduação,
onde a Segurança simplesmente não é abordada no currículo. Sem a pretensão de
resolver os problemas educacionais e tornar os sistemas inquebráveis, o
objetivo deste artigo é fornecer dicas que todo desenvolvedor deve saber e
aplicar para que o seu código esteja mais seguro e protegido contra os ataques
e ameaças mais comuns. É um ótimo começo para que seu código esteja mais
protegido.
Não confiar na entrada de dados
Uma
das principais formas de ataque é realizado a partir das interfaces de entrada
de dados. Muitas vezes por falta de validação de dados, definição correta de tipo
de dados ou por “confiar” muito no usuário, os desenvolvedores deixam brechas
que são exploradas por atacantes. A regra é: SEMPRE validar a entrada de dados,
tanto no lado do cliente como no servidor. Em aplicações Web a validação
ocorrer no browser através de JavaScript; não há problemas em realizar este
tipo de validação no cliente, mas é importante reforçar ao desenvolvedor que o
JavaScript pode ser desabilitado facilmente pelo usuário, fazendo com que toda
a estratégia de validação de dados caia por terra, abrindo um leque de
possibilidades enorme para ataques e mau uso. Uma estratégia muito interessante
e não tão complexa de ser adotada é “mover” a validação dos dados da camada
cliente (browser) para a camada servidor (IIS), e realizar a validação dos
dados de entrada após o POST do cliente. O melhor dos mundos é ter a validação
nas 2 camadas, mas no mínimo a tenha na camada do servidor.
Não confiar na rede
Normalmente
existe uma divisão muito forte entre a área de infraestrutura e a área de
desenvolvimento, onde um não entra na área de atuação do outro e vice-versa.
Essa abordagem é um erro, pois o código desenvolvido depende inteiramente da
infraestrutura disponibilizada, e a existência da infraestrutura é justificada
pela necessidade de hospedar e processar o código; ou seja, é uma relação
simbiótica e totalmente relacionada. Muitos desenvolvedores entendem que
Segurança envolve somente a configurações de regras no firewall, atividade esta
executada pela área de infraestrutura. Mas a experiência diz que o firewall é
um dos pontos da Segurança, e não o único para garantir que o software esteja
seguro. Os desenvolvedores não devem depender inteiramente da área de
infraestrutura para garantir a segurança do software; eles devem implementar
seus controles de segurança para garantir a integridade e confidencialidade da
informação. Recursos como criptografia, certificados digitais e autenticação
integrada estão disponíveis na API e são fáceis de ser implementados após o
entendimento do seu conceito. Muitas vezes o seu sistema será executado em um
local onde você não possui o controle e por isso a segurança deve ser tratada
na fase de design do código, prevendo todas as possibilidades e assumindo como
premissas que a rede onde será estabelecida a execução é insegura. Com esta
premissa em mente, o projeto fica mais seguro.
Não colocar passwords no código
Por
motivos óbvios, NUNCA insira informações sobre autenticação (username/password)
diretamente no código. Use a DPAPI ou autenticação integrada com o Active
Directory em suas aplicações para evitar este erro primário. Se você irá se
conectar a uma base de dados, configure como provider de autenticação do banco
de dados o Active Directory.
Usar criptografia
O
desenvolvedor teve ter a consciência de proteger a confidencialidade das
informações críticas de seus sistemas. Muitas vezes a palavra criptografia é
entendida como um recurso de infraestrutura, da rede, mas na realidade ela tem
muito mais a ver com codificação. As informações críticas que serão armazenadas
devem ser criptografadas, e a escolha do algoritmo é muito importante para uma
implementação bem sucedida, tanto sobre o ponto de vista da segurança como da
engenharia de software. A System.Security.Cryptography expõe interfaces da CryptoAPI
facilitando o trabalho de implementação. Atualmente, o algoritmo de criptografia
mais utilizado é o AES, sendo padrão. Fuja de algoritmos antigos como DES e
3DES que já foram quebrados em situações de laboratório.
Mantenha as coisas simples
Normalmente
implementações complexas são mais vulneráveis do que implementações mais
simples, mas que mantenham a mesma funcionalidade. Se durante a fase de design
você notar que o projeto está ficando muito complexo, muitas classes, muitas
integrações, PARE e tente simplificar. A segurança está na simplicidade da
mesma funcionalidade, e não na complexidade.
Não reinvente a roda, use o Active Directory
Quase
que 90% dos sistemas atualmente desenvolvidos necessitam de algum tipo de
autenticação para seu acesso. Muitos desenvolvedores criaram seus próprios
mecanismos de autenticação, bases de cadastro, controle de perfis de acesso,
etc. Em uma época onde não havia de forma satisfatória um serviço de diretório
para suprir esta função, esta atitude era compreensível; mas hoje em dia, com o
Active Directory, não faz mais sentido “reinventar a roda”. As interfaces ADSI
(Active Directory Server Interface) juntamente com a System.DirectoryServices
são simples de usar e facilitam muito a vida do desenvolvedor. Faça o
outsourcing da parte de autenticação e controle de acesso do seu sistema com o
Active Directory.
Use auditoria
Cada
vez mais as empresas devem seguir diversas normas e marcos regulatórios
(Sarbanes-Oxley, por exemplo), e são auditadas sobre o nível de conformidade de
seus ativos e sistemas com estas normas. É muito importante que os sistemas
desenvolvidos estejam preparados para atender estes novos requisitos; o
principal requisito é a auditoria das operações realizadas pelo sistema, ou
seja, quem fez o que, quando e como. Muitos desenvolvedores já tem esta cultura
e criam estruturas para logs de operações, mas novamente acabam por reinventar
a roda e gastam horas preciosas de desenvolvimento em recursos que não são
focados ao negócio do sistema. A plataforma Windows possui o Event Viewer como
repositório central de logs e utilizando a System.Diagnostics, o desenvolvedor
pode facilmente implementar recursos de log e auditoria em seus sistemas e usar
o Event Viewer como repositório; observe que novamente estamos fazendo outsourcing
de uma função do sistema.
O perímetro acabou
Como
já dissemos anteriormente, os desenvolvedores estão acostumados a confiar na infraestrutura
disponibilizada para seus sistemas. Mas, as coisas mudaram, pois atualmente a
forma de acesso aos sistemas e o local onde são executados pode ser a mais
diversa possível. A época onde os servidores ficavam em DMZ isolados está
acabando, pois dentro do conceito do Software + Services, SOA e Web 2.0 mudou o
conceito da segurança. Hoje em dia os desenvolvedores devem garantir a
integridade e confidencialidade da informação de ponta a ponta, ou seja desde a
ponta de entrada e interação com o usuário até o seu armazenamento do servidor.
Diversos métodos podem ser utilizados, mas não será nada diferente de
certificados digitais e criptografia. A System.Security apresenta tudo o que é
necessário para a proteção ponta a ponta, e em conjunto com o IPSec é possível
montar uma arquitetura muito interessante.
Estude sempre
A
segurança é um dos assuntos mais mutáveis que existem; novos ataques, ameaças
surgem diariamente e novas técnicas e recursos são implementados para minimizar
o risco. O jogo de gato e rato será eterno e por isso o desenvolvedor sempre
deve manter a sua educação e atualização constante e conhecer as novas API’s
que implementam os recursos de segurança. A cada novo Service Pack, novos
recursos interessantes.
Sobre o Autor
Weber
Ress, MVP e engenheiro de software com especialização nas áreas de Segurança da
Informação e Knowledge Management. Nos primeiros anos de carreira atuou em
projetos de desenvolvimento em Exchange Server e SQL para a Microsoft .
Posteriormente, no boom da Internet, atuou em grandes Datacenters
desenvolvendo, suportando e gerenciando complexos e ambiciosos projetos de
Internet, comércio eletrônico e portais. Atualmente atua como consultor senior
de segurança na Symantec.
Com
certificações MCSE, IBM CLP, MCT, professor de pós-graduação e mestrando em
Engenharia de Software pelo IPT, ele adora conversar com clientes sobre
tecnologia e como ela pode gerar um impacto positivo e ideal para os negócios.
Apaixonado pela área de suporte técnico, e com projetos paralelos na área de
HPC - High Performance Computing, ele considera que o maior desafio de sua vida
não é a tecnologia, e sim criar e educar sua filha para o dinâmico e intenso
mundo moderno.