Vous êtes sur la page 1sur 55

Sumário

1 Introdução.................................................................................................................................... 4
1.1 Princípios de segurança........................................................................................................... 7
1.2 Visão geral do ciclo de desenvolvimento seguro......................................................................8
1.2.1 Requisitos.............................................................................................................................. 8
1.2.2 Análise e Projeto.................................................................................................................... 9
1.2.3 Implementação...................................................................................................................... 9
1.2.4 Testes................................................................................................................................... 10
1.2.5 Implantação......................................................................................................................... 10
1.3 OWASP.................................................................................................................................. 10
2 Requisitos de Segurança de Software......................................................................................12
2.1 Engenharia de requisitos segura............................................................................................13
2.2 Categorização de segurança..................................................................................................14
2.2.1 Categorização dos tipos de informação..............................................................................15
2.2.2 Categorização do sistema...................................................................................................16
2.3 Classificação da informação...................................................................................................17
2.4 Especificação de requisitos de segurança.............................................................................18
2.5 Casos de Abuso...................................................................................................................... 19
3 Arquitetura Segura de Software.................................................................................................21
3.1 Frameworks de segurança.....................................................................................................22
3.2 Princípios de arquitetura segura.............................................................................................23
3.3 Análise da Superfície de Ataque.............................................................................................24
3.4 Modelagem de Ameaças........................................................................................................ 25
3.5 Arquitetura Segura.................................................................................................................. 27
4 Implementação segura de software...........................................................................................31
4.1 Erros comuns no desenvolvimento de software.....................................................................31
4.2 Vulnerabilidades das aplicações web.....................................................................................33
4.2.1 Injeção de código.................................................................................................................34
4.2.2 Cross site scripting............................................................................................................... 36
4.2.3 Buffer overflow..................................................................................................................... 39
4.2.4 Falha na autenticação e no gerenciamento de sessões.....................................................40
4.2.5 Referência Insegura a Objetos............................................................................................41
4.2.6 Cross site request forgery....................................................................................................42
4.2.7 Segurança configurada incorretamente...............................................................................43
4.2.8 Criptografia insegura...........................................................................................................43
4.2.9 Falha na Restrição de Acesso a URL..................................................................................44
4.2.10 Encaminhamentos e Redirecionamentos não validados...................................................44
4.2 Validação de estradas............................................................................................................. 45
5 Testes de Segurança................................................................................................................. 47
5.1 Testes de software.................................................................................................................. 47
5.2 Metologias de Teste de Segurança.........................................................................................48
5.2.1 Caixa Branca....................................................................................................................... 48
5.2.2 Caixa Preta.......................................................................................................................... 49
5.2.3 Diferenças entre caixa branca e caixa preta.......................................................................50
5.2.4 Fuzzing................................................................................................................................ 50
5.2.5 Escaneamento de vulnerabilidades e testes de Invasão.....................................................51
5.3 Testes de Segurança em software..........................................................................................51
5.3.1 Mecanismo de validação de entradas.................................................................................51
5.3.2 Teste de defesa para injeção de código..............................................................................52
5.3.3 Teste de defesa para o não repúdio....................................................................................53
5.3.4 Teste de defesa para o Spoofing.........................................................................................53
5.3.5 Teste de falha de software...................................................................................................53
5.3.6 Teste de validação do mecanismo de criptografia...............................................................53
5.3.7 Teste de defesa para Buffer Overflow.................................................................................54
5.3.8 Teste de defesa para escalonamento de privilégios...........................................................54
5.4 Documentação de vulnerabilidades e Rastreabilidade...........................................................54
1 Introdução
Com as facilidades da internet e o aumento da confiança em redes IP para comércio eletrônico e
telecomunicação, os projetistas de sistemas em software hoje devem estar atentos não somente aos usuários,
mas também aos adversários. Desde 1999, com a criação do Grupo de Resposta a Ataques (GRA) no
SERPRO, os incidentes de segurança em rede têm recebido um tratamento de acordo com referências
nacionais e internacionais (CERT.Br, CERT/Coordination Center, AusCERT). No entanto, devido à mudança na
anatomia dos ataques, agora explorando intensamente vulnerabilidades das aplicações, ações para construir
sistemas mais seguros devem estar integradas ao ciclo de desenvolvimento de software, em especial na
engenharia de requisitos, na análise e projeto, na implementação, nos testes e na implantação do sistema.
Os desafios de desenvolver software atendendo aos requisitos básicos de segurança
(confidencialidade, integridade e disponibilidade), somados aos problemas que comumente estão presentes na
produção de software de qualidade, requerem que as partes interessadas do sistema sejam treinadas e
conscientizadas de suas responsabilidades.
Diversas referências apontam que a maior parte das vulnerabilidades ocorrem na camada de
aplicação:
"75% dos novos ataques têm como foco a aplicação" - Gartner Group
"92% das vulnerabilidades estão na aplicação" - NIST

Figura 1.1
A figura 1.2 mostra o conceito de segurança em camadas. Este princípio defende a ideia de que a
segurança não é uma única solução, mas sim uma gama de controles que devem ser aplicados em várias
camadas.

Figura 1.2
A figura descreve a proteção relativa aos Sistemas Operacionais, que vão desde as permissões de
acesso aos arquivos até a instalação e execução de programas. A parte que envolve a camada de rede
(tomando como base as camadas 1 a 4 do modelo OSI) possui diversos mecanismos de proteção que
poderiam ser estudados em um curso específico de segurança em redes. Esses mecanismos vão desde ACLs
(Access Control List) até a detecção e prevenção de intrusão. Na criação de um banco de dados também
precisamos aplicar mecanismos de controle, como a configuração adequada do SGBD e controle dos
privilégios (GRANTS) de acesso. Assim como o servidor de aplicação deve ser devidamente configurado para
evitar certos tipos de ataques, como é o caso dos ataques que realizam acesso direto a recursos do servidor.

Segurança no desenvolvimento de software – COGSI 4


Por fim, a figura 1.2 nos mostra a camada de aplicação, onde são executados os softwares aplicativos
e os sistemas web. Neste curso, iremos focar no estudo das vulnerabilidades que ocorrem nos serviços web,
ou seja, as aplicações que rodam sobre o protocolo HTTP(S).
O artigo da SANS "Top Cyber Security Risks" diz que "... a quantidade de vulnerabilidades descobertas
em aplicações é muito maior do que as descobertas em sistemas operacionais". Dentre as causas para este
problema está o fato de que os sistemas não são construídos com base nas boas práticas de codificação e as
organizações não seguem um processo de desenvolvimento seguro suportado por testes que validem os
controles aplicados.
Analisando os dois aspectos ressaltados na afirmativa anterior, podemos verificar que:
i. é necessário treinar toda a equipe de um projeto de software, para que seja dada importância e
patrocínio à segurança. Este apoio deve garantir que os desenvolvedores seguirão as práticas de codificação
segura, disponíveis por meio de orientações técnicas, checklists e testes integrados de segurança. Algumas
vezes esses documentos não recebem a devida atenção pois o foco da equipe está em atender, dentro de um
prazo apertado, os requisitos funcionais do sistema.
ii. Um processo de desenvolvimento seguro de softwares deve ser criado e seguido na organização,
envolvendo todas as partes interessadas do projeto. A segurança não deve ser entendida como um
componente acoplável ao projeto, que possa ser incluído a qualquer momento, até mesmo depois de
concluído. A segurança deve ser planejada, executada e monitorada durante todo o ciclo de vida de
desenvolvimento.
Para agravar a situação, uma pesquisa realizada recentemente pelo Instituto de Engenharia de
Software (SEI) da Universidade de Carnegie Mellon afirma que a complexidade ou o conhecimento necessário
para realizar um ataque vem diminuindo ao longo do tempo enquanto que o impacto causado pelos ataques
vem crescendo.
A primeira afirmativa se justifica pelo aumento de informações disponíveis hoje na internet que
auxiliam os agentes maliciosos. Os atacantes contam com fóruns, scripts e bases de vulnerabilidades que
facilitam a realização de um ataque. Na figura 1.3 a linha descendente indica este fato.

Figura 1.3
Por outro lado, a linha azul representa a sofisticação do ataque que vem aumentando ao longo do
tempo. Quanto mais sofisticados são os ataques, maior é o impacto negativo causado nas organizações.
Portanto, esta pesquisa mostra que há alguns anos atrás um agente malicioso precisava possuir um
conhecimento muito maior para realizar ataques pouco sofisticados, ao contrário do que ocorre hoje, onde é
necessário ter muito menos conhecimento da tecnologia para realizar ataques sofisticados.
Uma falsa sensação de segurança é alimentada por afirmativas erradas (ou mitos ) relacionadas à
segurança de aplicações. As pessoas que não possuem um conhecimento técnico sobre os controles de
segurança podem se iludir e acreditar que suas aplicações estão seguras.
O primeiro mito é que colocar firewalls protegendo o servidor garantirá a segurança da aplicação.
Tipicamente o firewall atua até a camada de transporte, ou seja, é capaz de aplicar regras com base nos
protocolos desta camada e das que estão abaixo dela: MAC, ARP, RARP, IP, ICMP, IGMP, TCP, UDP e suas

Segurança no desenvolvimento de software – COGSI 5


portas. Como veremos adiante nos próximos Módulos, os ataques aos sistemas web ocorrem por meio do
protocolo HTTP, da camada de aplicação. Portanto, no seu uso mais comum, o firewall não é capaz de
identificar um ataque direcionado à camada de aplicação.
Existem firewalls que atuam como um proxy, interceptando e verificando os pacotes que passam por
ele e, portanto, capazes de interpretar a comunicação HTTP. As regras desse tipo de firewall devem ser
configuradas de acordo com cada aplicação, pois o simples uso de regras genéricas pode impedir o uso
normal de determinadas funcionalidades da aplicação, o que dificulta o uso de firewalls deste tipo. A prática de
segurança mais recomendada é a proteção em camadas, onde o código-fonte da aplicação é seguro e os
ativos de rede são implantados como outra camada de segurança.
O segundo mito é que o uso de SSL ou criptografia protege a aplicação contra os ataques . O
protocolo SSL é utilizado para criptografar a comunicação entre o cliente (browser) e o servidor. Este controle
de segurança deve ser utilizado para dificultar ataques do tipo sniffing, ou análise de tráfego na rede. Porém,
para proteger as aplicações, ele é ineficiente. O pacote malicioso (ataque) é criptografado pela camada de
criptografia provida pelo SSL e quando chegar ao servidor (ou destinatário) será decriptografado e executado
da mesma forma que um pacote sem criptografia. Este cenário caracteriza o que a bibliografia especializada
chama de "ataque seguro". A figura 1.4 ilustra os dois conceitos comentados.

Figura 1.4
Um documento elaborado pela Watsonhall1 mostra os 10 maiores mitos em relação a segurança de
páginas web. São eles:
1. Os desenvolvedores irão lidar com as questões de segurança;
2. Ninguém está interessado em atacar nosso site;
3. Estamos seguros porque utilizamos SSL;
4. Nós não usamos produtos Microsoft, por isso estamos seguros;
5. Estamos seguros porque temos um firewall;
6. Nós temos um backup, não há o que se preocupar;
7. Nossos dados estão criptografados;
8. Tudo que você precisa é de um teste de penetração anual;
9. Nossos usuários possuem desktops totalmente atualizados;
10. Temos um acordo de nível de serviço (SLA) com a nossa empresa de hospedagem.
O intuito desse treinamento é justamente mostrar que a segurança deve ser incorporada no ciclo de
desenvolvimento de software e quebrar esses mitos!

1 https://www.watsonhall.com/methodology/top10-website-security-myths.pl

Segurança no desenvolvimento de software – COGSI 6


1.1 Princípios de segurança
Os três princípios basilares da segurança da informação, formando a tríade da segurança, são: a
confidencialidade, a integridade e a disponibilidade (CID). De forma complementar, podemos citar outros
princípios, tais como: a autenticidade, a autorização e o não repúdio.

Confidencialidade
Propriedade de que a informação não será disponibilizada ou divulgada a indivíduos, entidades ou
processos não autorizados. Consiste na proteção dos dados contra divulgação não autorizada.
A confidencialidade de sistemas de informação está relacionada às áreas de propriedade intelectual,
covert channels1, análise de tráfego e criptografia.
A propriedade intelectual se refere às invenções, trabalhos literários e outros, que são protegidos por
uma lei de copyright e por patentes.
A análise de tráfego é uma quebra da confidencialidade que pode ser realizada pela análise do
volume, taxa, fonte e destino das mensagens, mesmo que estejam criptografadas. O aumento do tráfego em
uma determinada parte da rede pode indicar que um evento importante está ocorrendo.
A criptografia envolve o ciframento da mensagem para que esta não possa ser lida por uma entidade
não autorizada. O atacante pode ter o conhecimento do algoritmo, mas se não conhecer a chave,
teoricamente não conseguirá reverter a operação de criptografia. Um algoritmo de criptografia
computacionalmente seguro é aquele em que o tempo de quebra é maior que o tempo de vida útil da
informação e o custo para quebrar é maior que o valor da informação.

Integridade
Propriedade de salvaguarda da exatidão e completeza de ativos. É a garantia de que os dados
recebidos estão exatamente como foram enviados por uma entidade autorizada. Significa que não houve
modificação, inserção, exclusão nem repetição da informação, ou seja, os dados se mantêm consistentes.

Disponibilidade
Propriedade de um sistema ou de um recurso do sistema ser acessível e utilizável sob demanda por
uma entidade autorizada.

Autenticação
A garantia de que a entidade se comunicando é aquela que ela afirma ser. Essa garantia pode ser
fornecida por meio de três maneiras diferentes:
1. por aquilo que a entidade conhece: usuário/senha, por exemplo.
2. por aquilo que a entidade possui: um certificado digital, um cartão, etc.
3. por aquilo que a entidade é: envolve biometria. Por exemplo: reconhecimento facial e impressão
digital.
A autenticação de múltiplos fatores é um processo de autenticação que requer mais de um tipo de
credencial do usuário, por exemplo, combinação de uso de usuário/senha com certificado digital.

Autorização
A autorização se refere aos direitos e privilégios concedidos a um usuário ou processo. Depois que a
autenticação é realizada, a autorização é responsável por habilitar o acesso aos recursos ou ativos de
informação.

Não repúdio
Oferece proteção contra negação, por parte de uma das entidades envolvidas em uma comunicação,

1 Definição de covert channels segundo a iso/IEC 27002: são caminhos não previstos para conduzir fluxo de informações, mas que no entanto
podem existir num sistema ou rede. Por exemplo, a manipulação de bits no protocolo de pacotes de comunicação poderia ser utilizada como
um método oculto de sinalização.

Segurança no desenvolvimento de software – COGSI 7


de ter participado de toda ou parte da comunicação. Por exemplo: quem enviou uma mensagem não poderá
negar ter enviado e quem a recebeu não poderá negar ter recebido.

1.2 Visão geral do ciclo de desenvolvimento seguro


Um processo de segurança no desenvolvimento de software envolve todas as etapas do projeto, com
práticas específicas para cada uma de suas fases. Não adianta deixar para "pensar" ou se preocupar com a
segurança somente nas fases finais do desenvolvimento de uma solução. Ainda existe uma falsa ideia de que
segurança é algo que pode ser "acoplado" ou "instalado" em um sistema. Outro pensamento comum é de que
segurança é algo intrínseco ou implícito, ou seja, não precisa ser explicitado no projeto. Ambos pensamentos
estão equivocados e são a principal causa da falta de apoio e seriedade na busca pela segurança dos
sistemas.
A seguir veremos que a segurança é uma atividade que deve ser planejada, executada e monitorada
ao longo do ciclo de vida de uma aplicação. Ela deve estar presente desde o início, na definição dos
requisitos, na definição de arquitetura do projeto, até a fase de implantação. Abaixo podemos ver cada uma
das práticas específicas de segurança e em qual momento do Processo SERPRO de Desenvolvimento de
Soluções (PSDS)1 devem ser realizadas.

1.2.1 Requisitos
Na macroatividade de Requisitos, o Analista de Requisitos realiza as atividades de Definir Visão,
Analisar Sistema, Especificar Requisitos, Especificar Arquitetura, todas elas voltadas para buscar o
entendimento e a representação da solução que o Cliente deseja com o produto de software.
Quando um levantamento de requisitos é bem feito, poderá aumentar as chances do produto ser
entregue conforme as expectativas que o cliente criou sobre o sistema. Nesta etapa, é fundamental saber
quais informações serão tratadas pelo sistema, bem como fazer uma avaliação de riscos inicial com o objetivo
de verificar as necessidades de controles de segurança para o sistema.
Uma aplicação que lida com dados públicos, em que a indisponibilidade dos dados afeta poucos
usuários, com certeza necessita de menos investimentos em segurança do que uma aplicação que possui
dados críticos ao negócio, onde a indisponibilidade dos dados pode afetar negativamente diversos usuários.
Ter essa ideia no início do projeto é fundamental para se estimar o escopo, tempo e custo das atividades de
segurança. Podemos dividir esta atividade em duas etapas:

1) Estabelecer a categoria de segurança do sistema


O objetivo de categorizar a segurança do sistema é refletir o impacto potencial que uma falha de
segurança gera aos indivíduos ou à organização. Podemos pensar como uma análise de riscos, considerando
somente o impacto da falta de confidencialidade, integridade e disponibilidade do sistema. Para apoiar esta
decisão o Analista pode usar a metodologia do NIST FIPS 199 2, que será explicada no Módulo 2.
A categoria de segurança do sistema serve de base para a seleção dos controles que serão
implementados no sistema.

2) Especificar requisitos de segurança


A partir do nível de segurança do sistema, durante as especificações de requisitos, é necessário
identificar os requisitos de segurança de alto nível. Isso significa que são traçadas as linhas gerais de
segurança do sistema. Para auxiliar neste trabalho, o Analista de Requisitos pode consultar normas e políticas
internas e externas, orientações técnicas, restrições do negócio, etc. Nesta etapa, ele deve ser capaz de
identificar requisitos mínimos de segurança, como: "controle de acesso", "auditoria e registros de acesso",
"plano de contingência", "identificação e autenticação", "proteção das comunicações", "certificação e
avaliações de segurança", etc.

1 http://psds.portalcorporativo.serpro/psds/
2 http://csrc.nist.gov/publications/fips/fips199/FIPS-PUB-199-final.pdf

Segurança no desenvolvimento de software – COGSI 8


1.2.2 Análise e Projeto
Durante a macroatividade de Análise e Projeto, o Arquiteto de Software realiza as atividades de
Especificar a Arquitetura e Revisar Análise e Projeto. A especificação da arquitetura envolve a definição e
formalização da arquitetura do sistema, considerando requisitos do software, restrições de projeto, padrões
corporativos, tecnologias utilizadas e riscos envolvidos. É importante que nesta etapa atue um Arquiteto de
Segurança, um especialista que consegue, a partir dos requisitos de segurança levantados, projetar uma
solução que atenda às necessidades identificadas. Ele pode usar padrões arquiteturais para atender a um
requisito específico.
A definição da arquitetura de um software é uma atividade consolidada em praticamente todos os
ciclos de desenvolvimento de softwares. A proposta de um ciclo de desenvolvimento seguro é garantir que as
soluções arquiteturais foram escolhidas tendo em mente os controles de segurança. A atividade que cumpre
com esses objetivos é:

Realizar segurança de modelos arquiteturais


A segurança em modelos arquiteturais consiste em obter a solução mais segura para atender aos
requisitos do sistema. Estudaremos no Módulo 3 que podemos dividir em três subatividades:
(i) avaliar a superfície de ataque da aplicação: consiste em verificar a exposição do software. Quanto
maior a superfície de ataque, mais exposto a ataques o sistema vai estar.
(ii) realizar um modelagem de ameaças: consiste em fazer uma análise de riscos mais aprofundada do
sistema. Nesta etapa são consideradas as ameaças e a probabilidade de impacto.
(iii) selecionar os controles de segurança: é onde efetivamente os controles de segurança são
cuidadosamente avaliados e selecionados para compor a arquitetura da aplicação. Os padrões arquiteturais
auxiliam esta tarefa.

