Upload
spark-security
View
178
Download
1
Embed Size (px)
Citation preview
Computação confiável
Lições aprendidas em 5 anos de criação de softwares mais seguros
Michael Howard - Microsoft
Fonte: http://msdn.microsoft.com/pt-br/magazine/cc163310.aspx - Acessado em 08 de
novembro de 2012
Conteúdo
Não se trata apenas do código
Corrija o código antigo primeiro
Descarte! Elimine! Exclua!
As ferramentas são fundamentais... a um ponto
Automatize!
Você nunca atingirá vulnerabilidades de segurança zero
A segurança é uma batalha sem fim
Não há um boletim de segurança mágico
O mantra “muitos olhos” está certo!
A atual negação de serviço é a exploração de amanhã
Considerações finais
Há cinco anos, Bill Gates enviou um memorando a todos os funcionários da Microsoft
explicando a importância de criar um software mais seguro. Desde então, muitas pessoas na
Microsoft trabalharam para aprimorar a segurança de seus produtos. Ao fazer isso,
aprendemos muito sobre quais os requisitos para a criação de um software mais seguro.
A segurança não é um campo estático – ela evolui constantemente à medida que os invasores
atacam, os defensores defendem e cada lado aprende mais sobre as técnicas do outro. A
segurança é uma corrida de armamento. Para ficar à frente e prever as manobras dos
invasores, nós, os defensores, devemos aprender com nossos erros e criar formas melhores de
impedir que os usuários sejam comprometidos.
Sendo assim, o que aprendemos nos últimos cinco anos? A maioria dessas lições é
praticamente óbvia, mas como muitas coisas aparentes, às vezes ajuda ter alguém indicando o
caminho.
Não se trata apenas do código
A indústria de software, ou mais precisamente a indústria de qualidade de software, está
concentrada em obter o código correto. Eu realmente não tenho problemas com isso, mas
muitas vulnerabilidades de segurança não estão codificando esses problemas. Muitos
problemas têm a ver com o projeto. Se você mantiver o foco somente na detecção de
problemas de segurança no código, você perderá uma classe inteira de vulnerabilidades. Esse é
um dos motivos pelos quais a Microsoft atribui a modelagem de ameaças e a análise de
superfície de ataque como parte do Processo SDL (ciclo de vida do desenvolvimento da
segurança). A modelagem de ameaças é uma técnica de análise que ajuda a identificar e
reduzir os pontos fracos do projeto em um produto. A análise da superfície de ataque se
concentra em quais partes de um produto de software estão expostas a usuários não
confiáveis, sejam locais ou remotos. Um produto com uma ampla superfície de ataque tem
mais código exposto a usuários não confiáveis do que um produto com uma pequena
superfície de ataque. (Leia mais em
msdn.microsoft.com/msdnmag/issues/04/11/AttackSurface.)
A vulnerabilidade de saturação do buffer RPC DNS documentada no Microsoft Security Bulletin
MS07-029 (consulte microsoft.com/technet/security/Bulletin/MS07-029.mspx) permite que
um invasor tenha total controle de um sistema afetado. Nesse caso, houve certamente um
problema de código. No entanto, o código estava acessível a usuários anônimos e remotos
quando deveria estar restrito aos administradores. Dessa forma, o problema foi uma
combinação de vulnerabilidade de código e projeto. Analisei essa vulnerabilidade no blog do
SDL (consulte blogs.msdn.com/sdl/archive/2007/06/28/lessons-learned-from-ms07-029-the-
dns-rpc-interface-buffer-overrun.aspx).
Lição aprendida: É fundamental criar modelos de ameaças para detectar pontos fracos em
potencial do projeto e determinar a superfície de ataque do software. Você precisa se
certificar de que todas as ameaças materiais serão atenuadas e que a superfície de ataque será
a menor possível.
Corrija o código antigo primeiro
No que diz respeito à revisão de código, gosto de classificar o código pelo potencial de
vulnerabilidade. Escrevi um artigo sobre Segurança e a privacidade da IEEE, intitulado "A
Process for Performing Security Code Reviews" (em inglês), que explica as métricas que utilizei
para priorizar a revisão de código (você pode encontrar um link para o artigo no meu blog em
blogs.msdn.com/michael_howard/archive/2006/08/01/686029.aspx).
A primeira prioridade é o código antigo, pois é muito mais provável que ele tenha mais
vulnerabilidades de segurança do que o código mais recente. As ameaças estão em constante
evolução. O código antigo – até mesmo o código criado há alguns anos – foi criado quando as
ameaças eram diferentes do que são atualmente. Além disso, as técnicas usadas para criar o
código antigo não têm as técnicas de defesa e práticas recomendadas mais recentes. Da
mesma forma, o código herdado foi criado usando bibliotecas mais antigas e menos seguras. E,
finalmente, o código anterior foi criado com menos percepção situacional, em um momento
em que os desenvolvedores tinham pouco ou nenhum conhecimento de segurança.
Meu conselho é simples: todo o código antigo deve ser revisado manualmente quanto a
vulnerabilidades de segurança. Na verdade, essa é a finalidade da fase do esforço de segurança
do SDL na Microsoft. Embora o objetivo principal do SDL seja reduzir a probabilidade de os
desenvolvedores adicionarem novas vulnerabilidades a um produto, o esforço de segurança é
desenvolvido para forçar a equipe de desenvolvimento a verificar se há problemas no código
antigo.
Nenhuma outra métrica que avaliamos foi tão importante ao priorizar a revisão de código –
não a complexidade do código, nem a contagem do número de linhas, nem a formação do
código. O indicador número um da densidade potencial de vulnerabilidade é simplesmente a
idade do código.
Lição aprendida: Identifique todos os seus arquivos de código-fonte e classifique-os por idade,
em que idade é a data de “nascimento” do código. Execute a análise estática e revise
manualmente o código, começando primeiro com o código mais antigo.
Descarte! Elimine! Exclua!
Às vezes, um recurso pode não ser seguro o suficiente no atual cenário de ameaças. O recurso
pode ter sido bom há alguns anos, mas não é seguro atualmente não devido a vulnerabilidades
de código, mas sim às alterações no atual ambiente computacional.
Um bom exemplo disso é o serviço Alerter no Windows® que deveria mostrar o status de
impressão e enviar breves mensagens que seriam exibidas como pop-up na tela do outro
usuário. Isso se tornou rapidamente um mecanismo de spam. Portanto, tomamos a difícil
decisão de desativar o serviço por padrão no Windows XP SP2 e então o removemos
totalmente do Windows Vista®.
Outro bom exemplo são os protocolos herdados IPX e SPX. (Sim, sei que o IPv4 também é
antigo e tem seus próprios problemas.) No Windows Vista, simplesmente removemos o
suporte para o Microsoft® Client for NetWare Networks, pois o código era muito antigo e não
era utilizado pela maioria dos usuários.
Com o tempo, você verá que a Microsoft remove cuidadosamente os recursos mais antigos.
Como, alguns usuários contam com determinados recursos, é importante equilibrar o risco
com a utilidade.
Lição aprendida: Identifique os recursos antigos que podem ser problemas de segurança a
longo prazo e elabore um plano para eliminar tais recursos. Talvez a primeira etapa seja
continuar lançando o curso, mas desativá-lo por padrão. Então, na próxima versão do produto,
o recurso pode ser totalmente removido, mas disponibilizado como um download da Web
para aqueles que dependem absolutamente dele. Finalmente, interrompa o suporte para o
recurso. Apenas lembre-se de manter os clientes informados.
As ferramentas são fundamentais... a um ponto
No passado, eu era extremamente crítico em relação às ferramentas. Na verdade, não das
próprias ferramentas, mas a confiança excessiva de alguns desenvolvedores em relação a essas
ferramentas. Por ferramentas, quero dizer análise estática de código, análise binária e
similares que possam ajudar a determinar vulnerabilidades de segurança. Em meus velhos
tempos, eu era de certa forma menos rígido em relação a isso.
Se você tem muito código – digamos, um milhão de linhas – torna-se muito mais difícil analisar
todo esse código manualmente. As ferramentas são práticas porque analisam rapidamente
grandes faixas de código. No entanto, elas não substituem o intelecto humano. Além disso,
muitas delas tendem a não detectar vulnerabilidades por estarem preocupadas em manter
uma taxa de falso-positivos e falso-negativos o mais baixa possível. E, para ser totalmente
honesto, muitas ferramentas de análise de segurança criam uma quantidade tão ampla de
erros e avisos que pode ser muito difícil determinar quais bugs são reais.
É claro, se você vir uma grande quantidade de problemas, isso não significa que pode
simplesmente ignorar o resultado da ferramenta! Quando realizamos uma análise da causa
dos efeitos de uma vulnerabilidade de segurança, sempre temos que nos perguntar por que o
problema não foi detectado pelas nossas ferramentas. Existem três motivos possíveis: a
ferramenta não detectou a vulnerabilidade, a ferramenta a detectou mas separou
erroneamente o problema como prioridade baixa e a ferramenta de fato detectou o problema
e o revisor humano o separou erroneamente. Essa análise nos permite ajustar as nossas
ferramentas e treinamento ao longo do tempo.
As ferramentas de análise também são muito boas para determinar o potencial de
vulnerabilidades de segurança no código. Digamos que você tenha dois produtos, cada um
com aproximadamente 100.000 linhas de código C++. Você executa suas ferramentas em cada
base de código – para esse exemplo, vamos pressupor que você usa os comutadores de
compilador /W4 e /analyze. A primeira base de código produz 121 avisos /W4 e 19 avisos
/analyze, enquanto a segunda base de código tem 235 avisos /W4 e 65 avisos /analyze. Qual
conjunto de código você acha que precisa de mais revisão?
Finalmente, as ferramentas são excelentes quando executadas em código novo ou modificado
antes da verificação, pois podem atuar como protetores do código e detectar determinadas
classes de bug no início do processo.
Lição aprendida: As ferramentas de análise podem ajudá-lo a determinar qual o cuidado
necessário ao seu código. Você também pode usar o resultado da análise para determinar o
risco geral do código. Use as ferramentas no momento da verificação para detectar os bugs
precocemente. Além disso, execute as ferramentas com freqüência, de forma que possa lidar
rapidamente com novos problemas – se executar as ferramentas somente em intervalos de
meses poderá acabar tendo que lidar com centenas de avisos de uma só vez.
Automatize!
No início de um programa de melhoria de segurança, há uma quantidade significativa de
trabalho manual – revisão manual de código, revisões manuais de projeto e assim por diante.
Para realmente elevar seu trabalho, você precisa automatizar o máximo possível do processo.
Em nossa equipe, criamos muitas ferramentas personalizadas e criamos um site interno da
Web para coletar dados de ferramentas, de forma que a equipe de segurança central pudesse
revisar o resultado das ferramentas. Quando é proposta uma melhoria do SDL, essa proposta
deve incluir uma forma de automatizar a melhoria. Os principais motivadores para a
automação são a escalabilidade e o uso constante. Se você tiver uma quantidade significativa
de código, será necessário automatizar. E, se você quiser que partes de um processo sejam
repetidas constantemente, então a automação é obviamente a solução.
Lição aprendida: Sempre que possível busque a automação. Crie ou compre ferramentas que
verifiquem o código e carreguem os resultados em um local central para análise por
especialistas de segurança.
Você nunca atingirá vulnerabilidades de segurança zero
É triste, mas é verdade, mas você nunca terá vulnerabilidades de segurança zero. Lembro
quando lancei uma das primeiras atualizações de segurança para o Windows Vista. Alguns
usuários ficaram surpresos porque pensaram que a Microsoft alegava ter resolvido o problema
de segurança com o Windows Vista. Primeiro, eu não conheço alguém que tenha feito essa
alegação e, segundo, simplesmente não é possível atingir vulnerabilidades de segurança zero.
Embora as vulnerabilidades de segurança zero sejam o ideal, é ilusório achar que é possível
atingir essa condição. O fato é que o cenário da tecnologia está sempre em fluxo, as ameaças
são um alvo em movimento e a pesquisa de segurança está em andamento. Disse
anteriormente que a segurança é uma corrida de armamento. Adicionamos defesas aos nossos
produtos e os invasores se adaptam.
O seu código pode parecer totalmente isento de vulnerabilidades hoje, mas isso pode mudar
amanhã quando um novo tipo de vulnerabilidade for detectado. Por exemplo, em 15 de
outubro de 2003, a Microsoft lançou um boletim de segurança que corrigia uma
vulnerabilidade de script em diferentes locais no Outlook® Web Access, incluído com o
Microsoft Exchange 5.5. Em 4 de março do ano seguinte, a Sanctum (adquirida pela Watchfire
e agora pela IBM) divulgou um artigo que descrevia uma nova vulnerabilidade de script em
diferentes locais denominada divisão de resposta de HTTP. Seis meses depois, a Microsoft
divulgou outra atualização de segurança para o Outlook Web Access no Microsoft Exchange
5.5 para corrigir uma vulnerabilidade de divisão de resposta de HTTP. Então, o que aconteceu?
Em síntese, no momento em que o primeiro boletim foi lançado, os problemas de divisão de
resposta não eram conhecidos, mas o cenário mudou.
Lição aprendida: Certifique-se de que as pessoas na organização saibam que a meta é reduzir
as vulnerabilidades de segurança, mas que você nunca atingirá problemas de segurança zero
enquanto houver invasores buscando novas técnicas e vulnerabilidades.
A segurança é uma batalha sem fim
Nunca haverá um momento que você dirá, “concluímos a parte de segurança; o problema
agora está resolvido”. Essa é uma extensão do ponto anterior, mas com um ângulo levemente
diferente. É extremamente importante que você mantenha um treinamento contínuo para
seus engenheiros. Caso contrário, as habilidades podem ficar desatualizadas e a urgência se
dissipar ao longo do tempo. A segurança é fundamental e proteger os seus sistemas é
imprescindível. Como dito no ponto anterior, as novas ameaças e vulnerabilidades estão
constantemente sendo detectadas. Portanto, você deve tratar sempre a segurança como uma
tarefa que nunca é concluída.
Você também deve se conscientizar de que não há mais algo de especial em relação à
segurança. A segurança é simplesmente parte da conclusão do trabalho.
Lição aprendida: Continue fornecendo treinamento contínuo aos seus engenheiros e
certifique-se de que eles sempre estejam cientes da importância de solucionar os problemas
de segurança.
Não há um boletim de segurança mágico
As pessoas me perguntam com frequência “qual é o elemento mais importante do SDL?”. A
resposta é: tudo. Se uma parte do SDL comprovar não ser útil, ela será excluída do SDL. Cada
parte do SDL leva a uma redução nas vulnerabilidades de segurança. Portanto, quando escuto
alguém dizer que tem uma tarefa única e mágica para solucionar a segurança, como executar
ferramentas de análise estática ou treinar pessoas, ele não está cobrindo todas as suas bases
de segurança. Com certeza, as ferramentas de análise estática têm seu lugar e ensinar os
usuários é fundamental, mas não por eles mesmos. A segurança deve ser completa, bem como
deve ser parte do processo.
Lição aprendida Certifique-se de que você esteja solucionando a segurança de todos os
ângulos disponíveis. Caso contrário, você precisará alterar o seu processo!
O mantra “muitos olhos” está certo!
Renomado defensor de código-fonte, Eric Raymond, disse “tendo olhos suficientes, todos os
bugs são superficiais”. Ele está certo. Mas eu considero que essa afirmação simplificada peca
em um ponto principal. Ela deveria continuar assim, “desde que os olhos sejam incentivados e
instruídos”.
Na Microsoft, podemos exigir que as pessoas adotem melhorias de processo, pois esses
requisitos fazem parte do trabalho. Esse é o incentivo. Oferecemos ensino de várias formas,
como treinamentos dinâmicos, laboratórios e treinamento online. Portanto, há bastante
material para garantir que os engenheiros estejam atualizados com o que está acontecendo no
front de segurança.
Lição aprendida: Quanto mais olhos houver no código, melhor, mas isso deve ser feito em
uma determinada estrutura. Você deve garantir que os desenvolvedores fornecendo a revisão
do código tenham um incentivo para que se preocupem em se adaptar ao seu atual processo,
bem como que estejam treinados em relação às mais recentes ameaças de segurança.
A atual negação de serviço é a exploração de amanhã
Muitos fornecedores de software, incluindo a Microsoft, aprenderam essa lição arduamente.
Os engenheiros podem analisar o problema de código e rapidamente descartá-lo por ser
“apenas um DoS”. Lembre-se de que o mundo da pesquisa em segurança está em constante
evolução e as pressuposições sobre determinadas classes de vulnerabilidade podem mudar da
noite para o dia.
Lição aprendida: Não seja rápido ao descartar um problema de negação de serviço. Com
pouco trabalho, os usuários maliciosos podem transformar vulnerabilidades de DoS em
verdadeiras vulnerabilidades de execução de código.
Considerações finais
Se há algo que aprendi nos últimos anos é que, no que diz respeito à segurança, você precisa
estar preparado para ter suas ideias e ponto de vista constantemente desafiado, além de estar
sempre atualizado sobre os problemas mais recentes. Se você seguir à risca as lições
apresentadas neste artigo, você se sairá muito bem.
Michael Howard é um dos principais gerentes de programas de segurança na Microsoft e se
concentra no aprimoramento e nas melhores práticas do processo seguro. Ele é o co-autor de
muitos livros de segurança, incluindo Writing Secure Code for Windows Vista, The Security
Development Lifecycle, Writing Secure Code e 19 Deadly Sins of Software Security (em inglês).