SlideShare uma empresa Scribd logo
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).

Mais conteúdo relacionado

Mais de Spark Security

Mais de Spark Security (13)

Panorama de Segurança na Internet das Coisas
Panorama de Segurança na Internet das CoisasPanorama de Segurança na Internet das Coisas
Panorama de Segurança na Internet das Coisas
 
Deep Web 101 – Vasculhando as profundezas da Internet
Deep Web 101 – Vasculhando as profundezas da InternetDeep Web 101 – Vasculhando as profundezas da Internet
Deep Web 101 – Vasculhando as profundezas da Internet
 
História, Técnica e Classificação de Algoritmos Esteganográficos
História, Técnica e Classificação de Algoritmos EsteganográficosHistória, Técnica e Classificação de Algoritmos Esteganográficos
História, Técnica e Classificação de Algoritmos Esteganográficos
 
Artigo Científico - Classificação de Técnicas Esteganográficas
Artigo Científico - Classificação de Técnicas EsteganográficasArtigo Científico - Classificação de Técnicas Esteganográficas
Artigo Científico - Classificação de Técnicas Esteganográficas
 
Classificação de Algoritmos Esteganográficos
Classificação de Algoritmos EsteganográficosClassificação de Algoritmos Esteganográficos
Classificação de Algoritmos Esteganográficos
 
Gestão de Risco e Segurança Hospitalar
Gestão de Risco e Segurança HospitalarGestão de Risco e Segurança Hospitalar
Gestão de Risco e Segurança Hospitalar
 
Resposta a Incidentes de Segurança com ferramentas SIEM
Resposta a Incidentes de Segurança com ferramentas SIEMResposta a Incidentes de Segurança com ferramentas SIEM
Resposta a Incidentes de Segurança com ferramentas SIEM
 
A3 - Análise de ameaças - Threat analysis in goal oriented security requireme...
A3 - Análise de ameaças - Threat analysis in goal oriented security requireme...A3 - Análise de ameaças - Threat analysis in goal oriented security requireme...
A3 - Análise de ameaças - Threat analysis in goal oriented security requireme...
 
A2 - Aspectos Psicológicos - The Psychology of Security
A2 - Aspectos Psicológicos - The Psychology of SecurityA2 - Aspectos Psicológicos - The Psychology of Security
A2 - Aspectos Psicológicos - The Psychology of Security
 
A1 - Cibersegurança - Raising the Bar for Cybersecurity
A1 - Cibersegurança - Raising the Bar for CybersecurityA1 - Cibersegurança - Raising the Bar for Cybersecurity
A1 - Cibersegurança - Raising the Bar for Cybersecurity
 
Estratégias para Modelagem de Ameaças
Estratégias para Modelagem de AmeaçasEstratégias para Modelagem de Ameaças
Estratégias para Modelagem de Ameaças
 
Porque a Criptografia é mais difícil do que parece?
Porque a Criptografia é mais difícil do que parece? Porque a Criptografia é mais difícil do que parece?
Porque a Criptografia é mais difícil do que parece?
 
The Psychology Behind Security - ISSA Journal Abril 2010
The Psychology Behind Security - ISSA Journal Abril 2010The Psychology Behind Security - ISSA Journal Abril 2010
The Psychology Behind Security - ISSA Journal Abril 2010
 

Computação Confiável - Lições aprendidas pela Microsoft sobre Desenvolvimento Seguro

  • 1. 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
  • 2. 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
  • 3. 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
  • 4. 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
  • 5. 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 é
  • 6. 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.
  • 7. 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).