1.2.3 Implementação
Na macroatividade de Implementação, o Implementador executa as atividades Implementar Solução e
Integrar Unidades de Implementação. É nesta macroatividade que os requisitos do Cliente serão realmente
"transformados" em um produto, ou em uma solução funcional.

Implementar código seguro


Para orientar esta atividade, as definições das fases anteriores (especificação de requisitos de
segurança e arquitetura de segurança) devem estar disponíveis para o Implementador. É fundamental que ele
entenda todas essas especificações e saiba como implementar a solução de modo seguro, ou seja, produzindo
código sem falhas ou bugs de segurança. Os guias de codificação segura e os componentes e bibliotecas de
segurança devem ser conhecidos e utilizados pelo Implementador.
Após concluir uma unidade de implementação segura (componente do software que atende a um ou
mais requisitos funcionais e/ou não funcionais de forma segura), o Implementador é capaz de realizar a
seguinte atividade de segurança:

Revisão manual ou automática do código-fonte


Esta atividade consiste em executar uma análise no código-fonte em busca de falhas de
implementação ou vulnerabilidades na lógica do sistema. Essa busca pode ser realizada de forma manual (por
meio da revisão por pares, por exemplo) ou de forma automática (por meio de ferramentas de análise
estática). As ferramentas de análise estática podem ser executadas diretamente no Ambiente Integrado de
Desenvolvimento (IDE). Quando a equipe de desenvolvimento faz uso de um Ambiente de Integração
Contínua, os testes poderão ser realizados de forma automática toda vez que o código é submetido ao
servidor de versionamento (CVS ou SVN, por exemplo).

Segurança no desenvolvimento de software – COGSI 9


1.2.4 Testes
Na macroatividade de Testes é realizada a verificação dinâmica do comportamento de um sistema ou
componente de software, ou seja, os testes são realizados com a aplicação em execução, sem necessitar do
conhecimento da lógica interna da aplicação para realizar esses testes. Por este motivo estes testes são
chamados de testes de caixa-preta e complementam a análise de código realizada durante a implementação
da solução. Um dos tipos de testes que podemos realizar para verificar a segurança de uma aplicação em
execução é o teste de invasão.

Testes de invasão
Este tipo de teste submete ataques reais à aplicação e verifica como ela se comporta diante do uso
inesperado do sistema. O objetivo é determinar se um ataque é realmente praticável na aplicação. Pela
característica de execução destes testes, é necessário que haja um ambiente preparado e com infraestrutura
de rede isolada e devidamente configurada. É importante que o Gestor de Negócio seja o solicitante destes
testes, pois ele será capaz de identificar restrições de tempo, horário, ambiente e disponibilidade da aplicação.

1.2.5 Implantação
Na macroatividade de Implantação do sistema, o Gestor de Negócio, Cliente, Desenvolvedor, Gestor
de Infraestrutura, Líder de Projeto e Suporte Operacional são responsáveis por Planejar a Implantação.
Planejar a implantação do produto de software consiste em elaborar o Plano de Implantação que será a base
para a preparação do ambiente e a entrega e/ou disponibilização do produto ao Cliente.
Na implantação da solução, devemos nos preocupar com a configuração segura do servidor. Este
assunto envolve o gerenciamento de patches, hardening do servidor e o gerenciamento de configuração. No
que se refere ao servidor de aplicação, as atividades de segurança incluem o uso de um firewall de aplicações
web (Web Application Firewall ou WAF) e filtros HTTP(S), tais como ModSecurity (para o Apache) e URL Scan
(para o IIS).

1.3 OWASP
Neste curso iremos trabalhar com diversos documentos, conceitos e ferramentas que estão
disponíveis em uma iniciativa aberta para tratar aspectos de segurança de aplicações web, chamada Open
Web Application Security Project (OWASP). Esta associação congrega especialistas de empresas privadas,
órgãos governamentais, instituições acadêmicas e voluntários de todo o mundo. Esta comunidade trabalha na
criação de artigos, metodologias, documentação, ferramentas e tecnologias para aprimorar a segurança das
aplicações web.
Apesar de grandes empresas apoiarem a OWASP, ela não é afiliada a nenhuma delas e é uma
organização independente que se mantém através de eventos, doações e venda de materiais. Este aspecto é
importante, pois afasta as influências e pressões organizacionais e garante que as informações sobre a
segurança de aplicações sejam imparciais, sem preferências por determinado produto ou tecnologia
proprietária. A OWASP pode ser acessada no endereço www.owasp.org .
Existem muitos projetos em andamento na comunidade e qualquer interessado pode contribuir com
eles. Neste curso iremos estudar alguns dos principais projetos da OWASP. Para termos uma visão geral,
abaixo segue uma lista de projetos da OWASP que serão abordados durante o curso:

TOP 10: este documento teve sua primeira versão lançada em 2004 e é atualizado periodicamente a cada 3
anos, sendo a ultima versão a de 2010. O documento faz um levantamento das 10 vulnerabilidades que mais
ocorrem em aplicações web. Para cada uma delas é mostrado como ocorrem e como evitá-las.

WebGoat: é uma aplicação intencionalmente vulnerável que pode ser instalada em uma máquina local para
estudar ou ensinar como os ataques ocorrem em um aplicação real.

Segurança no desenvolvimento de software – COGSI 10


Application Verification Security Standard (ASVS): este documento descreve 4 níveis de segurança que
podem ser atribuídos a uma aplicação web e, para cada um dos níveis, os requisitos arquiteturais que devem
ser atendidos.

Quick Reference, ou Guia de referência rápida: este documento consiste em uma lista de verificação de
controles de segurança, independentes de linguagem de programação. Cada item está relacionado a uma
categoria específica, por exemplo: controle de sessões, autenticação, validação de dados de entrada/saída,
gerenciamento de configuração, etc.

Development Guide, ou Guia de desenvolvimento: este documento fornece orientações para


implementação dos controles de segurança descritos no ASVS, que estão divididas em 14 categorias, dentre
elas: controle de acesso, validação de entrada/saída de dados, tratamento de erros, etc.

Enterprise Security Application Programming Interface (ESAPI): consiste em uma API que fornece a
especificação das principais funções de segurança que devem ser utilizadas pelo desenvolvedor. Ela possui
versão implementada para as tecnologias JAVA, .NET, PHP, ASP clássico, ColdFusion, Python, Objective C e
Ruby.

Testing Guide, ou Guia de testes: este documento descreve como realizar cada tipo específico de teste para
verificar se os controles de segurança foram implementados na aplicação, bem como a eficácia desses
controles.

Comprehensive, Lightweight Application Security Process (CLASP): descreve um processo ágil de


desenvolvimento de software que leva em consideração a segurança durante todo o ciclo de vida da
aplicação.

Software Assurance Maturity Model (SAMM): este documento pode ser utilizado para avaliar uma
organização quanto à maturidade de seus processos de segurança no desenvolvimento ou para contribuir na
implementação das atividades.

Segurança no desenvolvimento de software – COGSI 11


2 Requisitos de Segurança de Software
Para garantir o desenvolvimento de software seguro é necessário entender as necessidades de
segurança do cliente e realizar uma avaliação das ameaças, dos pontos críticos, das informações importantes,
das políticas e dos controles já existentes no ambiente. Toda análise deve ser realizada logo no início do
projeto de desenvolvimento, mais especificamente na fase de Requisitos . É nesta fase que podemos obter do
cliente suas necessidades em relação à segurança das informações que são manipuladas pelo sistema.
Segundo a norma ISO/IEC 15.4081, que define uma metodologia para avaliação da segurança de TI,
essas informações podem ser obtidas por meio de três fontes:
1. Política de segurança: diretrizes, normas e legislação pertinente.
2. Objetivos de segurança: necessidades do usuário.
3. Ameaças: formas de ataque, compostas por um agente, um mecanismo e um ativo.
A primeira fonte, a Política de segurança, envolve as normas, legislações ou qualquer documento que
imponha ao sistema determinadas características de segurança. Elas são expressas por meio de diretrizes que
definem as características gerais de segurança de um sistema. Um exemplo de diretriz de segurança é: "Todo
sistema deve garantir que os usuários sejam responsabilizados por suas ações."
Estas definições se encontram em um nível mais alto, com poucos detalhes técnicos e sem especificar
como atingir os objetivos por ela definidos. Mesmo assim, podemos inferir itens que precisarão constar na
especificação de segurança da aplicação. Por exemplo, fica claro que será necessária a autenticação dos
usuários nas aplicações e o armazenamento das ações, preservando as trilhas de auditoria.
Os objetivos de segurança expressam as escolhas do cliente e consistem na especificação dos
Requisitos Funcionais de Segurança (RFS) e dos Requisitos Não Funcionais de Segurança (RNFS). Os
requisitos funcionais de segurança estão relacionados com as funcionalidades de segurança que o sistema
deve atender. Exemplo de RFS expressos pelo cliente são: "Todos os usuários devem ser autenticados para
uso do sistema."; "Somente os gerentes podem visualizar o módulo de relatórios."
Os requisitos não funcionais de segurança declaram restrições ou atributos que expressam como o
software deve ser feito. Exemplo de RNFS são: "O software deve validar todas as entradas de dados."; "Em
caso de erro, o sistema deve se manter em um estado seguro".
A diferença entre RFS e RNFS está na forma como são obtidos. Os RFS serão identificados e
solicitados pelo próprio cliente. Muitas vezes o cliente nem percebe que se trata de um requisito de segurança.
Geralmente envolve assuntos relacionados à autenticação dos usuários (uso de certificados digitais, políticas
de senhas, bloqueio de contas, uso de antirrobôs, etc.) e à autorização (permissões de acesso). Os RNFS
serão propostos pelo Analista de Requisitos, com base no conhecimento dos padrões adotados na organização
e o que é exposto nas boas práticas.
Devido ao fato de estarem em constante evolução, é praticamente impossível identificar todas as
ameaças a que um sistema está exposto. Portanto, devemos considerar um grupo geral e bem definido de
ameaças que possuem maior probabilidade de ocorrência ou maior impacto sobre o negócio.
Um exemplo de ameaça bem definida é: "usuário sem privilégios administrativos consegue acessar a
console de gerenciamento". Uma ameaça muito genérica e maldefinida seria: "hacker invade o sistema".
Falta no segundo exemplo um definição mais clara e objetiva da ameaça para que possamos derivar
em controles de segurança. Por outro lado, no exemplo de ameaça bem definida podemos com certa
facilidade especificar alguns controles de segurança que garantem a proteção contra esta ameaça.
Uma técnica que ajuda no levantamento das ameaças do sistema é o DIAGRAMA DE CASOS DE
ABUSO semelhante ao DIAGRAMA DE CASOS DE USO, mas descrito na perspectiva de um ator malicioso,
que tentará todas as possibilidades de uso do sistema de forma subversiva. O importante nesta etapa é que o
Analista de Requisitos desenvolva uma mentalidade de segurança, ou seja, que ele comece a imaginar
situações de mal uso (intencional ou não) do sistema.

1 Norma disponível em: http://www.commoncriteriaportal.org/cc/

Segurança no desenvolvimento de software – COGSI 12


2.1 Engenharia de requisitos segura
A engenharia de requisitos de um sistema demanda uma intensa interação com o cliente. Segundo
Roger Pressman, a engenharia de requisitos envolve as atividades de concepção, levantamento, elaboração,
negociação, especificação, validação e gestão de requisitos.
A literatura se preocupa com o entendimento dos requisitos, a modelagem de análise, resolução de
requisitos conflitantes, rastreabilidade dos requisitos, etc.

Figura 2.1

Todas essas atividades são essenciais para um ciclo de desenvolvimento. Porém, para garantir que o
sistema a ser construído tenha os controles de segurança necessários à proteção de suas informações,
devemos acrescentar algumas atividades na engenharia de requisitos:
1- categorização de segurança do sistema
2- especificação de requisitos de segurança
3- descrição dos casos de abuso

Figura 2.2
A figura 2.2 inclui mais 3 atividades de segurança para formar a chamada engenharia de requisitos
segura. O grande benefício dessas atividades é antecipar a preocupação com a segurança do sistema.
 primeiramente com o entendimento da necessidade de segurança do sistema por meio da
categorização de segurança;
 em seguida com a especificação dos requisitos de segurança que deverão ser implementados; e

Segurança no desenvolvimento de software – COGSI 13


 por fim, a descrição dos casos de abuso para deixar claro os cenários indesejados de uso do sistema.
Essas atividades serão explicadas a seguir.

2.2 Categorização de segurança


O National Institute of Standards and Technology (NIST)1 é o órgão nacional do governo Americano
responsável por definir padrões e tecnologias a serem utilizadas pelas agências dos Estados Unidos. Em sua
publicação FIPS (Federal Information Processing Standard) 199 2, o NIST define um padrão para categorização
de segurança de sistemas de informação.
O propósito da categorização dos sistemas de informação é identificar o nível apropriado de
segurança de acordo com os riscos identificados.
Podemos entender esta categorização de segurança como uma avaliação preliminar de riscos, feita
em conjunto com o cliente. Ela irá servir como base para a definição dos requisitos de segurança do sistema e
irá nortear todas as outras atividades de segurança durante o ciclo de desenvolvimento seguro.
Neste curso aprenderemos como aplicar a metodologia descrita no FIPS 199 para identificar a
categoria de segurança de um sistema. O momento mais adequado para realizar esta atividade é durante a
descrição dos casos de uso do sistema. Será muito mais fácil nesta etapa analisar quais dados são tratados
pelo sistema.
Abaixo mostramos o caso de uso "Realizar inscrição" de um sistema escolar que servirá de exemplo
para a aplicação da metodologia FIPS 199.

SISTEMA ESCOLA
Caso de Uso 01: Realizar Inscrição
Sumário: Aluno usa o sistema para realizar inscrição em disciplinas.
Ator Primário: Aluno
Atores Secundários: Sistema de Faturamento
Pré-condições: O Aluno está identificado pelo sistema.

Fluxo Principal
1. O Aluno solicita a realização de inscrição.
2. O sistema apresenta as disciplinas disponíveis para o semestre corrente e que o aluno atende aos pré-
requisitos.
3. O Aluno seleciona as disciplinas desejadas e as submete para inscrição.
4. Para cada disciplina selecionada, o sistema aloca o aluno em uma turma que apresente uma oferta para tal
disciplina.
5. O sistema informa as turmas nas quais o Aluno foi alocado. Para cada alocação, o sistema informa o
professor, os horários e os respectivos locais das aulas de cada disciplina.
6. O Aluno confere as informações fornecidas.
7. O sistema envia os dados sobre a inscrição do aluno para o Módulo de Faturamento e o caso de uso
termina.

Fluxo Alternativo (4): inclusão em lista de espera


a. Se não há oferta disponível para alguma disciplina selecionada pelo aluno, o sistema reporta o fato e
fornece a possibilidade de inserir o Aluno em uma lista de espera.

1 http://www.nist.gov/
2 http://csrc.nist.gov/publications/fips/fips199/FIPS-PUB-199-final.pdf

Segurança no desenvolvimento de software – COGSI 14


b. Se o Aluno aceitar, o sistema o insere na lista de espera e apresenta a posição na qual o aluno foi inserido
na lista. O caso de uso retorna ao passo 4.
c. Se o Aluno não aceitar, o caso de uso prossegue a partir do passo 4.

Fluxo Alternativo (6): desistência de disciplina


a. Se o Aluno quiser desistir de uma disciplina ou sair da lista de espera, ele submete ao sistema o pedido de
desistência. O caso de uso prossegue a partir do passo 6.

Pós-condição: O aluno foi inscrito em uma das turmas de cada uma das disciplinas desejadas, ou foi
adicionado a uma ou mais listas de espera.

2.2.1 Categorização dos tipos de informação


O primeiro passo definido no FIPS 199 é aplicar a categorização dos tipos de informação, que
representam uma categoria específica de informações definidas pela organização ou, em outras instâncias,
por leis, políticas, regulamentações, etc. Exemplos de tipos de informação comuns incluem: informações
médicas, proprietárias, financeiras, investigativas, contratuais, gerenciais, cadastrais, etc.
Neste primeiro passo devemos identificar cada tipo de informação que o sistema irá tratar.Um sistema
tipicamente trabalha com vários tipos de informação. Podemos identificar os tipos que estão destacadas no
Caso de Uso 01:

1) Aluno
A pré-condição do caso de uso indica que o sistema realiza a autenticação dos alunos para que eles
possam solicitar a matrícula. Os dados que são armazenados de cada aluno não estão detalhados, mas com
certeza o sistema possui um registro de todos os alunos. Portanto, o primeiro tipo de informação descrito no
caso de uso são as informações sobre os Alunos.
A confidencialidade dessa informação cresce a medida em que os dados pessoais importantes do
aluno são requeridos pelo sistema. Um sistema que guarda a matrícula do aluno mais o seu nome terá
diferente impacto na confidencialidade do que um sistema que necessita do CPF, número de identidade, título
de eleitor, endereço, telefones e, em alguns casos, a conta bancária. Para dar continuidade ao nosso exemplo,
iremos supor que os dados dos alunos são: matrícula, nome e data de nascimento.

2) Inscrição
A segunda informação tratada pelo sistema é a Inscrição. Esta informação consiste no relacionamento
entre o aluno e as disciplinas que irá cursar no semestre. Podemos notar que o atributo de segurança mais
relevante desta informação é a integridade, pois uma alteração indevida nas inscrições tem um impacto
relevante ao sistema. Devemos garantir que a inscrição do aluno se mantenha consistente, íntegra, para que
no primeiro dia de aula todos consigam se deslocar às salas das disciplinas que se matricularam. Ao passo
que a confidencialidade dessa informação é pouco relevante para o sistema e poderia até mesmo ser
considerada pública.

3) Disciplina
As informações que são apresentadas pelo sistema aos seus usuários também devem ser
classificadas. Percebam que as informações referentes às disciplinas somente são consultadas neste caso de
uso. O cadastramento, alteração e exclusão provavelmente são tratados em outro caso de uso responsável
por manter as informações sobre disciplinas.
No nosso exemplo, iremos considerar que essa informação é pública e que a perda de integridade
possui um impacto alto (com o raciocínio semelhante aos das informações sobre inscrição).

4) Turma
O caso de uso especifica que os alunos serão alocado nas turmas. Haverá um relacionamento entre o
aluno e a turma. A integridade dessa informação é importante para a segurança do sistema. Iremos englobar

Segurança no desenvolvimento de software – COGSI 15


aqui as informações dessa associação descritas no passo 5 do caso de uso: professor, horários e local de aula.

5) Lista de espera
O fluxo alternativo (4) descreve a possibilidade de um aluno entrar em uma fila de espera. A quebra de
confidencialidade dessa fila causa menos impacto que a de integridade. O objetivo é impedir que um aluno
espertinho "fure a fila" de espera.

Depois de identificarmos todos os tipos de informação tratados pelo caso de uso devemos aplicar a
metodologia à cada um dos tipos de informação. Esta metodologia consiste em avaliar o impacto da perda de
confidencialidade, integridade e disponibilidade das informações e atribuir os níveis ALTO, MÉDIO, BAIXO e
NÃO SE APLICA1.
Impacto
Confidencialidade Integridade Disponibilidade
Tipos de informação

Alunos BAIXA MÉDIA BAIXA

Inscrição MÉDIA ALTA BAIXA

Disciplina NÃO SE APLICA ALTA BAIXA

Turma NÃO SE APLICA ALTA MÉDIA

Lista de espera BAIXA ALTA MÉDIA

Tabela 2.1
Esta tabela representa a categorização de segurança dos tipos de informação do Caso de Uso 01.
Essa metodologia deve ser repetida para todos os casos de uso do sistema, até termos todas as informações
do sistema avaliadas. Porém, passaremos para o passo seguinte da metodologia considerando apenas as
informações descritas no Caso de Uso 01.

2.2.2 Categorização do sistema


O passo seguinte da metodologia consiste em atribuir a categorização de segurança ao sistema de
informação. Este valor é obtido a partir dos impactos atribuídos aos tipos de informação que o sistema irá
tratar. A regra é que o sistema deve ser categorizado pelo nível mais alto definido em cada atributo de
segurança (confidencialidade, integridade e disponibilidade). O sistema escolar dado como exemplo receberia
a categorização MÉDIA para confidencialidade, ALTA para integridade e MÉDIA para disponibilidade. Esta
categorização pode ser representada como na tabela 2.2 ou em formato textual.

1 De acordo com o FIPS 199, a confidencialidade é o único atributo de segurança na qual se pode atribuir o
impacto “não se aplica”, usado nos casos em que as informações são públicas.

Segurança no desenvolvimento de software – COGSI 16


Impacto
Confidencialidade Integridade Disponibilidade

Alunos BAIXA MÉDIA BAIXA


Tipos de informação

Inscrição MÉDIA ALTA BAIXA

Disciplina NÃO SE APLICA ALTA BAIXA

Turma NÃO SE APLICA ALTA MÉDIA

Lista de espera BAIXA ALTA MÉDIA

SISTEMA ESCOLAR MÉDIA ALTA MÉDIA


Tabela 2.2
Categoria de segurança sistema_escolar = {(confidencialidade, média) , (integridade, alta) ,
(disponibilidade, média)};

Esta categorização do sistema servirá de base para a seleção dos requisitos de segurança do sistema,
para a aceitação/avaliação de riscos e seleção dos controles. A dificuldade desta tarefa está na avaliação de
impacto de cada atributo. É de se esperar que o Analista de Requisitos pergunte: "Mas o que significa um
impacto ALTO, MÉDIO ou BAIXO?". Esta resposta deverá ser obtida com o próprio cliente e exige a definição
desses critérios pelas partes interessadas.
Uma outra forma de obter a categorização do sistema é por meio de uma metodologia de Análise do
Impacto no Negócio (BIA - Business Impact Analysis).

2.3 Classificação da informação


Para exemplificar os conceitos até aqui apresentados, iremos estudar o Decreto 4.553 de 27 de
dezembro de 20021, que dispõe sobre a salvaguarda de dados, informações, documentos e materiais sigilosos
de interesse da segurança da sociedade e do Estado, no âmbito da Administração Pública Federal. Apesar do
Decreto ser geral, não específico para softwares, é um exemplo de política que direciona controles de
segurança a serem atendidos para a salvaguarda de documentos. Neste ato normativo podemos, inclusive,
observar os tipos de informação bem definidos para cada grau de sigilo.
Com isto em mente, é altamente viável a elaboração de uma política de segurança para os sistemas
de informação que contemple os tipos de informação mais comuns na empresa, a definição dos níveis de
riscos e os requisitos de alto nível de segurança. Esta ideia foi apresentada no início deste módulo quando
falamos da norma ISO 15.408, que mostra como primeira fonte de requisitos a Política de segurança.
O Decreto 4.553 define, no seu artigo 5º, quatro classificações de informações sigilosas, conforme
podemos ver a seguir:
Art. 5º Os dados ou informações sigilosos serão classificados em ultra-secretos, secretos, confidenciais e
reservados, em razão do seu teor ou dos seus elementos intrínsecos.
A tabela 2.3 resume o art. 5º do Decreto 4.553 mostrando as classificações e os tipos de informação
de cada uma.

1 http://www.planalto.gov.br/ccivil_03/decreto/2002/D4553.htm

Segurança no desenvolvimento de software – COGSI 17


Classificação Tipo de informação
Soberania e à integridade territorial nacionais
Planos e operações militares
Relações internacionais do País
Projetos de pesquisa e desenvolvimento científico e
Ultra-secretos
tecnológico de interesse da defesa nacional
Programas econômicos, cujo conhecimento não-
autorizado possa acarretar dano excepcionalmente grave
à segurança da sociedade e do Estado
Dentre outros
Dados ou informações referentes a sistemas,
instalações, programas, projetos, planos ou operações de
interesse da defesa nacional
Assuntos diplomáticos e de inteligência
Secretos estratégicos, cujo conhecimento não-autorizado possa
acarretar dano grave à segurança da sociedade e do
Estado
Dentre outros
Assuntos que devam ser de conhecimento restrito, no
interesse do Poder Executivo e das partes
Confidenciais Assuntos cuja revelação não-autorizada possa frustrar
seus objetivos ou acarretar dano à segurança da
sociedade e do Estado
Assuntos cuja revelação não-autorizada possa
Reservados comprometer planos, operações ou objetivos neles
previstos ou referidos

Tabela 2.3
O Decreto 4.553 define alguns requisitos de segurança que devem ser atendidos pelos sistemas que
produzem, manuseiam, transmitem, mantêm e guardam informações sigilosas. Vejamos esses requisitos em
seus artigos 45 a 48.
Art. 45. Os equipamentos e sistemas utilizados para a produção de documentos com grau de sigilo ultra-
secreto só poderão estar ligados a redes de computadores seguras, e que sejam física e logicamente isoladas
de qualquer outra.
Art. 46. A destruição de dados sigilosos deve ser feita por método que sobrescreva as informações
armazenadas. Se não estiver ao alcance do órgão a destruição lógica, deverá ser providenciada a destruição
física por incineração dos dispositivos de armazenamento.
Art. 47. Os equipamentos e sistemas utilizados para a produção de documentos com grau de sigilo secreto,
confidencial e reservado só poderão integrar redes de computadores que possuam sistemas de criptografia e
segurança adequados a proteção dos documentos.
Art. 48. O armazenamento de documentos sigilosos, sempre que possível, deve ser feito em mídias removíveis
que podem ser guardadas com maior facilidade.
Podemos observar que, como foi dito antes, o Decreto 4.553 é bem geral e inclui requisitos voltados
para a área de segurança de redes e segurança física. Esses requisitos especificam as diretrizes gerais dos
controles de segurança que devem ser aplicados. Esta é a característica que deve ser seguida por uma
Política de Segurança de um sistema de informação.

2.4 Especificação de requisitos de segurança


Na próxima atividade de segurança da fase de Requisitos, iremos especificar os requisitos de
segurança do sistema. Continuando com o exemplo do sistema escolar, o primeiro passo é analisar se há
algum requisito funcional de segurança. O caso de uso "Realizar inscrição" define somente um Requisito
Funcional. Esta funcionalidade não agrega segurança ao sistema. Por conta disso, podemos ver que não se
trata de um requisito funcional de segurança.
Extrapolando o caso de uso "Realizar inscrição", podemos visualizar sua pré-condição que o aluno já

Segurança no desenvolvimento de software – COGSI 18


foi autenticado pelo sistema. Isto pressupõe que há um caso de uso "Autenticar aluno no sistema escolar".
Este sim, seria um Requisito Funcional de Segurança, pois se trata de uma funcionalidade voltada para a
segurança do sistema.
Porém, iremos manter o foco no caso de uso "Realizar inscrição" e derivar os requisitos não funcionais
de segurança a partir da categorização feita anteriormente. Os requisitos estão relacionados à forma como a
funcionalidade é implementada, com as restrições e propriedades de segurança do caso de uso. A
categorização de segurança nos indica que devemos selecionar principalmente os requisitos que tratam da
integridade das informações (a confidencialidade e disponibilidade foram definidas como de impacto médio).
Primeiro, vamos conhecer uma lista de requisitos não funcionais para cada atributo de segurança.
Confidencialidade: em linhas gerais, são requisitos que lidam com a proteção das informações para dificultar
o acesso não autorizado. Por exemplo:
 prevenir a divulgação não autorizada da informação;
 garantir autorização para acesso aos recursos;
 aplicar criptografia nos dados armazenados no sistema.
Integridade: geralmente com o objetivo de assegurar a integridade dos dados em trânsito e armazenados pelo
sistema. Podem especificar meios de detectar e recuperar erros, tais como exclusões, inclusões e
modificações. Por exemplo:
 fazer validação dos dados de origem;
 detectar alterações dos dados;
 assinar digitalmente os documentos.
Disponibilidade: estão preocupados com a negação de acessos ilegítimos aos recursos computacionais e
prevenir ataques de negação de serviço. Além disso, requisitos para tratar as tentativas de destruição ou dano
aos dados e negação de acesso legítimo ao sistema. Por exemplo:
 restringir acesso aos recursos;
 bloquear acessos simultâneos;
 limitar o número de conexões.

2.5 Casos de Abuso


Após obter a categorização do sistema e a especificação dos requisitos de segurança, a próxima
atividade do ciclo de desenvolvimento seguro é a descrição dos Casos de Abuso do sistema. Esta atividade
pode ser vista como uma extensão à elaboração do Diagrama de Caso de Uso.
O Diagrama de Caso de Uso é um diagrama UML que descreve a funcionalidade proposta para um
novo sistema, que será projetado. Segundo Ivar Jacobson, podemos dizer que um Caso de Uso é: "um
documento narrativo que descreve a sequência de eventos de um ator que usa um sistema para completar um
processo".
A figura 2.3 ilustra o Diagrama de Caso de Uso do sistema Escolar descrito no item 2.

Figura 2.3
A partir deste Diagrama, que descreve as ações normais entre os autores e o sistema, podemos
construir o Diagrama de Caso de Abuso. Para isso, devemos agora imaginar as situações de abuso do
sistema, ou seja, vestir a camisa de um usuário malicioso que tentará, de várias formas, usar a aplicação de
uma maneira diferente da qual foi projetada. Isto retoma a ideia das Ameaças que estudamos no início deste
Módulo.

Segurança no desenvolvimento de software – COGSI 19


Figura 2.4
Pela figura 2.4 podemos visualizar três situações indesejáveis que poderiam ser feitas por um aluno
mal-intencionado. Este aluno pode tentar fraudar uma inscrição, seja criando uma inscrição fraudulenta com
as credenciais de outro aluno, seja alterando uma inscrição previamente realizada por alguém. Outra situação
imaginada é a de burlar a lista de espera, representada no fluxo alternativo (4) da descrição do caso de uso. A
ultima situação descrita no Caso de Abuso é burlar o pré-requisito de uma matéria, possibilitando um aluno se
inscrever em uma matéria sem ter os pré-requisitos.
A lista de mal uso do sistema prossegue e é papel do Analista de Requisitos, com o apoio de uma
equipe de segurança, identificar os casos de abuso mais relevantes para o sistema. Esta identificação deve
estar em conformidade com a categorização de segurança. Vamos lembrar a classificação do sistema escolar:
{(confidencialidade, média) , (integridade, alta) , (disponibilidade, média)};
Os casos de abuso identificados afetam diretamente a integridade da inscrição: fraudar a inscrição,
burlar lista de espera ou pré-requisitos. Faz sentido termos levantado justamente esses casos de abuso do
sistema, pois na categorização do sistema a integridade é o ponto mais relevante. E por isso deixamos outros
casos de abuso de lado. Poderíamos ter identificado, por exemplo, um caso de abuso que ataca a
confidencialidade (Visualizar inscrição de outros alunos) ou até mesmo a disponibilidade (Inundar o sistema
com inscrições).
Agora a associação dos requisitos de segurança de integridade com os casos de abuso, na figura 2.5.

Figura 2.5
Por meio desta técnica, juntamos os requisitos de segurança não funcionais levantados para o sistema
escolar com os casos de abuso identificados. O sistema deve ter certeza de que os dados a ele enviados
foram submetidos pelo aluno previamente identificado. Isto consiste na validação dos dados de origem e
dificulta que um aluno mal intencionado consiga fraudar uma inscrição ou burlar os pré-requisitos da disciplina.
No caso da lista de espera, podemos definir que o sistema será capaz de inserir alunos na lista mas
nunca excluí-los. Portanto, o requisito não funcional de segurança "detectar alterações nos dados" irá dificultar
a ameaça de burlar lista de espera.

Segurança no desenvolvimento de software – COGSI 20


3 Arquitetura Segura de Software
Quando tentamos solucionar um problema, é possível identificar diversas soluções que poderiam ser
utilizadas visando resolvê-lo. Contudo, outros fatores como custo e eficiência influenciam na escolha da
solução a ser adotada. No contexto do desenvolvimento de software, o mesmo pode ser observado ao se
analisar os requisitos visando à construção de um software: várias soluções computacionais podem ser
definidas para atender a esses requisitos, mas uma análise deve ser feita para definir a mais adequada ao
contexto de desenvolvimento da aplicação.
Para se representar essas soluções, a arquitetura de software é uma das abordagens que podem ser
usadas. Com isso, para se obter a arquitetura (solução) mais adequada para atender aos requisitos do
software (problema), uma avaliação dessa estrutura deve ser realizada. A arquitetura, portanto, consiste em
um modelo de alto nível que possibilita um entendimento e uma análise mais fácil do software a ser
desenvolvido.
O uso de arquitetura para representar soluções de software foi incentivado principalmente por duas
tendências:
 o reconhecimento por parte dos projetistas de que o uso de abstrações facilita a visualização e o
entendimento de certas propriedades do software;
 a exploração cada vez maior de frameworks visando diminuir o esforço de construção de produtos
através da integração de partes previamente desenvolvidas.
Uma outra propriedade da arquitetura é a possibilidade de usá-la como ferramenta para comunicar a
solução projetada às diversas partes interessadas que participam do processo de desenvolvimento do
software. Contudo, para que essa comunicação seja possível, a arquitetura deve ser representada através de
um documento conhecido como documento arquitetural.
Para se construir a arquitetura de um software, e por consequência o documento arquitetural que a
representa, os requisitos são as principais informações usadas. Durante o processo de especificação
arquitetural, além dos requisitos, outras fontes de conhecimento podem ser utilizadas para definir os
elementos arquiteturais e a forma como eles devem estar organizados. Entre essas fontes de conhecimento se
destacam principalmente a experiência do arquiteto, o raciocínio sobre os requisitos e os estilos e princípios
arquiteturais. Dentre os objetivos e desafios da fase de elaboração da arquitetura de software estão:
 garantir o alinhamento técnico do projeto às diretrizes e estratégias tecnológicas da organização, bem
como à sua cultura;
 atender as restrições gerenciais de um projeto tais como custo, prazo e competências técnicas da
equipe;
 identificar e detalhar requisitos significativos para a arquitetura de software;
 antecipar e mitigar os riscos técnicos de um projeto;
 construir provas de conceito e gerar código executável para os principais pontos de risco do projeto;
 orientar e acompanhar o time técnico para garantir a aderência do código construído às diretrizes
arquiteturais do projeto;
 validar a estabilidade e objetivos da arquitetura do produto;
 coletar lições aprendidas e promover um novo ciclo de melhorias;
 manter a rastreabilidade entre os requisitos, as definições arquiteturais e o código construído.
Vale a pena destacar o último objetivo pois consiste em garantir a rastreabilidade entre o que foi
especificado pelo Analista de Requisitos, o que está sendo projetado pelo Arquiteto e ainda pelo que será
codificado pelo desenvolvedor.

Segurança no desenvolvimento de software – COGSI 21


Esta rastreabilidade facilita uma análise dos controles de segurança que serão adotados no software.
Por meio dela é possível saber que determinada função implementada no software está aderente ao padrão
arquitetural adotado e que este padrão atende aos requisitos de segurança.
O objetivo do ciclo de desenvolvimento seguro de software é garantir que o produto final de software
tenha o nível de segurança adequado, levando em consideração o ambiente em que será executado. Para
isso, é muito importante executar atividades de segurança durante a definição da arquitetura.
As atividades de segurança conduzidas na fase de Requisitos produziram a categorização de
segurança do sistema, os requisitos especificados (inclusive os de segurança) e os diagramas de caso de
abuso. Na fase de Análise e Projeto, temos que definir orientações técnicas para auxiliar o Arquiteto de
Segurança. Dois guias são fundamentais:
 definição dos frameworks de segurança recomendados; e
 uma lista de princípios de arquitetura segura.
A definição de uma arquitetura segura inicia-se pela Análise da Superfície de Ataque, onde o Arquiteto
de segurança verifica os pontos de entrada que podem ser utilizados para fins maliciosos no software. Depois
disso, deve ser feita uma Modelagem de Ameaças para entender a que ameaças o sistema está exposto e
quais são os riscos dessas ameaças. Por fim a Arquitetura Segura do software é definida com todos os
controles de segurança que deverão ser implementados.

3.1 Frameworks de segurança


" Framework é um conjunto de classes que colaboram para realizar uma responsabilidade para um
domínio de um subsistema da aplicação"1.
Um framework define parâmetros de projeto, a forma como é realizada a divisão em classes e objetos
e suas responsabilidades, a maneira como colaboram entre si e o fluxo de controle, ditando, assim, a
arquitetura de software das aplicações que os utilizam. Além disso, fornece padrões de projetos - estruturas
essenciais para o desenvolvimento de projetos de aplicações de software - uma espinha dorsal e o continente
para os componentes criados nas aplicações e que irão funcionar dentro delas.
Os principais objetivos dos frameworks e das metodologias de desenvolvimento baseadas em
componentes são a reutilização de softwares, a padronização de desenvolvimento, a difusão do entendimento
comum entre equipes de desenvolvimento, entre outros.
Os frameworks permitem que as aplicações sejam desenvolvidas mais rapidamente e mais facilmente,
além de contribuir para a qualidade do produto final. Por meio dos frameworks os desenvolvedores contam
com estruturas bem definidas, revisadas por outras pessoas e melhoradas constantemente. Portanto, os
desenvolvedores podem se beneficiar com o uso dos frameworks quando escolhem utilizá-los para resolver
alguma função de codificação em vez de criar do zero.
Do ponto de vista da segurança do software, os frameworks podem ajudar o desenvolvedor no sentido
de fornecer funções de segurança, como:
 autenticação/autorização;
 validação/codificação de dados;
 tratamento de erros;
 logs;

1 Fayad, M. Schmidt, Object-Oriented Application Frameworks - Communications of the ACM, New York, v. 40, n.10, p. 32-38, Oct. 1997.

Segurança no desenvolvimento de software – COGSI 22


 detecção de intrusão;
 criptografia.
Existem algumas bibliotecas livres que exercem este papel muito bem. Para o desenvolvimento em
plataforma .NET, a biblioteca de proteção web da Miscrosoft (Web Protection Library 1) fornece funções para
proteger a aplicação de ataques Cross Site Scripting (XSS) e SQL Injection.
[NOTA]: Os ataques serão explicados nos Módulos mais adiante.
A biblioteca de segurança mais atual e completa hoje é a ESAPI (Enterprise Security API), mantida
pela comunidade OWASP (explicada no Módulo 1). A ESAPI é complexa e exige um bom esforço para
dominá-la, mas existem muitas pessoas contribuindo para a melhoria da documentação da ESAPI de forma a
facilitar sua adoção. No SERPRO recomendamos o uso desta biblioteca e dedicaremos uma parte do nosso
curso para explicá-la com mais detalhes. Um manual da ESAPI, em português, está disponível na Wiki do
SERPRO2.
Outro framework de segurança é o Apache Shiro, voltado para aplicações JAVA. Apesar de ser mais
simples de usar e entender do que a ESAPI, ele cobre parte das funções de segurança (autenticação,
autorização, gerenciamento de sessões e criptografia) e deixa de fora funções muito importantes, como a
validação e codificação de entradas/saídas. Além da ESAPI, que é a biblioteca recomendada e mais
abrangente, existem outros frameworks para atender controles de segurança específicos, conforme mostra a
tabela 3.1.
Nome Descrição Desenvolvedor
Spring Security Segurança para Spring Acegi Security System
AntiSamy Sanitização de rich HTML OWASP
CSRFGuard Proteção de Cross Site Request Forgery OWASP
(CSRF)
Java Simplified Encryption Libray Para criptografia Jasypt
Bibliotecas da Bouncy Castle Para criptografia Java e C# Bouncy Castle
JSReg Expressões regulares Google
Java HTML Sanitizer JAVA Google
Javascript Sandboxing Para Javacript Google
XHP Para PHP Facebook
Django Security Para Python com Django SD Elements
Tabela 3.1
Podemos ver que a lista de frameworks é bem extensa. É importante que os Arquitetos de Segurança
contribuam na especificação dos componentes recomendados para a empresa, inclusive sugerindo melhorias
corporativas desses frameworks. Outra tarefa essencial é disponibilizar ao desenvolvedor toda documentação
e orientação de uso dos frameworks de segurança.

3.2 Princípios de arquitetura segura


Durante a elaboração da arquitetura do software temos que balancear os objetivos como o custo, a
performance, a manutenibilidade , a segurança, etc. É provável que um sistema completamente seguro
apresente baixa performance. O objetivo é projetar um sistema que seja seguro enquanto tenha uma boa
performance e confiança. Os hackers tecnicamente competentes geralmente encontram um modo de burlar o
sistema, tendo em vista o tempo e os recursos empregados que costumam ser suficientes para atingir seus
propósitos.
A proteção da informação armazenada em um sistema deve ser projetada durante a fase de
arquitetura do sistema. É importante que os princípios de segurança sejam observados.
Privilégios mínimos: qualquer entidade (usuário, processo, etc.) deve receber os privilégios mínimos e os
recursos durante o menor tempo possível para cumprir uma tarefa. Esta abordagem evita que uma entidade
receba permissões que elas não precisam ter, reduzindo a oportunidade de acesso não autorizado às
informações sigilosas.
1 http://wpl.codeplex.com/
2 https://wiki.serpro/unidades/cetec/seguranca/seguranca-no-desenvolvimento/biblioteca-de-seguranca-
esapi/ESAPI/

Segurança no desenvolvimento de software – COGSI 23


Defesa em profundidade: consiste na aplicação de múltiplas camadas de proteção para que uma camada
bloqueie um ataque se a camada anterior foi transposta.
Separação de responsabilidades: este princípio orienta que devem ser atendidas múltiplas condições para
completar uma determinada tarefa sensível ou acessar uma informação sigilosa. Por exemplo, determinada
transação será aceita somente com a assinatura de mais de um indivíduo.
Arquitetura aberta: há uma discussão no mérito e nível de segurança de projetos que são mantidos em
segredo contra os que são abertos para a comunidade avaliar e contribuir. Um bom exemplo é a criptografia.
Alguns defendem que os algoritmos mantidos em segredo são mais difíceis de quebrar que um algoritmo
público. Outros defendem que a força de um algoritmo de criptografia reside somente na chave. Para a
maioria dos casos, um projeto aberto que foi avaliado e testado por muitos experts, provavelmente deve
possuir uma segurança maior do que aqueles que não foram largamente acessados e testados. A segurança
desses sistemas não deve se concentrar apenas na forma como trabalham (algoritmo), mas deve-se garantir o
sigilo e manutenção1 das chaves.
Falha segura: este princípio significa que caso ocorra uma falha no sistema ele deve retornar a um estado
onde a segurança não seja comprometida. Uma implementação desta ideia seria fazer com que o sistema
passe para um estado padrão onde os usuários e processos não podem acessar o sistema. Uma regra
complementar é assegurar que o sistema seja recuperado para um estado seguro. Nos casos onde a
recuperação é feita manualmente, o sistema em falha deve restringir o acesso somente ao administrador e
deixar que os usuários acessem somente depois de restabelecer os controles de segurança.
Economia de mecanismos: defende que o projeto ou a implementação dos controles de segurança seja
simples e compreensível. Isto evita que o sistema apresente corvert channels 2.
Carga de trabalho: o custo de um controle de segurança necessário para diminuir um risco deve ser
comparado com o custo da perda da informação resultante de um ataque que explora a vulnerabilidade
associada à este risco.
Elo mais fraco: como no ditado que diz "uma corrente é tão forte quanto o seu elo mais fraco", a segurança
da informação é tão boa quanto o seu componente mais frágil. Portanto, é importante identificar o mecanismo
mais fraco em uma arquitetura e fortalecê-lo para que os riscos ao sistema sejam mitigados até o nível
aceitável.
Evitar segurança por obscuridade: este princípio é a generalização do princípio de arquitetura aberta. Ele
defende que a segurança não deve ser obtida pelo desconhecimento de como o sistema funciona, mas sim
por um controle de segurança bem implementado (um desafio/resposta, certificado digital, etc.)
Isolamento de entidades não confiáveis: consiste em isolar as entidades ou os processos não confiáveis
para que o comportamento deles não afete o funcionamento esperado do sistema ou consiga acesso a áreas
restritas. Este princípio pode ser obtido por meio de sandboxing, máquinas virtuais, módulos de
processamento confiáveis e configurações do controle de acesso.
A tabela 3.2 agrupa os princípios de segurança em 3 objetivos gerais:
Objetivo Geral 01 Objetivo Geral 02 Objetivo Geral 03
Minimizar o número de alvos de alta Não expor componentes vulneráveis Negar ataques que venham a comprometer o
consequencia sistema
privilégios mínimos manter arquivos de configuração do sistema simplificar o design
separados da aplicação
separação de trabalhos isolamento de entidades não confiáveis manter todos os autores responsabilizados
minimizar o número de pontos de evitar problemas de temporização, sincronização e
entradas/saída sequenciamento
assumir que os dados do ambiente não são falha segura
confiáveis
usar somente interfaces seguras para os funções do servidor nunca devem confiar em dados
recursos do ambiente originados pelo cliente
Tabela 3.2

1 Acerca de manutenção, temos tanto o processo que envolve a definição de chaves difíceis de serem deduzidas, como o processo de
substituição das chaves com determinada frequência.
2 Segundo a ABNT NBR ISO/IEC 17799:2005, Covert channels são caminhos não previstos para conduzir um fluxo de informações, mas que
no entanto podem existir num sistema ou rede.

Segurança no desenvolvimento de software – COGSI 24


3.3 Análise da Superfície de Ataque
Os pontos de entrada e saída de uma aplicação que são acessíveis aos usuários e atacantes são
referenciados como a superfície de ataque da aplicação. O objetivo é analisar e reduzir a superfície de
ataques de uma aplicação. Os pontos de entrada são as interfaces, serviços, protocolos, códigos, etc. Os
pontos de saída consistem nas mensagens produzidas pela aplicação, relatório, respostas a uma interação,
etc. Esses pontos de entrada/saída devem estar acessíveis somente aos usuários que possuam o nível
adequado de confiança.
Michael Howard mostra em seu artigo "Fending Off Future Attacks by Reducing Attack Surface" que é
possível calcular a "atacabilidade"1, a probabilidade de um sistema ser atacado ou a exposição da aplicação a
ataques, mas não necessariamente a vulnerabilidade. Esta é uma ideia muito importante a respeito da
superfície de ataque. Uma aplicação com superfície de ataque muito grande implica em sua exposição ser alta
e, consequentemente, um aumento em sua probabilidade de ser atacada. Porém, isso não quer dizer que a
aplicação necessariamente esteja vulnerável a esses ataques.
Para analisar a superfície de ataque de uma aplicação é necessário identificar as funcionalidades ou
os pontos de entrada e saída que são passíveis de serem atacados. Esses pontos podem ser chamados de
vetores de ataques. Em uma arquitetura é importante identificarmos todos esses vetores para que sejam
aplicados controles de segurança quando necessário.
Para cada projeto de software é necessário criar uma visão simplificada da arquitetura geral. Esta
visão deve ter como base os artefatos do projeto já produzidos (especificação de requisitos, modelos de
análise, etc). É importante cobrir todos os módulos do sistema, mas a granularidade da visão geral da
arquitetura deve ser decidida de acordo com o tamanho e complexidade do sistema. O desafio é obter uma
visão simples da arquitetura e ao mesmo tempo com todas as informações relevantes das interfaces do
sistema.
A partir da visão simplificada da arquitetura devemos analisar cada componente em termos de
acessibilidade das interfaces. Esta análise envolve verificar se cada interface pode ser acessada por usuários
autorizados, usuários anônimos ou por papéis específicos da aplicação. Os componentes que fornecem a
interface também devem ser considerados no contexto da visão geral da arquitetura para que seja possível
identificar delegações de função ou dados que passam de um componente a outro. Neste momento podemos
agrupar as interfaces e componentes com perfis de acesso semelhantes. O conjunto dessas interfaces e
componentes formam a superfície de ataque da aplicação.
Com base nos grupos de interfaces e componentes da superfície de ataque, é importante verificar a
segurança das interfaces. Essa análise deve ser conduzida por alguém experiente na área de segurança, pode
ser um Arquiteto de Segurança ou um consultor externo.
Uma forma de verificar a segurança das interfaces e componentes é atribuir pesos de acordo com a
probabilidade de ser atacada e impacto ao sistema caso o ataque ocorra nesses locais. Para identificar a
probabilidade do ataque podemos verificar o nível de acesso necessário para se "chegar" a determinada
função do sistema. O nível de acesso pode variar tanto pelas permissões necessárias quanto pela sua
exposição.
A figura 3.2 mostra que quanto maior a permissão de acesso e quanto mais exposto está o sistema,
maior a superfície de ataque.

1 http://msdn.microsoft.com/en-us/library/ms972812.aspx

Segurança no desenvolvimento de software – COGSI 25


Figura 3.2
O eixo X representa as permissões necessárias para acessar determinada interface, componente ou
função do sistema. Um acesso administrativo diminui a probabilidade de que um ataque ocorra através do
recurso que está sendo analisado.
O eixo Y representa a exposição de determinada interface, componente ou função do sistema. Um
componente que é acessado somente em seu escopo local, ou seja, somente por outros componentes da
própria aplicação, tem menos probabilidade de ser explorado do que uma interface pública que pode ser
acessada por requisições de fora da aplicação.
Por fim, é importante destacar que a análise da superfície de ataque deve ser atualizada sempre que
houver mudanças nas interfaces ou componentes do sistema durante a fase de Análise e Projeto.

3.4 Modelagem de Ameaças


Uma ameaça pode ser definida como "um ator, agente, circunstância ou evento que tem potencial
para causar prejuízos a um sistema ou a seus dados e recursos." Uma ameaça pode ser categorizada por sua
intenção: não intencional; intencional, mas não maliciosa; e maliciosa (que necessariamente é intencional).
Todas as ameaças, independentemente da categoria, são capazes de comprometer o software, porém
somente as ameaças maliciosas são realizadas por meio de um ataque. A maioria dos ataques contra
softwares se aproveitam de (ou exploram) alguma vulnerabilidade ou falha no sistema.
Fazer a modelagem de um software é uma forma de visualizar as interações do sistema dentro do
ambiente em que será executado. Quanto mais a modelagem refletir o ambiente operacional em que o
software irá operar, mais útil será para a análise de segurança. Esta análise de segurança consiste em
incorporar as ameaças nos documentos de modelagem.
Daí a definição de modelagem de ameças: "uma metodologia para avaliar e documentar os pontos
fracos ou riscos de segurança de uma aplicação". A modelagem de ameaças ajuda a equipe de projeto a
identificar os componentes de maior risco, analisando o sistema sobre a perspectiva de um atacante que tem
o objetivo de comprometer o sistema.
Existem muitas sistemáticas e ferramentas para apoiar a modelagem de ameaças de um software. As
vantagens de usar ferramentas em vez de fazer um processo manual são:
 a modelagem e análise manual tendem a consumir muito mais tempo;
 quando o software a ser analisado é muito grande, a probabilidade de erros na análise é maior;
 por meio da ferramenta é possível gerar novas ameaças quando alguma alteração é feita no ambiente
da aplicação;
 a ferramenta auxilia o processo de gerar diferentes visualizações do sistema e suas ameaças;
 todos os requisitos de segurança do software são centralizados na base de dados da ferramenta,
auxiliando na rastreabilidade e entendimento dos controles de segurança.
A tabela 3.3 mostra algumas sistemáticas que podem auxiliar uma equipe na tarefa de modelagem de
ameaças. Essas sistemáticas podem servir também como um guia de referência para elaborar uma
sistemática própria do SERPRO.

Segurança no desenvolvimento de software – COGSI 26


Application Threat Modeling - Microsoft http://msdn.microsoft.com/en-
us/security/aa570413.aspx
Calculative Threat Modeling Methodology http://www.ptatechnologies.com/
Trike http://www.octotrike.org/
Consultative Object Risk Analysis System http://coras.sourceforge.net
(CORAS)
Threat Modeling based on Attacking Path (T-MAP) http://sunset.usc.edu/csse/research/COTS_Security/
Tabela 3.3
A sistemática descrita na dissertação de doutorado de Yue Chen (SOFTWARE SECURITY
ECONOMICS AND THREAT MODELING BASED ON ATTACK PATH ANALYSIS) 1 mostra como quantificar as
ameaças de segurança pelo cálculo do peso dado à severidade de caminhos de ataques relevantes aos
softwares de prateleira (commercial off the shelf).
Esta metodologia leva em consideração as prioridades das partes interessadas e o ambiente
operacional de TI. Outra característica da sistemática apresentada por Yue Chen é permitir a rastreabilidade
entre os objetivos de negócio, as ameaças de segurança e seus respectivos controles.
A Microsoft possui uma sistemática própria bastante popular2, que tem evoluído ao longo do tempo.
Em sua primeira versão, a modelagem de ameaças da Microsoft usava 6 categorias gerais de ameaças. Essas
categorias são chamadas de STRIDE, que vem do termo em inglês.
Spoffing (Enganação ou Imitação): tentativa de oter acesso a um sistema usando uma identidade falsa. Isto
pode ser realizado usando uma credencial falsa ou roubada. Depois que o atacante ganhou acesso como um
usuário ou máquina legítima, ele pode tentar a elevação de privilégios ou o abuso de funções.
Tampering (Falsificação): modificação não autorizada de dados, como, por exemplo, o tráfego que passa na
rede entre dois computadores.
Repudiation (Repúdio): habilidade de um usuário (legítimo ou não) de negar que tenha realizado uma ação
ou transação. Sem a adequada auditoria, o não repúdio é difícil de ser obtido.
Information Disclosure (Divulgação de Informação): divulgação não autorizada de informações privadas.
Por exemplo, um usuário visualiza o conteúdo de uma tabela ou arquivo que ele não tem permissão de abrir
ou monitora os dados que passam em claro pela rede. Algumas vulnerabilidades de vazamento de
informações incluem: campos escondidos em código HTML; comentários embutidos no código que revelam
informações sobre conexão com o banco ou até mesmo senhas; tratamento de exceções mal-implementado
que revela informações do sistema para o cliente; etc.
Denial of Service (Negação de Serviço): processo de deixar a aplicação ou um sistema indisponível. Este
ataque pode ser conseguido pelo "bombardeamento" de requisições para consumir todos os recursos do
sistema ou submeter uma entrada maliciosa que causa a parada total do sistema (crash).
Elevation of Privileges (Elevação de Privilégios): ocorre quando um usuário com privilégios limitados
assume a identidade de um usuário com mais privilégios. Por exemplo, um atacante com privilégio restrito
poderia elevar seu privilégio para comprometer ou tomar controle de uma conta ou processo de privilégio mais
alto.
Ameaça Princípio de Segurança Definição
Spoofing Autenticação Personalização de algo ou alguém
Tampering Integridade Alteração de código ou de dados
Repudiation Não repúdio Alegar não ter realizado determinada ação
Information Disclosure Confidencialidade Expor informações à alguém que não tenha permissão
Denial of Service Disponibilidade Negar ou degradar o serviço aos usuários
Elevation of Privilege Autorização Ganhar permissões ou capacidades sem a devida
autorização
Tabela 3.4
Para complementar o STRIDE, uma metodologia de cálculo dos riscos chamada DREAD foi criada:
Damage potential (potencial de dano): Quão alto é o dano se a vulnerabilidade for explorada?
Reproducibility (facilidade de reprodução): Quão fácil é reproduzir o ataque?
Exploitability (facilidade de exploração): Quão fácil é executar o ataque?

1 http://sunset.usc.edu/csse/TECHRPTS/PhD_Dissertations/files/ChenY_Dissertation.pdf
2 http://www.microsoft.com/security/sdl/discover/design.aspx

Segurança no desenvolvimento de software – COGSI 27


Affected users (usuários afetados): Qual é a estimativa de usuários afetados (em porcentagem)?
Discoverability (facilidade de descobrimeto): Quão fácil é descobrir a vulnerabilidade?
Podemos notar alguns pontos fracos na primeira versão da metodologia de modelagem de ameaças
da Microsoft:
 o STRIDE e DREAD são subjetivos e precisam ser aplicados por pessoas com conhecimento em
segurança para serem efetivos;
 são focados em ataques em vez de ter o foco em ameaças.
Por conta disso, a Microsoft evoluiu a metodologia para um processo mais simples e compreensível. A
nova versão da metodologia ficou mais amigável para os desenvolvedores, arquitetos e outras partes
interessadas que não são especialistas em segurança. Os guias de uso da metodologia e as ferramentas de
apoio podem ser acessados em:
http://www.microsoft.com/security/sdl/adopt/threatmodeling.aspx
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=2955

3.5 Arquitetura Segura


A última atividade de segurança da fase de Análise e Projeto é documentar a Arquitetura Segura do
software. Nesta atividade, o Arquiteto de Segurança identificará os controles para cada ameaça levantada na
modelagem de ameaças. O arquiteto pode obter auxílio de listas de verificação contendo controles de
segurança divididos em categorias específicas. Um bom documento da OWASP que foi traduzido para
português é o ASVS. No Módulo 01 apresentamos o ASVS como Application Verification Security Standard
(ASVS)1. Este documento descreve quatro níveis de segurança que podem ser atribuídos à uma aplicação web
e, para cada um dos níveis, os requisitos arquiteturais que devem ser atendidos.
Nossa atenção será na parte dos requisitos arquiteturais do documento, chamados de requisitos de
verificação. As tabelas a seguir representam alguns requisitos de verificação do AVSV.
Tabela 3.5 – Requisitos de Verificação da Arquitetura de Segurança (V1)
Nível 1A

Nível 1B

Nível 2A

Nível 2B

Nível 4
Nível 3
Requisitos de Verificação

V1.1: Identif icar todos os componentes da aplicação


(tanto individuais como grupos de códigos-f onte, V V V V V V
bibliotecas e/ou executáveis).
V1.2: Definir ou checar a existência de uma arquitetura
V V V V
de alto-nível para a aplicação.
V1.3: Identif icar as interconexões lógicas entre
componentes da aplicação, grupos de componentes e V V
sistemas externos.
V1.4: Verificar que na def inição da arquitetura da
aplicação os aspectos de segurança foram V V
documentados.
V1.5: Verificar a integridade de códigos interpretados,
bibliotecas, executáveis e arquivos de conf iguração, V
utilizando checksums ou hashes.
Observe que para cada requisito de verificação o documento associa em qual nível
de segurança cada requisito deve ser atendido. Por exemplo, para as aplicações menos
críticas (de nível 1) basta atender o requisito de verificação V1.1. Por outro lado uma
aplicação crítica (nível 4) deve atender todos os requisitos de verificação (V1.1 ao V.1.5) no
caso acima.
O ASVS define 4 níveis de verificação de segurança, onde o rigor e a cobertura das verificações
aumentam a cada nível. O Nível 1 consiste na verificação automática, sendo dividido em análise de
vulnerabilidades e análise de código. O Nível 2 consiste na verificação manual e é dividida em testes de
invasão e revisão de código. O Nível 3 consiste na verificação da arquitetura e o Nível 4 na verificação interna
1 https://wiki.serpro/unidades/cetec/seguranca/seguranca-no-desenvolvimento/recomendacoes-owasp/ASVS/

Segurança no desenvolvimento de software – COGSI 28


da aplicação (incluindo todas as bibliotecas utilizadas). O ASVS agrupa os requisitos de verificação em 14
categorias ao todo:
 V1. Arquitetura de Segurança
 V2. Autenticação
 V3. Gerenciamento de Sessões
 V4. Controle de Acesso
 V5. Validação de Entradas
 V6. Codificação/Escape de saídas
 V7. Criptografia
 V8. Tratamento de Erros e Logs
 V9. Proteção de Dados
 V10. Segurança da Comunicação
 V11. Segurança do HTTP
 V12. Configuração da Segurança
 V13. Investigação de Códigos Maliciosos
 V14. Segurança Interna
A tabela 3.6 é outro exemplo de requisitos de verificação definidos no ASVS. Estes são específicos
para o controle de acesso da aplicação. Esse tipo de de checklist contendo controles de segurança divididos
em categorias específicas podem auxiliar o Arquiteto de Software na atividade de Gerenciar os Riscos
Arquiteturais1.

Tabela 3.6 – Requisitos de Verificação do Controle de Acesso (V4)


Nível 1A

Nível 2A

Nível 2B
Nível 1B

Nível 3

Nível 4
Re quis itos de V e r ificação

V 4.1: V erif icar que os usuários podem acessar


somente URLs nas quais eles possuem autorização V V V V V
específ ica.
V 4.2: V erif icar que os usuários podem acessar
somente arquivos nas quais eles possuem autorização V V V V V
específ ica.
V 4.3: V erif icar que a navegação pelos diretórios está
V V V V
desabilitada ao menos que explicitamente desejada.
V 4.4: V erif icar que os usuários podem acessar
somente f unções protegidas nas quais eles possuem V V V V V V
autorização específ ica.
V 4.5: V erif icar que os usuários podem acessar
somente serviços nas quais eles possuem autorização V V V V
específ ica.
V 4.6: V erif icar que os usuários podem acessar
somente dados nas quais eles possuem autorização V V V V
específ ica.
V 4.7: V erif icar que os controles de acesso f alham de
V V V V
f orma segura (princípio do fail safe).
V 4.8: V erif icar que as decisões de controle de acesso
são registradas (logs), inclusive as decisões de f alha V V V
de acesso.
V 4.9: V erif icar que as mesmas regras de controle de
acesso aplicadas pela camada de apresentação são V V V V
executadas no lado servidor.
V 4.10: Verif icar que toda inf ormação usada pelos
controles de acesso não podem ser manipuladas pelos
V V V V
usuários f inais ao menos que especif icamente
autorizado.
V 4.11: Verif icar que ref erencias diretas à objetos são
protegidas, tal que somente objetos autorizados são V V V V V
acessíveis para cada usuário.
V 4.12: Verif icar que para cada tipo de recurso
protegido, existe um controle de segurança único que é V V V
usado para proteger aquele tipo de recurso.
V 4.13: Verif icar que todos os controles de acesso são
V V V V
executados do lado servidor.
V 4.14: Verif icar que todos os códigos que
implementam ou usam controles de acesso não são V
af etados por nenhum código malicioso.
V 4.15: Verif icar que as regras de negócio que limitam o
controle de acesso (por exemplo, limite de transações V V V V
diárias) não são burladas.

1 http://psds.portalcorporativo.serpro/psds/psdsplugin/guidances/guidelines/gerenciamento_riscos_arquiteturais_D12EA0F6.html

Segurança no desenvolvimento de software – COGSI 29


Um checklist deve ser customizado pela organização para atender os princípios de arquitetura segura
respeitando os padrões arquiteturais da empresa. Como o SERPRO possui diversos clientes, cada um com
requisitos muito específicos, é possível haver um checklist geral e outros específicos para determinados
clientes.
Outra tarefa importante é definir a prioridade de cada controle e selecionar os frameworks de
segurança que serão adotados. A prioridade deve ter como base a probabilidade e impacto da ameaça a que a
interface ou componente da aplicação estão expostos (atividade realizada na modelagem de ameaças).
A tabela 3.7 representa a estrutura geral de um checklist, composto pelo grupo, descrição do item e
prioridade de adoção do requisito, sendo esta última definida para cada aplicação.
ID Grupo Descrição Prioridade
1 Registro de Aplicação apta a receber auditorias de segurança.
Auditoria
2 Controle de Acesso A autorização controlada tanto nas telas quanto nas chamadas às regras de negócio.
3 Banco de Dados A base de dados do sistema acessada para alteração de estruturas (DDL), o que será realizado
apenas por um usuário administrador do banco de dados, e não, por usuários da aplicação.
4 Controle de Acesso Anti-Robô na Autenticação
5 Tráfego de dados Certificação de que as informações transmitidas não são alteradas acidental ou maliciosamente em
nenhum ponto de seu trajeto entre um emissor e um receptor.
6 Controle de Acesso Credenciais de acesso ao sistema, individuais para cada usuário (CPF ou um Código Especial).
7 Não repúdio Não Repúdio, garantia, através de criptografia, de que um emissor não pode negar que enviou uma
mensagem que foi recebida por um receptor.
8 Controle de Sessão O sistema expira a sessão do usuário por inatividade, configurável para a aplicação
9 Infraestrutura Balaceamento de Carga na Aplicação
10 Modelo Arquitetural Acesso à camada de negócio protegida;
... ... ...
Tabela 3.7
Para cada aplicação que será construída, é necessário que um checklist deste seja respondido. A
próxima fase do ciclo de desenvolvimento seguro, a fase de codificação, deve atender às especificações de
arquitetura. A figura 3.3 resume as atividades da fase de Análise e Projeto ligadas à segurança da aplicação a
ser construída.

Figura 3.3

Segurança no desenvolvimento de software – COGSI 30


4 Implementação segura de software
Escrever um código seguro é uma dos aspectos mais importantes do ciclo de desenvolvimento seguro.
Um código escrito sem a implementação adequada dos controles de segurança está sujeito a ataques. Alguns
dos ataques mais comuns contra aplicações hoje incluem ataques de injeção de código contra o banco de
dados e armazenamentos em diretórios, ataques cross site scripting (XSS), cross site request forgery (CSRF) e
buffer overflows.

Hoje em dia, a maior parte dos relatos de incidentes que envolvem brechas de segurança apresentam
uma característica em comum: são ataques que exploram alguma vulnerabilidade na camada de aplicação. A
análise das vulnerabilidades invariavelmente indica um dos seguintes procedimentos para apontar a causa da
violação: falhas de projeto, questões de codificação (implementação), questões de configuração inadequada e
operações, com a prevalência de ataques que exploram vulnerabilidades de codificação da aplicação.
Geralmente os hackers mais experientes possuem um conhecimento abrangente, que vai desde o
funcionamento dos protocolos de rede até a implementação e uso de frameworks. Portanto é necessário que o
desenvolvedor saiba como os seus códigos podem ser explorados e as técnicas defensivas de codificação,
incluindo o gerenciamento de memória, análise estática e dinâmica de código, revisão por pares e segurança
no processo de geração da build. Além disso, o desenvolvedor deve conhecer os 25 erros de codificação mais
comuns que deixam a aplicação vulnerável (CWE/SANS Top 25) e as 10 vulnerabilidades mais comuns
(OWASP TOP 10).

4.1 Erros comuns no desenvolvimento de software


O Mitre1, centro de pesquisas Federais dos EUA, em parceria com a organização educacional SANS,
editou um documento, o CWE/SANS Top 252, que descreve os 25 erros de software mais perigosos. A sigla
CWE é de Commom Weakness Enumeration ou lista de fraquezas comuns. O CWE contribui para uma
linguagem comum que descreve as vulnerabilidades da codificação de softwares. Além disso, pode ser
utilizada como um padrão para medição de ferramentas de segurança e para ajudar na identificação,
mitigação e prevenção de vulnerabilidades. Os erros descritos no CWE/SANS Top 25 são considerados os
mais perigosos pelos seguintes motivos:
 eles ocorrem com frequência;
 são fáceis de achar;
 fáceis de ser explorados;
 com frequência permitem que um atacante tome o controle total do software, roube informações ou
faça com que o software pare de funcionar.
O CWE/SANS Top 25 pode ser utilizado como forma de treinamento e conscientização dos
programadores com ou sem experiência em segurança para que eles evitem os erros mais comuns de
implementação de softwares. O documento pode ser utilizado por responsáveis pela aquisição de softwares
para que consigam definir critérios de segurança na aceitação do software. Os gerentes de projeto de
softwares podem se beneficiar deste documento na medição do esforço de segurança do projeto. A lista geral

1 http://www.mitre.org/
2 http://cwe.mitre.org/top25/index.html

Segurança no desenvolvimento de software – COGSI 31


dos erros contidos no CWE/SANS Top 25 está na tabela 4.1.
CWE/SANS Top 25
Posição Nome
1 Validação imprópria de elementos usados em comandos SQL
2 Validação imprópria de elementos usados em comandos do Sistema Operacional
3 Cópia de buffer sem verificar o tamanho da entrada
4 Validação imprópria de entrada de dados durante a geração da página web
5 Falta de autenticação em funções críticas
6 Falta de autorização
7 Informações credenciais explícitas no código
8 Falta de criptografia de dados sensíveis
9 Falta de restrições no upload de arquivos
10 Confiança em entradas inseguras na tomada de decisão
11 Execução com privilégios desnecessários
12 Cross-Site Request Forgery (CSRF)
13 Limitação imprópria do caminho no acesso a diretórios restritos
14 Falta de verificação de integridade no download do código
15 Autorização incorreta
16 Inclusão de funcionalidades de locais remotos não confiáveis
17 Atribuição incorreta de permissões para recursos críticos
18 Uso de funções potencialmente perigosas
19 Uso de algoritmo fraco de criptografia
20 Cálculo incorreto do tamanho do buffer
21 Restrição imprópria de tentativas excessivas de autenticação
22 Redirecionamento para URLs não confiáveis
23 Falta de controle na formatação de String
24 Overflow de inteiros
25 Uso inseguro da função de hash
Tabela 4.1
O CWE/SANS Top 25 dividem a lista apresentada na tabela anterior em 3 categorias gerais:
Interação insegura entre componentes
Posição Nome
1 Validação imprópria de elementos usados em comandos SQL
2 Validação imprópria de elementos usados em comandos do Sistema Operacional
4 Validação imprópria de entrada de dados durante a geração da página web
9 Falta de restrições no upload de arquivos
12 Cross-Site Request Forgery (CSRF)
22 Redirecionamento para URLs não confiáveis
Tabela 4.2
A categoria interação insegura entre componentes consiste em formas inseguras de envio e
recebimento dos dados entre componentes, módulos, programas, processos, etc.

Segurança no desenvolvimento de software – COGSI 32


Gerenciamento inadequado de recursos
Posição Nome
3 Cópia de buffer sem verificar o tamanho da entrada
13 Limitação imprópria do caminho no acesso a diretórios restritos
14 Falta de verificação de integridade no download do código
16 Inclusão de funcionalidades de locais remotos não confiáveis
18 Uso de funções potencialmente perigosas
20 Cálculo incorreto do tamanho do buffer
23 Falta de controle na formatação de String
24 Overflow de inteiros
Tabela 4.3
O gerenciamento inadequado de recursos consiste nos casos em que o software não gerencia
adequadamente a criação, uso, transferencia ou destruição de recursos do sistema.
Configurações inseguras
Posição Nome
5 Falta de autenticação em funções críticas
6 Falta de autorização
7 Informações credenciais explícitas no código
8 Falta de criptografia de dados sensíveis
10 Confiança em entradas inseguras na tomada de decisão
11 Execução com privilégios desnecessários
15 Autorização incorreta
17 Atribuição incorreta de permissões para recursos críticos
19 Uso de um algoritmo fraco de criptografia
21 Restrição imprópria de tentativas excessivas de autenticação
25 Uso de função de hash fracas
Tabela 4.4
As configurações inseguras consistem em técnicas defensivas malconfiguradas que podem ser
burladas ou ignoradas. Estudaremos em detalhes alguns dos principais erros apresentados no CWE/SANS Top
25 em um item mais adiante deste módulo. Antes vamos conhecer as vulnerabilidades mais comuns em
aplicações web.

4.2 Vulnerabilidades das aplicações web


A OWASP lançou em 2004 a primeira versão do documento TOP 10, que descreve as 10
vulnerabilidades que mais ocorreram naquele ano em aplicações web. A partir da primeira versão do
documento, a OWASP tem mantido o TOP 10 atualizado a cada 3 anos: a segunda versão foi lançada em
2007 e a versão mais atual lançada em 2010.
A ultima versão do documento OWASP Top 10, além de considerar as questões mais comuns de
segurança de aplicações a partir da perspectiva das vulnerabilidades (como fez nas versões de 2004 e 2007),
abrange agora a perspectiva dos riscos organizacionais (riscos técnicos e impacto nos negócios), como
mostrados na Tabela 4.2. A classificação das vulnerabilidades vai desde a A1 (a que ocorreu com mais
frequência) até a A10 (a décima vulnerabilidade que mais ocorreu).

Segurança no desenvolvimento de software – COGSI 33


OWASP Top 10
Vulnerabilidade Descrição
A1 - Injeção de código Falhas de injeção, tais como SQL, SO e LDAP ocorrem quando dados não confiáveis são enviados para um
interpretador como parte de um comando ou consulta (query). Os dados do ataque hostil podem iludir o
interpretador em executar comandos indesejáveis ou acessar dados não autorizados.
A2 - Cross Site Scripting Falhas XSS acorrem sempre quando uma aplicação recebe dados não confiáveis e envia-os para um navegador
(XSS) sem validação ou “escaping” (consiste no processo de substituição de determinados caracteres ASCII com seus
equivalentes em entidade HTML). XSS permite aos atacantes executarem scripts no navegador da vítima e
“sequestrar” a sessão do usuário, alterar sites de forma perniciosa ou redirecionar o usuário para sítios
maliciosos.
A3 – Falha na autenticação "Funções da aplicação relacionadas com autenticação e gestão de sessões geralmente são implementadas de
e no gerenciamento de forma incorreta, permitindo que os atacantes comprometam senhas, chaves e tokens de sessão ou, ainda,
sessões venham explorar alguma falha da implementação e possam assumir a identidade de outro usuário."
A4 - Referência Insegura a Uma referência insegura a um objeto ocorre quando um programador expõe uma referência à implementação
Objetos direta de um objeto (diretório, arquivo ou registro da base de dados) sem que haja uma verificação de controles de
acessos ou outra proteção. Os atacantes podem manipular estas referências para comprometer dados sensíveis
e sigilosos.
A5 - Cross Site Request Um ataque CSRF força a vítima que possui uma sessão ativa em um navegador a enviar um pedido (request)
Forgery (CSRF) HTTP forjado, incluindo o cookie da sessão, bem como outras informações da sessão, a uma aplicação WEB
vulnerável. Esta falha permite ao atacante forçar o navegador da vítima a criar requisições que a aplicação
vulnerável aceite como requisições legítimos, realizadas pela vítima.
A6 - Segurança A segurança depende também de configurações específicas na aplicação, envolvendo: frameworks, servidor web,
Configurada Incorretamente servidor de aplicações e plataforma. Todas essas configurações devem ser definidas, implementadas e mantidas,
pois muitas vezes elas não vem aplicadas diretamente da fábrica.
A7 - Falha na Restrição de Muitas aplicações web verificam os direitos de acesso URL antes de mostrarem links e botões protegidos. No
Acesso a URL entanto, as aplicações devem realizar o controle de acesso quando as páginas são requisitadas. Caso contrário
os atacantes podem forjar URLs e acessar estas páginas.
A8 - Encaminhamentos e Uma aplicação WEB redireciona e encaminha usuários para outras páginas e sítios web e usa dados não
Redirecionamentos não confiáveis para determinar as páginas de destino. Sem uma validação adequada, os atacantes poderão
validados redirecionar a vítima para sítios de pishing ou malware ou usar o encaminhamento para acessar páginas não
autorizadas.
A9 - Criptografia Insegura Muitas aplicações WEB não protegem devidamente dados sensíveis, como cartões de créditos, CPFs e
credencias de autenticação com algoritmos de criptografia e hash. Os atacantes podem usar esta vulnerabilidade
na proteção dos dados para realizar roubo de identificação, fraude de cartões de crédito ou outros crimes.
A10 - Proteção insuficiente As aplicações frequentemente falham na encriptação do tráfego de rede quando é necessário proteger
no Nível de Transporte comunicações sensíveis. Quando o fazem, fazem-no com suporte a algoritmos fracos, com certificados inválidos
ou expirados ou fazem-no de forma incorreta.
Tabela 4.5
Veremos mais detalhes de cada uma das vulnerabilidades contidas no OWASP Top 10
correlacionando com os erros mais comuns apontados pelo CWE/SANS Top 25.

4.2.1 Injeção de código


As falhas de injeção de código ocorrem quando um dado fornecido pelo usuário não é validado antes
de ser processado. Um atacante submete uma informação que é interpretada como um comando ou parte de
um comando. Praticamente todas as fontes de entrada de dados são passíveis de ataques de injeção caso não
ocorra a validação dos dados antes de serem processados.
Alguns exemplos de vetores de ataque comuns de injeção de código são: query strings, entradas de
um formulário, applets em aplicações web, etc. As falhas de injeção de código são facilmente descobertas por
meio da revisão de código ou testes de invasão.
Os tipos mais comuns de injeção de código são SQL Injection, OS command injection, LDAP injection
e XML injection. O conceito da falha é o mesmo em todos os casos: a consulta ou o comando é construído a
partir de informações não validadas submetidas pelo usuário.
A figura 4.2 ilustra como uma requisição gerada por um usuário malicioso contendo injeção de código
modifica um recurso da aplicação (neste exemplo através de uma consulta direcionada ao banco de dados).

Segurança no desenvolvimento de software – COGSI 34


No caso do SQL Injection, o atacante explora a forma como as consultas ao banco de dados são
formadas. A implementação de código vulnerável abaixo mostra a construção dinâmica de uma consulta
(sqlQuery) a partir de dados submetidos nos campos de entrada (usuario e senha) de um formulário.

String sqlQuery = " SELECT * FROM USERS WHERE user_id = ' " + usuario.Text + " ' AND user_pass = ' " +
senha.Text + " '

Se um atacante fornecer o nome do usuário como ' OR 1=1 -- a consulta final que será submetida ao
bando de dados será:
String sqlQuery = “ SELECT * FROM USERS WHERE user_id = ' “ + ' OR 1=1 -- + “ ' AND user_pass = ' “ +
senha.Text + “ '
A informação em vermelho será ignorada por conta do comentário --

Podemos associar a vulnerabilidade de injeção de código com os erros comuns no desenvolvimento


de softwares apontados pelo CWE/SANS. A tabela 4.3 ilustra essa ligação.

OWASP Top 10 CWE/SANS Top 25


A1 - Injeção de CWE/SANS 01 - Validação imprópria de elementos usados em comandos SQL
código
CWE/SANS 02 - Validação imprópria de elementos usados em comandos do Sistema Operacional
Tabela 4.6
As práticas de codificação defensivas ou estratégias preventivas que podem controlar as
vulnerabilidades de injeção de código são descritas a seguir:
 considerar todas as entradas de dados como não confiáveis e fazer a validação;
 filtrar as entradas com uma lista de caracteres permitidos (lista branca), rejeitando a entrada de tudo o
que estiver fora da lista;
 uma lista contendo os caracteres não permitidos (lista negra) é uma opção que pode ser usada em
conjunto com a anterior. Deixar somente a lista negra é insuficiente, pois o atacante pode utilizar
formas variadas para uma mesma entrada de dados;
 fazer a codificação dos dados para o conjunto de caracteres apropriados, fazendo com que as
entradas de dados não sejam interpretadas como código;
 fazer o escaping dos caracteres especiais;
 quando possível, evitar contrução dinâmica de consultas (SQL, LDAP, XPATH ou Xquery);
 mostrar mensagens de erro genéricas com o mínimo de informações sobre a estrutura do software.

Segurança no desenvolvimento de software – COGSI 35


A figura 4.3 ilustra como um mecanismo de validação dos dados de entrada pode barrar a tentativa de injeção
de código:

Figura 43
A figura 4.4 ilustra como um mecanismo de codificação dos dados evita um ataque de SQL Injection,
transformando os parâmetros enviados pelos usuários em uma sequência literal de caracteres.

Figura 4.4
A OWASP está desenvolvendo um projeto de tutoriais em vídeo para explicar de forma bem didática
as vulnerabilidades apresentadas pelo OWASP TOP 10. No segundo episódio desta série de tutoriais são
apresentadas as vulnerabilidades de injeção de código. Os vídeos estão no youtube e seus endereços estão
na página do projeto: https://www.owasp.org/index.php/OWASP_Appsec_Tutorial_Series

4.2.2 Cross site scripting


O ataque cross site scripting, conhecido como XSS, é muito comum nas aplicações web. As falhas
XSS ocorrem sempre que uma aplicação recebe dados não confiáveis e os envia para um navegador, sem
que os tenha validado ou feito codificação dos caracteres, processo também conhecido como escaping ou
encoding. Consiste na substituição de determinados caracteres ASCII pelas suas entidades HTML
equivalentes. Por exemplo, a codificação poderia substituir o caractere "<" pela entidade HTML equivalente
"&lt;". Essas entidades são "inertes" na maioria dos interpretadores - especialmente em navegadores - e
podem atenuar ataques do lado do cliente.
A vulnerabilidade XSS permite aos atacantes executarem scripts (java script, vb script, etc) no
navegador da vítima, para com isso obter informações da sessão do usuário, alterar a aparência dos sites ou
redirecionar o usuário para sites maliciosos. Os ataques XSS basicamente ocorrem de duas formas: XSS

Segurança no desenvolvimento de software – COGSI 36


Persistido e XSS Refletido.
O XSS persistido ocorre quando os dados de entrada do cliente são armazenados em uma base de
dados e o script passa a ser executado no browser do cliente toda vez que um cliente acessa a página
contendo a informação armazenada. O ataque ocorre por que a sequência de caracteres recuperada no banco
de dados é concatenada sem nenhum tratamento na formação da página HTML. Este caso é comum em
mensagens de fóruns, comentários dos visitantes, etc.
A figura 4.5 mostra um caso onde o atacante consegue persistir um script contendo ataque XSS no
banco de dados da aplicação.

Figura 4.5
O atacante consegue realizar a persistência do script XSS através de diversas formas, como: envio de
um formulário contendo script XSS, manipulação dos parâmetros de uma requisição GET ou POST, através de
uma vulnerabilidade de SQL Injection presente na aplicação e manipulação dos campos presentes em uma
requisição SOAP quando se utiliza Web Services. A figura 4.6 mostra um caso onde o usuário acessa a página
vulnerável que renderiza o script XSS persistido."

Figura 4.6
A falha está presente tanto na camada de controle que não realizou a validação dos dados de entrada,
como na camada de apresentação que não codificou os dados exibidos na página, permitindo que o script
XSS persistido seja renderizado no browser do usuário.
O XSS refletido é um tipo de ataque semelhante ao XSS persistido, porém a entrada de dados do
usuário não é armazenada em uma base de dados, ela é somente incluída na resposta do servidor para o

Segurança no desenvolvimento de software – COGSI 37


cliente. Este caso é comum em páginas que informam os resultados de uma busca, páginas de confirmação
de um formulário ou páginas de erro.
De modo semelhante, a aplicação usa dados não confiáveis na construção da página HTML, sem
antes realizar a validação dos dados recebidos, ou então a codificação dos dados a serem renderizados na
página HTML. A figura 4.7 mostra um exemplo onde o atacante envia para o usuário um link malicioso que ao
ser clicado pelo usuário dispara uma requisição contendo um script XSS para uma página vulnerável que
renderiza o script XSS.

Figura 4.7
As consequências de um ataque de XSS bem sucedido variam bastante e são graves. Os atacantes
podem executar um script no browser da vítima e:
 roubar informações de autenticação;
 roubar informações da sessão do usuário, possibilitando que ele se passe por alguém já autenticado;
 pichar sites;
 redirecionar os usuários a páginas maliciosas;
 inserir conteúdo hostil.
Os erros comuns no desenvolvimento de softwares que estão associados aos ataques de XSS estão
listadas na tabela 4.4.
OWASP Top 10 CWE/SANS Top 25
A2 - Cross site scripting CWE/SANS 04 - Validação imprópria de entrada de dados durante a geração da página web
Tabela 4.7
Os controles de segurança que podem ser adotados para evitar os ataques de XSS incluem:
 tratar as saídas (output) para o cliente usando escaping ou encoding de caracteres, fazendo com que o
script submetido pelo atacante seja tratado como um mero texto a ser renderizado pelo browser.
 validar todas as entradas de dados por meio de um lista branca. Essas entradas incluem os
cabeçalhos, cookies, URL, campos do formulário, campos escondidos, etc. Essa validação deve
decodificar qualquer valor codificado (encoding) e verificar o tamanho, os caracteres, o formato e as
regras de negócio do dado de entrada antes de ser aceito.
 utilizar frameworks que fornecem proteção contra XSS, seguindo as bibliotecas padronizadas pela
empresa (vide item 3.1).
A figura 4.8 mostra como um esquema de validação de dados pode impedir a persistência de um
scripts XSS.
A figura 4.9 mostra como um processo de codificação de caracteres pode impedir que um script XSS
persistido seja renderizado no browser do usuário. As técnicas de prevenção apresentados no tópico anterior

Segurança no desenvolvimento de software – COGSI 38


(validação dos dados de entrada e codificação dos dados de saída), também se aplicam na proteção contra
XSS Refletido.
A figura 4.10 mostra como um processo de codificação de caracteres impede que o script XSS
refletido seja renderizado no browser do usuário.
No terceiro episódio da série de tutoriais da OWASP (último lançado até o dia 12/07/11) é apresentado
o XSS. Confira os vídeos disponíveis na página do projeto:
https://www.owasp.org/index.php/OWASP_Appsec_Tutorial_Series
Figura 4.8

Figura 4.9

Figura 4.10

4.2.3 Buffer overflow


Historicamente este ataque contra os softwares era um dos mais problemáticos. Ele afeta diretamente
a maneira como é realizada a execução do programa e o seu gerenciamento de memória. O buffer overflow é
uma condição que ocorre quando o dado copiado para dentro de um buffer é maior do que este espaço pode
tratar. As principais causas de buffer overflows são:
 cópia de dados para o buffer sem checar o tamanho da entrada de dados;
 acessar o buffer com valores de tamanho incorretos;

Segurança no desenvolvimento de software – COGSI 39


 validação imprópria do índice da matriz (forma mais simples de expressar um buffer);
 cálculo incorreto do tamanho do buffer antes da alocação de dados.
A maneira mais provável de achar um buffer overflow é por meio da análise de código (será discutida
no módulo 5) ou engenharia reversa. Um atacante provavelmente possui o executável do software e realiza
testes exaustivos para descobrir uma vulnerabilidade de buffer overflow. Por esta razão, é muito incomum
encontrar esse tipo de problema em aplicações web que são customizadas, que não são de prateleira, e em
aplicações escritas em linguagens que fazem o seu próprio gerenciamento de memória. 1 Por estes motivos,
ela está ausente do OWASP Top 10, que trata tipicamente de aplicações web construídas para atender
demandas de clientes específicos.
OWASP Top 10 CWE/SANS Top 25
Não aparece CWE/SANS 03 - Cópia de buffer sem verificar o tamanho da entrada
CWE/SANS 20 - Cálculo incorreto do tamanho do buffer
CWE/SANS 24 - Overflow de inteiros
Tabela 4.8

As formas de tratamento da vulnerabilidade de buffer overflow inclui, mas não se limita a:


 usar bibliotecas ou frameworks que incluem funções de manipulação segura de strings;
 substituir funções banidas das APIs por suas alternativas seguras; 2
 promover o uso de compiladores que fazem a detecção de buffer overflows no código compilado;
 promover o uso de funcionalidades do próprio sistema operacional, tais como ASLR (Address Space
Layout Randomization)3, DEP (Data Execution Protection)4 e ESP (Executable Space Protection)5, que
dificultam a ocorrência de um ataque;

4.2.4 Falha na autenticação e no gerenciamento de sessões


As falhas na autenticação e no gerenciamento de sessões geralmente são encontradas nas funções de
logout, troca de senhas, expiração da sessão, perguntas secretas ou atualização da conta. Essas falhas
permitem que um atacante descubra informações da sessão de uma vítima e se façam passar por elas
(personificação). Essa vulnerabilidade, além de possibilitar que o atacante faça "sequestro" da sessão e
consiga personificar uma parte legítima da comunicação, pode permitir também que ele venha a burlar os
mecanismos de autenticação e autorização.
Os erros comuns de codificação que podem causar este tipo de vulnerabilidade incluem, mas não se
limitam aos casos descritos abaixo:
 uso de mais de um conjunto de controles de autenticação ou gerenciamento de sessões, permitindo
acesso por canais de comunicação variados;
 transmissão de credenciais de autenticação ou identificadores de sessão pela rede com o texto em
claro;
 armazenamento das credenciais de acesso sem passar por uma função de hash ou criptografia;
 senhas ou chaves criptográficas escritas em claro no próprio código fonte ou arquivos de
configuração;
 falta de um mecanismo aleatório ou pseudoaleatório de geração dos números de sessão ou senhas
geradas pelo sistema.
A associação entre os erros mais comuns do CWE/SANS Top 25 com a vulnerabilidade A3 da OWASP
é mostrada na tabela 4.6.

1 Para entender melhor a relação do buffer overflow com as aplicações web customizadas, leia o artigo
disponível em: https://www.whitehatsec.com/articles/mythbusting_buffer_overflow.shtml
2 Uma lista de funções banidas e suas substitutas para a linguagem C e C++ está disponível em:
https://buildsecurityin.us-cert.gov/bsi-rules/home.html
3 http://en.wikipedia.org/wiki/Address_space_layout_randomization
4 http://en.wikipedia.org/wiki/Data_Execution_Prevention
5 http://en.wikipedia.org/wiki/Executable_space_protection

Segurança no desenvolvimento de software – COGSI 40


OWASP Top 10 CWE/SANS Top 25
A3 - Falha na autenticação e no CWE/SANS 05 - Falta de autenticação em funções críticas
gerenciamento de sessões
CWE/SANS 07 - Informações credenciais explícitas no código
CWE/SANS 21 - Restrição imprópria de tentativas excessivas de autenticação
Tabela 4.9
Para prevenir que uma aplicação sofra ataques relacionados a falha na autenticação e no
gerenciamento de sessões algumas considerações importantes incluem:
 usar um mecanismo de autenticação e gerenciamento de sessões comprovadamente seguro, pois
implementar seu próprio mecanismo aumenta a probabilidade de erros de codificação;
 usar um único mecanismo de autenticação, de preferência um que suporte autenticação em múltiplos
fatores (veja os fatores de autenticação no item 1.1 deste documento) ou controle de acesso baseado
em papéis;
 fazer a criptografia ou gerar um hash das credenciais de autenticação antes de armazená-las em
arquivos de configuração ou na base de dados;
 certificar-se de que todas as proteções contra XSS (apresentadas no item 4.2.2) estão funcionando
corretamente. Um ataque de XSS permite o roubo das credenciais de autenticação da vítima;
 criptografar toda comunicação entre o cliente e o servidor.

4.2.5 Referência Insegura a Objetos


A referência insegura a objetos ocorre quando um usuário consegue ter acesso a funções internas do
software sem ter a autorização necessária. Esse ataque pode ser realizado por meio da manipulação de
parâmetros e valores de outros objetos que fazem referência à funcionalidade ou ao objeto que deveria estar
protegido.
Podemos citar um exemplo simples de referência insegura a objetos para facilitar a compreensão da
vulnerabilidade. Voltando ao Sistema Escola apresentado no Módulo 2, suponha que, ao submeter a matrícula
em determinada disciplina, o aluno André envie a seguinte requisição para o servidor:
http://www.sistemaescola.com.br/matricula.asp?aluno=Andre&disciplina=Calculo1&turma=A
Neste caso, o sistema aloca o aluno em determinada disciplina na turma solicitada. Vamos supor
que um aluno mal intencionado (Charles) deseje burlar o sistema, ele pode tentar os seguintes ataques:
 submeter a inscrição para uma disciplina que não tem permissão:
http://www.sistemaescola.com.br/matricula.asp?aluno=Charles&disciplina=Calculo2&turma=A
 submeter a incrição para uma turma que não foi apresentada para ele:
http://www.sistemaescola.com.br/matricula.asp?aluno=Charles&disciplina=Calculo1&turma=B
 inscrever outro aluno sem ter permissão:
http://www.sistemaescola.com.br/matricula.asp?aluno=Bianca&disciplina=Calculo3&turma=C
Esta vulnerabilidade normalmente permite que um atacante acesse dados restritos, faça uma
escalação de privilégios, burle o mecanismo de autorização e autenticação ou obtenha informações sigilosas.
Os erros de programação associados a esta vulnerabilidade são mostrados abaixo.
OWASP Top 10 CWE/SANS Top 25
A4 - Referência Insegura a CWE/SANS 06 - Falta de autorização
Objetos
CWE/SANS 13 - Limitação imprópria do caminho no acesso a diretórios restritos
CWE/SANS 15 - Autorização incorreta
CWE/SANS 16 - Inclusão de funcionalidades de locais remotos não confiáveis
Tabela 4.10

A forma mais simples de prevenir a referência insegura a objetos é evitar expor as funcionalidades
internas da aplicação usando referências que podem ser facilmente manipuladas. Algumas estratégias para
controle incluem:
 usar uma referência indireta aos objetos, por meio de um índice ou um mapa de referências, onde
uma entrada genérica (por exemplo um código) é mapeada internamente para a localização real do
objeto ou da funcionalidade;

Segurança no desenvolvimento de software – COGSI 41


 não expor objetos por meio da URL ou parâmetros do formulário;
 marcar ou criptografar os parâmetros expostos.
Para exemplificar um controle de segurança para esta vulnerabilidade, abaixo é mostrada uma nova
forma de o Sistema Escola receber as inscrições dos alunos:
http://www.sistemaescola.com.br/matricula.asp?A8902=MMJO9T&DKL2X=4985135&0P2EQF=001
Desta forma o sistema esconde os objetos que estão sendo passados assim como codifica os seus
valores. Algumas tabelas de referência interna do sistema deveriam fazer a tradução para os valores reais:
 A8902=aluno
 MMJO9T=Andre
 DKL2X=disciplina
 4985135=Calculo1
 0P2EQF=turma
 001=A
Esta medida dificulta a realização do ataque, pois é necessário conhecer a estrutura interna ou a regra
de formação das tabelas de referência para manipular os objetos.
Outra forma de proteger os parâmetros e referências é através do uso de criptografia da query string 1,
ou seja, suponhamos a seguinte URL:
http://www.sistemaescola.com.br/matricula.asp?aluno=Bianca &disciplina=Calculo3&turma=C
Utilizando a técnica de criptografia dos parâmetros, teremos ao final um único parâmetro "qs" que
contém a Query String original criptografada para os valores informados, ex:
http://www.sistemaescola.com.br/matricula.asp?qs=000000000132b41a000001326ab5e0400014414
5532f4342432f504b43533550616464696e670080001000105247de39cbd13a8e31d049a4fd637216
0000002053eae9142e802c8678f867e2db3f5110e35fb7cde5691ba84c8d08663282d5900014a966b
321a062da27a00c7fe23eb4e1facf502345
Para tornar mais seguro ainda a criptografia da Query String, é recomendável adicionar um parâmetro
com valores aleatórios que para a aplicação não tem significado algum, ex:
aluno=Bianca &disciplina=Calculo3&turma=C&randomParam=A23FB98321CA44510074123
Assim, o parâmetro com valor aleatório fará com que a Query String sempre seja gerada com valores
diferentes, mesmo que a Query String original faça referência aos mesmos valores dos parâmetros.

4.2.6 Cross site request forgery


A vulnerabilidade de cross site request forgery (CSRF) possui uma característica que a diferencia das
demais: para que o ataque ocorra o usuário deve estar previamente autenticado no sistema vulnerável, ou
seja, o usuário possui as credenciais de autenticação. Apesar desse fator que dificulta um pouco a realização
do ataque, o impacto causado por um ataque bem sucedido de CSRF pode ser muito grave. No geral, um
atacante pode forçar que a vítima (autenticada no sistema) execute uma funcionalidade do sistema sem que
ela perceba.
Um ataque CSRF força a vítima que tenha uma sessão ativa em um navegador a enviar uma
requisição HTTP forjada, incluindo o cookie da sessão, bem como outras informações da sessão, a uma
aplicação WEB vulnerável. Esta falha permite ao atacante forçar o navegador da vítima a criar pedidos que a
aplicação vulnerável aceite como pedidos legítimos oriundos da vítima. O seguinte exemplo ilustra o cenário
de um ataque de forma a deixar mais claro como ele funciona:
Um usuário (vítima) se autentica no sistema web de seu banco, que possui uma vulnerabilidade de
CSRF. A URL do sistema é a seguinte:
http://www.meubanco.com.br/index.php
O usuário, ainda autenticado no sistema bancário, abre um e-mail (do atacante) que o induz a clicar
em um link. O link leva a vítima para o endereço:
http://www.meubanco.com.br/conta/tranferencia.php?ag=1234-5&conta=0987-6
Neste caso, o atacante conseguiu com que a vítima fizesse uma transferência bancária para outra
conta, pois ele aproveitou as credenciais de autenticação que o browser da vítima estava usando. Por isso

1 tudo que vem após o marcador "?" na URL contendo um ou mais parâmetros compostos por campo/valor, ex: http://www.exemplo.com?
field1=value1&field2=value2

Segurança no desenvolvimento de software – COGSI 42


esse ataque também é conhecido como carona de sessão (session riding attack).
OWASP Top 10 CWE/SANS Top 25
A5 - Cross site request forgery CWE/SANS 12 - Cross-Site Request Forgery (CSRF)
Tabela 4.11
Dentre os controles de segurança que os desenvolvedores podem adotar para tratar CSRF estão:
 limitar o tempo de validade das credenciais de autenticação;
 requisitar autenticação em parâmetros GET e POST, não somente via cookies;
 checar o HTTP Referer header;
 limitar o tempo de vida dos cookies de autenticação;
 quando estiver processando uma requisição via POST, desconsiderar os parâmetros GET se for
conhecido que as requisições provêm de um formulário;
 solicitar um token único e secreto em cada requisição, definido para sessão do usuário nas URLs de
submissão;
 solicitar senha para operações críticas. Esta solução dispensa o uso de Tokens, porém prejudica a
usabilidade da aplicação para os casos onde a chamada de operações críticas é frequente na
aplicação;
 aceitar requisições para as funcionalidades mais críticas da aplicação somente quando realizadas pelo
método POST do protocolo HTTP.
Os usuários podem se prevenir dos ataques de CSRF adotando algumas boas práticas de segurança,
como por exemplo:
 não salvar usuários e senhas no browser;
 não usar o mesmo browser para navegar na internet e ao mesmo tempo em sites sensíveis;
 fazer o logoff explícito depois de usar alguma aplicação web.

4.2.7 Segurança configurada incorretamente


Uma tarefa fundamental para disponibilizar um serviço de software é manter o sistema operacional
com todas as atualizações de segurança em dia. Além disso, é muito importante aplicar as configurações de
segurança corretas e necessárias nas aplicações que rodam sobre o sistema operacional. Uma falha na
configuração do software pode levar ao vazamento de informações ou até mesmo ao comprometimento total
do sistema. Alguns exemplos de configurações inseguras de softwares incluem:
 credenciais ou chaves criptográficas escritas em claro no código fonte ou em arquivos de
configuração;
 listagem de diretórios habilitada no servidor web;
 instalação de aplicativos sem alterar as permissões padrão do sistema;
 consoles administrativos com a configuração padrão do sistema;
 instalação de serviços desnecessários (portas, protocolos, páginas, arquivos ou diretórios);
 falta de atualizações do software.
OWASP Top 10 CWE/SANS Top 25
A6 – Segurança configurada CWE/SANS 7 - Informações credenciais explícitas no código
incorretamente
CWE/SANS 13 - Limitação imprópria do caminho no acesso a diretórios restritos
CWE/SANS 11 - Execução com privilégios desnecessários
CWE/SANS 17 - Atribuição incorreta de permissões para recursos críticos
Tabela 4.12
Configurações de segurança envolvem projetar, desenvolver, implantar, operar, manter e descartar o
software de maneira confiável, resiliente e recuperável. As recomendações essenciais incluem:
 alterar a configuração padrão do software para uma regra que garanta a segurança do sistema;
 proteger as chaves criptográficas e as senhas de acesso em um local seguro;
 remover serviços, processos, arquivos ou diretórios desnecessários;
 estabelecer um processo de gerenciamento de atualizações (patches de segurança).

Segurança no desenvolvimento de software – COGSI 43


4.2.8 Criptografia insegura
O impacto de vulnerabilidades relacionadas à criptografia podem causar grandes impactos ao negócio,
indo desde danos à imagem da organização até o vazamento de informações confidenciais. A maioria das
falhas de softwares relacionadas à criptografia tem as seguintes causas:
 falta de criptografia de informações sigilosas;
 uso de um algoritmo não validado ou um que foi customizado/alterado;
 uso de uma API antiga de criptografia;
 gerenciamento inseguro da chave, seja na geração, troca ou no descarte;
 armazenamento inseguro das informações que precisam ser criptograficamente seguras.
OWASP Top 10 CWE/SANS Top 25
A9 – Criptografia insegura CWE/SANS 8 - Falta de criptografia de dados sensíveis
CWE/SANS 19 - Uso de algoritmo fraco de criptografia
CWE/SANS 25 - Uso de função de hash fraca
Tabela 4.13
No ciclo de desenvolvimento seguro, a categorização de segurança das informações do sistema
(módulo 2) é responsável por identificar a criticidade dos dados do sistema. Dessa forma, podemos identificar
quais informações deverão ser criptografadas, por exemplo: dados cadastrais, senhas, dados financeiros,
informações médicas, etc. Algumas questões a ser observadas na proteção dessas informações:
 garantir a criptografia nos locais onde elas serão armazenadas, especialmente em backups de dados;
 usar um algoritmo de criptografia padronizado, de preferencia os recomendados pelo e-ping;
 garantir que todas as chaves e senhas sejam protegidas contra acesso não autorizado;
 garantir que os backups sejam criptografados e que as chaves sejam gerenciadas e armazenadas
separadamente.

4.2.9 Falha na Restrição de Acesso a URL


Uma das vulnerabilidades mais fáceis de serem exploradas em aplicações Web é a falha de restrição
de acesso às URLs. Em alguns casos, a restrição de acesso às URLs são gerenciadas por arquivos de
configuração ou verificações do código. Em outros casos, quando a aplicação está vulnerável, a única
restrição de acesso às URLs é exibir os links e botões que dão acesso às funcionalidades críticas apenas para
usuários autorizados.
Um exemplo típico é a página de administração apresentada somente para os usuários logados no
sistema com permissões de administração. Se a aplicação não implementar um processo de autenticação e
verificação de controle de acessos adequado, a URL poderá ser acessada diretamente:
http://www.sistemaescola.com.br/admin/
Mesmo que a URL esteja escondida e nunca seja exibida para um usuário não autorizado, as URLs
podem ser descobertas e suas funcionalidades acessadas. O trabalho de descoberta de URLs pode ser
realizado pelo mapeamento forçado do sistema web e é facilitado quando estruturas de diretórios comuns ou
padrões são utilizados.
Podemos associar a vulnerabilidade de falha na restrição de acesso à URL com os seguintes erros
comuns no desenvolvimento de software apontados pelo CWE/SANS.
OWASP Top 10 CWE/SANS Top 25
A7 - Falha na Restrição de CWE/SANS 06 - Falta de autorização
Acesso a URL
CWE/SANS 13 - Limitação imprópria do caminho no acesso a diretórios restritos
CWE/SANS 15 - Autorização incorreta
Tabela 4.14
Habilitar controle de acesso na URL necessita de um planejamento cuidadoso. Dentre as
considerações mais importantes podemos destacar:
 garantir que a matriz do controle de acesso é parte do negócio, da arquitetura e do design da
aplicação;
 proteger todas URLs e funções de negócio com um mecanismo de controle de acesso efetivo que
verifique as funções e direitos do usuário antes que qualquer processamento ocorra;

Segurança no desenvolvimento de software – COGSI 44


 ter em mente que os atacantes tentarão acessar URLs ou APIs importantes que estejam escondidas;
 assegurar que ações com privilégios altos e administrativos estarão protegidas;
 permitir acesso somente aos tipos de arquivos que a aplicação deve executar (html, pdf, odt, etc) e
bloquear todos os que não devam ser executados diretamente (log, arquivos XML, etc).

4.2.10 Encaminhamentos e Redirecionamentos não validados


As aplicações web frequentemente redirecionam os usuários para outras páginas e sites, tanto
explicitamente no lado do cliente quanto internamente no lado do servidor. Redirecionamentos geralmente
fazem referência a páginas externas, enquanto que os encaminhamentos lidam com as páginas internas de
uma aplicação.
Quando não há a validação adequada, um atacante poderá redirecionar as vítimas para sites
maliciosos, tentando obter informações sigilosas, instalar algum malware ou burlar o controle de acesso da
aplicação. Um exemplo para facilitar o entendimento é o de uma aplicação que tem uma página chamada
"redirect.jsp", que recebe um parâmetro chamado "url". O atacante insere a URL de um site malicioso para
fazer o phishing de dados pessoais ou instalar um malware:
http://www.aplicacaovulneravel.com.br/redirect.jsp?url=paginadoatacante.com.br
Outro exemplo é a aplicação que usa o método forward para fazer o encaminhamento entre as
diferentes partes do site. Para facilitar esse processo, a página usa parâmetro fwd que indica para qual página
o usuário deve ser encaminhado. O uso normal seria:
http://www.aplicacaovulneravel.com.br/index.jsp?fwd=outra_pagina_interna.jsp
Um atacante certamente tentará manipular a entrada de dados para tentar acessar uma página que
não tenha permissão:
http://www.aplicacaovulneravel.com.br/index.jsp?fwd=admin.jsp
OWASP Top 10 CWE/SANS Top 25
A8 – Encaminhamentos e CWE/SANS 22 - Redirecionamento para URLs não confiáveis
redirecionamentos não
validados
Tabela 4.15
O uso seguro de redirecionamentos e encaminhamentos pode ser obtido por meio dos seguintes
controles de segurança:
 evitar redirecionamentos e encaminhamentos quando possível;
 usar uma lista de URLs a que os usuários possam ser redirecionados;
 não permitir que os usuários especifiquem a URL de destino em algum parâmetro da aplicação. Se
essa for uma regra de negócio, faça a validação da URL antes de processá-la;
 alerte os usuários quando eles forem redirecionados da aplicação para um outro site externo; Este
aviso pode ser feito por meio de uma página de transição;
 utilizar referências indiretas para as URLs, por meio de uma tabela de referências ou mapa de URLs
permitidas.

4.2 Validação de estradas


Até agora vimos os principais erros de codificação, as vulnerabilidades que ocorrem com maior
frequência nas aplicações e uma visão das medidas corretivas. Para finalizar este módulo, veremos os
conceitos relacionados à principal prática de codificação defensiva 1: validação de entradas de dados.
Para garantir a segurança do sistema de informação é necessário partir da premissa de que todas as
entradas de dados são maliciosas e, por isso, é obrigatório validar todas as entradas para a aplicação. Esta
tarefa consiste em verificar que a informação submetida:
 é do tipo e formato correto;
 está dentro do conjunto de valores permitidos;
 não será interpretada como código executável (java script, SQL, etc);

1 Além da validação de entradas, o desenvolvedor precisa conhecer outras práticas de codificação defensiva. Para isso, está disponível um
guia de consulta rápida no endereço https://wiki.serpro/unidades/cetec/seguranca/seguranca-no-desenvolvimento/recomendacoes-
owasp/Guia_de_Referencia_Rapida_v1.2.pdf

Segurança no desenvolvimento de software – COGSI 45


 não seja mascarada em formatos alternativos.
A validação das entradas de dados pode ser feita por meio de um filtro, que consiste em comparar as
entradas com uma lista branca (whitelist) ou lista negra (blacklist). A lista branca especifica os caracteres,
comandos ou padrões de dados aceitos. Por exemplo, uma aplicação deve aceitar somente números e "/" no
campo data; tudo o que chegar fora deste conjunto especificado deve ser negado pela aplicação. Já a lista
negra especifica os caracteres, comandos ou padrões de dados não aceitos. Uma aplicação deve negar
números e quaisquer caracteres especiais no campo nome. Uma forma simples de implementar os filtros é por
meio de expressões regulares1.
Esta validação de dados deve obrigatoriamente ser realizada no lado do servidor, onde o usuário não
terá controle da lógica de processamento. As validações do lado do cliente podem ser realizadas
opcionalmente mais por uma questão de usabilidade da aplicação. Por exemplo, a aplicação aplica filtros no
lado cliente em um formulário de maneira que o campo data somente aceite a forma DD/MM/AAAA. No
aspecto de usabilidade do sistema, essa máscara pode ser algo desejável, porém nada agrega em termos de
segurança pois o cliente pode facilmente burlar esse mecanismo.

1 Para saber sobre expressões regulares, consulte:


Jeffrey E. F. Friedl : "Mastering Regular Expressions".
ou acesse o endereço https://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html

Segurança no desenvolvimento de software – COGSI 46


5 Testes de Segurança
Nos módulos anteriores aprendemos como especificar requisitos de segurança, elaborar a arquitetura
segura e implementar o software com segurança. Neste módulo veremos uma etapa importante do ciclo de
desenvolvimento seguro, que é a fase de testes de segurança. Os testes de segurança têm como objetivo
validar a presença e verificar a efetividade dos controles de segurança implementados no software. Neste
módulo serão abordados os diferentes tipos de testes de segurança, o modo como são conduzidos e as
equipes envolvidas em cada atividade.

5.1 Testes de software


Dentre os testes de software mais comuns entre as equipes de desenvolvimento estão os testes
funcionais, de recuperação e performance. Os testes funcionais abrangem os testes unitários, de integração,
lógicos e de regressão. Todos esses testes são muito importantes, porém eles devem ser complementados
com outros tipos de testes de forma a garantir a qualidade e a segurança do software.
A figura 5.1 mostra os tipos de teste que serão descritos neste módulo.

Figura 5.1
Testes Funcionais
Os testes funcionais têm como objetivo assegurar que o software atende às expectativas do usuário,
ou seja, estão de acordo com os requisitos especificados. Eles podem ser divididos em testes unitários,
integração, lógico e regressão.
Unitário: é o primeiro teste a ser conduzido para verificar se o software funciona corretamente. Ele é realizado
pelo desenvolvedor durante a fase de implementação. Cada parte do software é testada isoladamente para
verificação de erros de build, de compilação ou da lógica de programação. Este tipo de teste é realizado mais
facilmente quando a arquitetura do software é modular, com alta coesão e baixo acoplamento. Os benefícios
dos testes funcionais incluem:
 validar a lógica funcional;
 encontrar complexidades, ineficiências, e vulnerabilidades no código (credenciais explícitas, etc.)
 alta cobertura de testes
Integração: diferentemente dos testes unitários, que verificam cada parte do software, os testes de integração
avaliam a "soma de todas partes", ou seja, a agregação de todas as unidades que formam o sistema. O
objetivo é identificar problemas que ocorrem quando as partes são combinadas.
Lógico: tem o objetivo de validar a precisão da lógica de processamento do software. A validação manual de
todas as linhas ou fazer o debug do código tem o benefício de testar grande parte do software (consegue uma
alta cobertura) para descobrir problemas no código.
Regressão: este tipo de teste tem o objetivo de garantir que alterações no software (mudanças corretivas ou
evolutivas) não interferiram negativamente nas funcionalidades anteriores. A implementação de um controle
de segurança pode negar uma funcionalidade disponível anteriormente. Por meio dos testes de regressão
podemos verificar:
 que a correção de um bug não introduziu nenhum outro bug;
 que os requisitos especificados continuarão a ser atendidos após modificações;
 que o código não modificado não seja impactado;

Segurança no desenvolvimento de software – COGSI 47


Testes de Recuperação
Os testes de recuperação, ou de recuperabilidade, têm o foco na disponibilidade do sistema e têm o
objetivo de verificar se os mecanismos de replicação, de balanceamento de carga ou de recuperação de
desastres funcionam corretamente. Por meio dos testes de recuperação podemos avaliar se o sistema atende
ao tempo máximo de parada (maximum tolerable downtime - MTD) e o tempo de recuperação (recovery time
objective - RTO) acordado com o cliente.

Testes de Performance
São conduzidos para verificar se o sistema atende aos acordos de nível de serviço (ANS) e
expectativas do negócio. Um controle de segurança necessário pode vir a impactar na performance do
software. É necessário realizar um teste de performance para identificar o(s) gargalo(s) do sistema e fazer
ajustes finos (conhecidos como tunning) no código, no sistema operacional e no hardware, para otimizar o uso
dos recursos.

Testes de Segurança
Enquanto os testes funcionais são conduzidos para verificar que o software está de acordo com o que
foi especificado, os testes de segurança têm o objetivo de causar falhas no software, verificando sua
resiliência. O foco é detectar a presença e efetividade de controles de segurança implementados no software.
Os envolvidos nos testes de segurança devem ter o foco em subverter o sistema, achando novos caminhos
para atacar o software. É importante que esses profissionais tenham capacitação adequada, inclusive em
relação à ética no serviço executado, pois é comum que eles tenham acesso a informações críticas do
sistema.
Existem três aspectos envolvidos nos ataques hackers: motivação, oportunidades e os meios. A
motivação inclui obter fama, dinheiro ou vingança. As oportunidades que eles têm consistem nas
vulnerabilidades existentes nos sistemas e os meios incluem as ferramentas e o conhecimento do atacante.
Durante os testes de segurança são analisados principalmente dois dos aspectos: as oportunidades e os
meios.

Outros tipos de testes de software


Testes de ambiente: consiste em verificar a integridade dos arquivos de configuração e dos dados do
ambiente em que o software irá operar. É importante demarcar os limites desse ambiente, pois as novas
tecnologias da web 2.0, que agregam conteúdos de outros sites, tornam necessário testar o cenário completo
para garantir a segurança do ambiente.
Testes de aceitação: consistem nos testes conduzidos antes do software entrar em produção. São
realizados pelos usuários finais com o foco maior nas funcionalidades e usabilidade da aplicação. Estender os
testes de software ao usuário final fornece uma confiança maior no produto final.

5.2 Metologias de Teste de Segurança


Existem duas abordagens principais para se descobrir vulnerabilidades em uma aplicação: testes de
caixa-branca (white box) e testes de caixa-preta (black box). Os fatores que separam estas abordagens são: o
nível de conhecimento da aplicaçãoe os recursos disponíveis no momento em que os testes são realizados.
Constituem recursos para a execução dos testes: o código-fonte da aplicação, a documentação, as bibliotecas
que ela utiliza e, em alguns casos, o próprio desenvolvedor da aplicação.

5.2.1 Caixa Branca


Os testes de caixa branca são conhecidos também como análise de código, pois o código é o principal
recurso utilizado durante os testes. Esses testes podem ser conduzidos assim que o desenvolvedor produza
algum código. Porém, o momento ideal para sua execução é em conjunto com os testes unitários ou com os
testes de integração.
As entradas para os testes de caixa branca incluem a documentação de arquitetura, o código-fonte,
arquivos de configuração, casos de uso e de abuso, os arquivos de configuração e os requisitos de segurança

Segurança no desenvolvimento de software – COGSI 48


do sistema. Por meio dos testes é possível verificar os erros relacionados à lógica interna do software. É
possível detectar problemas embutidos no código, tais como: trojans, bombas lógicas, spyware e backdoors
implementados intencionalmente por funcionários internos.
Durante a execução dos testes serão analisados os fluxos de informação e fluxos de controle, as
interfaces, as entradas e saídas de dados.
A figura 5.2 mostra o fluxo do teste de caixa branca.

Figura 5.2

Como podemos ver na figura 5.2, os testes de caixa branca são capazes de detectar defeitos ou bugs
no código, falhas na arquitetura do software ou desvio de padrões arquiteturais previamente definidos. A partir
desses apontamentos o desenvolvedor corrige o código-fonte. Em um processo de análise de código
descentralizada, em que os testes são conduzidos por uma equipe diferente da de desenvolvimento, os
responsáveis pelos testes podem abrir requisições de mudança e elaborar recomendações de correção.
A vantagem dos testes de caixa branca é a cobertura ou abrangência que consegue atingir. De posse
do código-fonte, é possível analisar todos fluxos de execução do programa. A desvantagem é a alta
complexidade, pois as ferramentas de revisão de código geralmente costumam gerar muitos falsos positivos,
ou seja, situação em que a vulnerabilidade apontada pela ferramenta é improcedente. Com isso é necessário
que o desenvolvedor ou a equipe de testes avalie todos os resultados gerados pela ferramenta. Outra
desvantagem é a baixa viabilidade, pois nem sempre é possível ter acesso ao código-fonte da aplicação.
Listas de ferramentas para análise de código podem ser acessadas em:
http://samate.nist.gov/index.php/Source_Code_Security_Analyzers.html
http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis

5.2.2 Caixa Preta


Os testes de caixa preta são o oposto dos de caixa branca. A equipe de testes tem poucos recursos
disponíveis durante os testes de caixa preta, ficando praticamente limitadas ao que o usuário final pode
observar da aplicação. Ou seja, para as aplicações web, o recurso disponível é somente a conectividade com
a aplicação. É importante observar que a aplicação deve estar em execução para se realizar os testes de
caixa preta, ao contrário dos testes de caixa branca. Assim, os testes de caixa preta consistem em uma
análise comportamental do software, enquanto os de caixa branca consistem em análises estruturais.
Existem dois momentos indicados para a realização dos testes de caixa preta: antes de colocar a
aplicação em produção ou com a aplicação em produção. A execução dos testes antes do software entrar em
produção tem como objetivo identificar e corrigir as vulnerabilidades de forma pró-ativa, minimizando os riscos
de segurança. Outra vantagem de testar antes de entrar em produção é que o custo de correção é menor se
comparado aos testes conduzidos após o software ter entrado em produção. Por sua vez, a execução dos
testes após o software entrar em produção tem a vantagem de cobrir os problemas existentes no ambiente
real da aplicação. Essa lacuna pode ser minimizada fazendo com que o ambiente de testes antes do software
entrar em produção seja o mais semelhante possível ao ambiente de produção, sendo essa a abordagem mais
recomendada.
Dentre as vantagens dos testes de caixa-preta podemos citar a viabilidade e a simplicidade. Os testes

Segurança no desenvolvimento de software – COGSI 49


de caixa preta são mais viáveis do ponto de vista de precisar de menos artefatos para a condução dos testes.
Todas aquelas entradas para os testes de caixa branca são reduzidas apenas a um requisito:
conectividade com a aplicação. A simplicidade é explicada pelo fato de ser exigido pouco (ou nenhum)
conhecimento da lógica da aplicação para a execução dos testes de caixa preta. Porém, há uma desvantagem
na metodologia de testes de caixa preta em relação à cobertura, pois é mais difícil atingir todas as partes da
aplicação.
Outra metodologia de testes encontrada na literatura é a de caixa cinza 1, qque é um meio termo entre
caixa branca e caixa preta.. O teste é realizado a partir do que o usuário final pode observar da aplicação,
porém o código-fonte ou a documentação arquitetural está disponível para direcionar a execução dos testes.

5.2.3 Diferenças entre caixa branca e caixa preta


Como vimos nos tópicos anteriores, os testes de segurança podem ser conduzidos por meio de uma
metodologia de caixa branca ou caixa preta. Cada uma delas possui suas vantagens e desvantagens que
foram mostradas por alto. Esta seção trata com mais detalhes as diferenças entre as duas metodologias.
Os testes de caixa branca podem ser executados mais cedo no processo de desenvolvimento seguro,
fazendo com que a segurança seja integrada ao código. As vulnerabilidades detectadas durante os testes de
caixa branca têm maior precisão, podem até mesmo apontar a linha de código onde se encontra o problema,
ajudando a identificar as causas do problema. Já os testes de caixa preta fornecem uma visão melhor da
capacidade do software ser realmente explorado, mostrando os efeitos de um ataque.
Entre as limitações dos testes de caixa preta estão a exatidão da causa raiz da vulnerabilidade e a
cobertura dos testes. É importante entender que mesmo os testes de caixa branca têm suas limitações quanto
à cobertura dos testes: as dependências (serviços, bibliotecas, etc.) ou os componentes de terceiros podem
não ser cobertos pelos testes por falta do código-fonte. A tabela 5.1 sintetiza as principais diferenças entre as
duas metodologias.

Tabela 5.1

5.2.4 Fuzzing
Outra metodologia de testes de segurança é o Fuzzing2, também conhecido como teste de injeção de
falhas. Fuzzing consiste em um teste de força bruta em que entradas inesperadas (aleatórias ou
pseudoaleatórias) são submetidas ao software e o seu comportamento é observado. O objetivo dos testes de
fuzzing é disparar um comportamento inseguro ou inesperado no software por meio da entrada de dados. Ele
é capaz de indicar a efetividade dos mecanismos de validação de entrada.
O fuzzing pode ser usado tanto para testar aplicações quanto para testar protocolos e formatos de
arquivos. Dentre as falhas identificadas por meio dos testes de fuzzing estão: buffer overflows, execução de
código, exceções não tratadas e DoS. Os endereços a seguir mostram dois exemplos reais de
vulnerabilidades que poderiam ter sido identificadas pelos testes de fuzzing:
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-0599
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-1788
Os testes de fuzzing podem ser divididos em duas técnicas diferentes: dumb fuzzing e smart fuzzing.
Quando os dados de entrada que serão usados nos testes forem realmente aleatórios, sem nenhuma relação
com o software, protocolo ou arquivo que será analisado, a técnica utilizada é a dumb fuzzing. Quando os
dados de entrada são gerados a partir de uma estrutura já conhecida do software, protocolo ou formato de

1 HOWARD, Michael: Escrevendo código seguro. Ed. Bookman, 2005.


2 SUTTON, Michael: Fuzzing – Brute Force Vulnerability Discovery: Pearson Education, 2007.

Segurança no desenvolvimento de software – COGSI 50


arquivo, a técnica utilizada é a smart fuzzing. Um exemplo de estrutura que poderia ser utilizada para geração
dos dados de entrada pode ser encontrada em:
http://www.mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm

5.2.5 Escaneamento de vulnerabilidades e testes de Invasão


Duas técnicas comuns de testes de caixa preta é o escaneamento de vulnerabilidades e os testes de
invasão, também conhecidos como testes de penetração (penetration tests). Uma diferença fundamental entre
essas duas técnicas consiste no modo de operação: o escaneamento de vulnerabilidades age de modo
passivo; os testes de invasão agem de forma ativa. O modo passivo é usado para detectar a presença de
vulnerabilidades que possam ser exploradas por um atacante. O modo ativo vai um passo além e tem como
objetivo verificar se o software pode ser comprometido, explorando as vulnerabilidades identificadas. Em
outras palavras, o escaneamento de vulnerabilidades identifica partes do software que podem ser atacadas,
enquanto os testes de invasão medem a resiliência do software realizando ataques reais nas vulnerabilidades
identificadas.
As informações produzidas pelo escaneamento de vulnerabilidades são úteis para:
 mapear o ecosistema computacional, a rede e as interfaces da aplicação;
 identificar versões dos servidores de aplicação, as portas abertas e os serviços ativos;
 identificar patches a serem aplicados;
 identificar vulnerabilidades.
Os testes de invasão podem produzir informações úteis para:
 fornecer uma visão mais apurada da segurança dos softwares;
 servir de referências para ações corretivas;
 determinar controles de segurança que devem ser aplicados para conter as vulnerabilidades
identificadas.
Os testes de invasão geralmente são divididos nas seguintes etapas: reconhecimento; exploração;
remoção de evidências; relatório e recomendações. Durante a fase de reconhecimento serão utilizadas
várias técnicas de enumeração do alvo. Esta primeira fase é responsável por fornecer uma descrição ampla
da aplicação que será testada (versões, interfaces, portas abertas, vulnerabilidades, etc). A segunda fase,
exploração, consiste em tentar atacar o alvo por meio de força bruta das credenciais de autenticação,
escalação de privilégios, descobrimento de informações sensíveis, manipulação da base de dados, criação de
contas, etc. A terceira fase consiste em retornar o sistema ao estado inicial, removendo todas as alterações
que foram feitas. A quarta fase é a geração do relatório, que deve incluir as recomendações técnicas de
tratamento das vulnerabilidades e também as informações de não conformidade com a política de segurança
da organização.

5.3 Testes de Segurança em software


Nesta seção abordaremos os diferentes tipos de testes e como eles devem ser realizados. O objetivo é
tratar adequadamente a segurança do código que está sendo desenvolvido na fase de implementação.
Portanto, antes de realizar os testes, é importante esclarecer o seguinte questionamento: "O software a ser
testado é novo ou é decorrente de uma nova versão (release)?"
Caso seja uma nova versão, então deverá ser validado se o atual estado de segurança não regrediu
em relação à versão anterior. Este tipo de validação poderá ser realizado através de testes de regressão,
tendo como enfoque os aspectos de segurança.

5.3.1 Mecanismo de validação de entradas


A maioria das vulnerabilidades de segurança podem ser mitigadas por meio da validação adequada
das entradas de dados. Ações maliciosas tais como: buffer overflow, injeções de código e scripting podem ser
efetivamente reduzidas caso o software realize a validação das entradas antes de efetuar o processamento.
Em um ambiente cliente/servidor, rotinas de validação de entrada devem ser utilizadas tanto no cliente
quanto no servidor. Rotinas de validação de entrada de dados no lado cliente são geralmente utilizadas para
verificar questões de performance e usabilidade, pois pouco contribuem para a segurança. Os recursos de

Segurança no desenvolvimento de software – COGSI 51


implementação das rotinas de validação de entrada de dados devem ser direcionados para efetuarem as
checagens de segurança do lado servidor.
Atributos das entradas de dados incluem: os intervalos; formatos; tipos e valores de dados. Todos eles
devem ser verificados pela rotina de validação. Quando esses atributos forem mapeados, então os testes de
segurança direcionados para o mecanismo de validação de entrada poderão ser realizados utilizando técnicas
de reconhecimento de padrões via expressão regular e/ou técnicas de fuzzing.
Os testes devem ser conduzidos para assegurar que o mecanismo de validação de entrada baseado
em whitelist (lista de padrões aceitáveis) é permitido enquanto o controle de entrada baseado em blacklist
(assinatura de entradas não aceitáveis) está realizando o bloqueio adequadamente.
Os testes não devem somente tratar das rotinas de validação (white list e black list), mas devem
também incluir cenários de testes para verificação dos mecanismos proteção contra a dissimulação da entrada
de dados, pois caso o atacante consiga usar um encoding diferente do previsto pelas listas de validação, este
não seria enquadrado pelas regras de validação e provavelmente obteria êxito no ataque.
Os ataques para burlar os mecanismos de validação de dados evoluem basicamente de duas formas:
por meio da "descoberta" de variações dos ataques existentes; e pela elaboração de novos ataques, à medida
que a tecnologia evolui (AJAX, XML, HTML 5, etc). O que ocorre com maior frequencia é a variação de um
mesmo ataque de maneira que eles passem despercebidos pelos mecanismos de filtragem. Uma das técnicas
é aplicar encoding de caracteres distintos (BASE 64, URL encoding, Hex encoding, UTF 8, etc). Por exemplo,
abaixo são mostradas 3 variações de JavaScript que produzem o mesmo resultado:
alert(document.cookie)
alert(document['cookie'])
with(document)alert(cookie)
Um exemplo de novas formas de ataque surge com o avanço da tecnologia. Por exemplo, o HTML 5
permitirá atributos em tags de fechamento:
</a onmousemove="alert(1)">
Por ultimo, o exemplo de variações na representação de dados inclui as várias formas de representar
o sinal "menor que" <
&lt; PA==
0x3C %253C
%%33%63 CHAR(60)
Por meio da técnica de variações dos ataques é possível burlar os filtros ModSecurity, PHP-IDS, XSS-
Filter do Internet Explorer e o plugin do Firefox NoScript.1

5.3.2 Teste de defesa para injeção de código


Ataques de injeção decorrem das entradas de dados fornecidas pelo usuário que, por sua vez, são
interpretadas como um comando ou parte de um comando. A validação da entrada de dados é uma
salvaguarda efetiva em relação às falhas de injeção.
Para efetuar os testes de validação de entrada, é fundamental determinar as origens das entradas de
dados e dos eventos, os quais irão disparar ações no servidor de aplicação, na base de dados ou no sistema
operacional. As entradas de dados podem ter como origem formulários de autenticação, campos de busca,
campos do tipo hidden em páginas web, querystrings em endereços de URLs, cookies, etc.
Uma vez que a origem é determinada, testes de validação de entrada podem ser utilizados para
assegurar que o software não é suscetível aos ataques de injeção de código. Para que a cobertura dos testes
em relação às falhas de injeção seja mais abrangente, existem outros testes que precisam ser executados
para assegurar que:
 Queries parametrizadas não são suscetíveis a injeção e estão sendo utilizadas corretamente;
 A construção de queries dinâmicas sem validação dos dados não é permitida;;
 Mensagens de erro e exceções são explicitamente tratadas de forma adequada;
 Precedures e declarações não essenciais são removidas do banco de dados;
 Erros gerados pelo SGBD não revelam a estrutura interna do banco de dados;

1 http://www.blackhat.com/presentations/bh-usa-09/VELANAVA/BHUSA09-VelaNava-
FavoriteXSS-SLIDES.pdf

Segurança no desenvolvimento de software – COGSI 52


 Estruturação de listas do tipo white list que somente permitem a entrada de dados no formato, tipo,
faixa de valores e tamanho adequados;
Por fim, é possível aplicar testes de caixa branca, caixa preta ou fuzzing para validar os mecanismos
de controle. Os testes de caixa branca serão aplicados para verificar se todas as funções de validação estão
implementadas de forma correta. O responsável pelos testes pode verificar se o código está em conformidade
com os controles padrões da organização, por exemplo, o uso de determinada biblioteca. Os testes de caixa
preta ou de fuzzing são aplicados de forma a submeter vetores de ataques à aplicação para tentar burlar os
controles de segurança.1

5.3.3 Teste de defesa para o não repúdio


O não repúdio pode ser tratado pelo gerenciamento e auditoria de sessões. Casos de teste devem
validar as trilhas de auditoria de forma precisa, tendo em vista a determinação dos atores e suas respectivas
ações. As trilhas de auditoria devem ser definidas de forma adequada por meio dos casos de abuso do
sistema.
Os testes de segurança devem verificar se uma determinada ação é única, está protegida e é
rastreável. Os casos de testes devem também incluir a verificação dos procedimentos de proteção e
gerenciamento das trilhas de auditoria e também a integridade dos registros de auditoria (logs). Inclui-se
também nestes testes a verificação do uso adequado dos certificados digitais.
A publicação NIST SP 800-922 fornece diretrizes para a proteção das trilhas de auditoria e
gerenciamento seguro dos arquivos de log.

5.3.4 Teste de defesa para o Spoofing


Casos de testes para verificar a possibilidade de spoofing precisam ser estruturados. Ataques de
spoofing no nível de rede incluem o address resolution protocol (ARP) poisoning, spoofing de endereço IP e
spoofing de endereço media access control (MAC).
Em relação à camada de aplicação, há testes de spoofing de usuários e certificados, phishing e a
verificação de código que possa permitir a personificação indevida de outras identidades. A estruturação de
testes para verificação de spoofing de usuário e/ou certificado em conjunto com a validação da presença de
mecanismos de proteção na camada de transporte podem garantir uma comunicação segura e proteção para
ataques do tipo man-in-the-middle.
Os casos de teste devem também contemplar a expiração de cookies e a presença de criptografia nos
mesmos.

5.3.5 Teste de falha de software


O software tende a falhar quando ocorre um erro acidental do usuário ou mesmo um ataque
intencional. Os seguintes erros de projeto de software são geralmente a causa das falhas nas aplicações:
deficiências na elicitação dos requisitos, omissão arquitetural e/ou erros de implementação.
Testes de falha de software devem incluir a verificação dos seguintes princípios de segurança:
Falha segura (fail safe): verificar a confidencialidade, integridade e disponibilidade do software ou dos dados
que são manipulados quando ocorrem falhas. Atenção especial deve ser dada para verificar a integridade de
qualquer processo de autenticação, de modo que a ocorrência de uma falha não resulte em um estado
inseguro (atacante autenticado no sistema). Também deve estar contemplado nos casos de teste o
funcionamento adequado do mecanismo de bloqueio das contas de usuários.
Tratamento de erros e exceções: verificar o tratamento de erros e exceções, que deve incluir casos de teste
para validar as mensagens de erro e também mecanismos de encapsulamento dos seus detalhamentos. Os
testes devem induzir a ocorrência de falhas para verificar se nenhuma informação sigilosa ou detalhes de
implementação estão sendo exibidos.

1 https://wiki.serpro/unidades/cetec/seguranca/seguranca-no-
desenvolvimento/treinamentos/TestesDeFuzzingParaSeguran_c3_a7aDasAplica_c3_a7_c3_b5esWeb/
2 csrc.nist.gov/publications/nistpubs/800-92/SP800-92.pdf

Segurança no desenvolvimento de software – COGSI 53


5.3.6 Teste de validação do mecanismo de criptografia
Os testes de validação do mecanismo de criptografia devem atestar:
Conformidade com padrões de mercado: confirmar a utilização dos padrões de mercado nos módulos
criptográficos, tais como os descritos no documento e-Ping. 1 É importante utilizar algoritmos
reconhecidamente seguros tais como: AES, RSA e DSA. O NIST FIPS 140-2 2 disponibiliza uma suíte de
conformidade que possibilita a aferição de quatro níveis de segurança. Validação de ambiente: o ambiente
computacional no qual ocorrem as operações criptográficas também deve ser validado. A norma ISO/IEC
15408 common criteria (CC) pode ser utilizada para esta finalidade.
Validação de ambiente: o ambiente computacional no qual ocorrem as operações criptográficas também
deve ser validado. A norma ISO/IEC 15408 common criteria (CC) 3 pode ser utilizada para esta finalidade.
Validação dos dados: os dados não validados em ambientes e sistemas criptográficos não estão protegidos
como um todo e devem ser considerados como se estivessem em texto claro. A proteção de dados sensíveis,
privados e pessoais que utilizam mecanismos de proteção criptográficos devem ser validados, tendo como
objetivo a efetividade da confidencialidade.
Implementação criptográfica: As sementes utilizadas pelos algoritmos criptográficos devem ser checadas
para que tenham um grau adequado de aleatoriedade. Testes de caixa branca permitem verificar se as chaves
criptográficas não estão implementadas no código-fonte em texto claro, pois caso estejam implementadas no
código-fonte, representam uma grande fragilidade do sistema criptográfico.

5.3.7 Teste de defesa para Buffer Overflow


As consequências de um ataque de buffer overflow podem ser devastadoras, portanto é necessário
testar as defesas contra este tipo de ataque. A vulnerabilidade 4 de buffer overflow pode ser verificada através
das técnicas de caixa preta e caixa branca. Os testes de caixa preta podem ser conduzidos utilizando técnicas
de fuzzing. Já os testes de caixa branca devem incluir os seguintes casos de teste:
 Todas as entradas de dados estão sendo tratadas, inclusive em relação ao tamanho máximo permitido
para a entrada dos dados;
 É realizada a checagem dos limites de alocação de memória;
 A conversão de um tipo de dado para outro é realizada explicitamente;
 APIs banidas e inseguras não estão sendo utilizadas;5
 O código compilado utiliza proteções em nível de compilação que protegem a pilha e/ou atribui de
forma aleatória o espaço de memória.

5.3.8 Teste de defesa para escalonamento de privilégios


Testes para verificação de cenários de escalonamento de privilégio devem ser conduzidos para que
sejam evitadas ocorrências de usuários ou processos que obtêm acesso a recursos aos quais originalmente
não deveriam ter.
O escalonamento de privilégio pode ser do tipo vertical, horizontal ou híbrido. O escalonamento de
privilégio vertical permite que um determinado usuário ou processo acesse de forma não autorizada recursos
que necessitariam de um perfil de acesso maior. Já o tipo horizontal permite o acesso de forma não autorizada
a recursos que necessitam de um perfil de acesso semelhante.
A referência insegura a objetos consiste em uma falha arquitetural e/ou de implementação que
geralmente permite o escalonamento de privilégio. Portanto a verificação da manipulação de parâmetros
precisa ser realizada, tendo como objetivo a garantia de que o privilégio associado a um determinado perfil
não pode ser escalonado.

1 http://www.governoeletronico.gov.br/acoes-e-projetos/e-ping-padroes-de-interoperabilidade
2 csrc.nist.gov/publications/fips/fips140-2/fips1402.pdf
3 https://buildsecurityin.us-cert.gov/bsi-rules/home.html
4 É uma fragilidade que torna um sistema suscetível a um ataque ou a um dano.
5 https://buildsecurityin.us-cert.gov/bsi-rules/home.html

Segurança no desenvolvimento de software – COGSI 54


5.4 Documentação de vulnerabilidades e Rastreabilidade
As falhas de segurança encontradas durante os testes devem ser priorizadas levando em
consideração a facilidade de exploração, a exposição e o impacto causado por um ataque. O ideal é que as
vulnerabilidades sejam corrigidas antes que o software entre em produção, embora isto nem sempre é
possível. O importante é que o desenvolvedor receba um relato completo da vulnerabilidade para que ele
possa entender e corrigir o problema de forma efetiva.
O objetivo do relato de vulnerabilidades é mostrar de forma clara o problema e fazer com que alguém
assuma a responsabilidade de tratá-lo. Alguns campos comuns nos relatórios de vulnerabilidades incluem:
identificador da vulnerabilidade: um número único que identifique a vulnerabilidade para facilitar a
comunicação entre as partes interessadas;
título: é o nome dado à vulnerabilidade (por exemplo: upload de arquivo malicioso);
descrição: consiste em um resumo do problema;
detalhes passo a passo: é uma forma de mostrar a reprodução da vulnerabilidade. É importante descrever
como a vulnerabilidade funciona para que o desenvolvedor entenda a lógica do problema. Uma abordagem é
a descrição passo a passo da exploração ou então por meio de telas (screenshots);
responsável pela análise: o responsável pela análise pode sanar eventuais dúvidas sobre a vulnerabilidade;
responsável pela correção: o responsável pela correção pode informar o estado da correção (por exemplo:
resolvida, em andamento, etc);
data do relato: é importante, para fins de registro, colocar a data em que o relato foi descoberto e divulgado;
severidade: a severidade do problema é importante para embasar decisões de priorização das correções.
Durante o relato de vulnerabilidades é importante que as informações sensíveis sejam mascaradas.
Por exemplo, em uma vulnerabilidade de injeção de código em que é possível extrair a tabela de senhas do
banco de dados é necessário ocultá-las durante o detalhe passo a passo da vulnerabilidade. Outro exemplo é
uma tela de erro que mostra informações confidenciais, onde as informações devem ser suprimidas no relato
da vulnerabilidade.

Segurança no desenvolvimento de software – COGSI 55