• Nenhum resultado encontrado

UNIVERSIDADE DO ESTADO DE SANTA CATARINA CENTRO DE CIÊNCIAS TECNOLÓGICAS - CCT TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS

N/A
N/A
Protected

Academic year: 2021

Share "UNIVERSIDADE DO ESTADO DE SANTA CATARINA CENTRO DE CIÊNCIAS TECNOLÓGICAS - CCT TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS"

Copied!
32
0
0

Texto

(1)

UNIVERSIDADE DO ESTADO DE SANTA CATARINA CENTRO DE CIÊNCIAS TECNOLÓGICAS - CCT

TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS

GILLIAN STUART THAYZE NAIZER

PROGRAMAÇÃO SEGURA EM JAVA

JOINVILLE, SC 2013

(2)

LISTA DE CÓDIGOS

Código 3.1.1.1 – Código vulnerável de um buffer overflow, 22 Código 3.1.1.2 – Código seguro de um buffer overflow, 22

Código 3.2.1.1 – Código vulnerável de cross-site request forgery, 24 Código 3.2.1.2 – Código de tratamento do cross-site request forgery, 25 Código 3.2.1.3 – Código validação de cross-site request forgery, 25 Código 3.3.1.1 – Código sem tratamento de command injection, 26 Código 3.3.1.2 – Código executando command injection, 27

(3)

LISTA DE FIGURAS

Figura 2.1 – Como ocorre o Buffer Overflow ... 16 Figura 2.2 – Como ocorre o Command Injection ... 19

(4)

SUMÁRIO

INTRODUÇÃO ... 5

1. CONCEITOS ... 6

1.1 LINGUAGEM DE PROGRAMAÇÃO JAVA ... 6

1.2 HISTÓRICO DAS APLICAÇÕES EM JAVA ... 7

1.3 NORMAS E TÉCNICAS DE SEGURANÇA EM JAVA ... 9

1.4 CONSIDERAÇÕES PARCIAIS ... 11

2. PROBLEMAS DE SEGURANÇA EM JAVA ... 12

2.1 SEGURANÇA EM JAVA ... 12

2.2 PRINCIPAIS PROBLEMAS DE SEGURANÇA EM JAVA ... 15

2.2.1 BUFFER OVERFLOW ... 15

2.2.2 CROSS-SITE REQUEST FORGERY ... 17

2.2.3 COMMAND INJECTION ... 18

2.3 CONSIDERAÇÕES PARCIAIS ... 20

3. ANÁLISE DE CODIFICAÇÃO EM JAVA ... 21

3.1 ANÁLISE BUFFER OVERFLOW ... 21

3.1.1 ANÁLISE DE CÓDIGOS ... 22

3.2 ANÁLISE CROSS-SITE REQUEST FORGERY ... 23

3.2.1 ANÁLISE DE CÓDIGOS ... 23

3.3 ANÁLISE COMMAND INJECTION ... 26

3.3.1 ANÁLISE DE CÓDIGOS ... 26

3.4 CONSIDERAÇÕES PARCIAIS ... 27

(5)

INTRODUÇÃO

Ao desenvolver uma aplicação em Java a maior dificuldade é criar um

software seguro e confiável. Para se evitar isto, é importante conhecer quais os

principais ataques às aplicações web e quais os seus efeitos. Estes ataques podem danificar a aplicação e os dados do cliente ou utiliza-los para obter informações confidenciais do usuário.

Para ter um desenvolvimento confiável em Java é preciso conhecer esta linguagem, e saber qual a sua finalidade. Portanto no capítulo 1 será apresentado o que é o Java, por que esta linguagem foi criada e quais os seus principais produtos. Pensando em segurança existem normas que podem ser seguidas para um desenvolvimento confiável, as duas que serão apresentadas são ITSEC e OWASP, porém o foco será na segunda, pois é a mais utilizada.

Os princípios de segurança em Java e como ele é importante na tomada de decisões no desenvolvimento das aplicações será visto no capítulo 2. Além disto, a OWASP listou os dez principais ataques às aplicações web, porém foram escolhidos os três principais: Buffer Overflow, Cross-Site Request

Forgery e Command Injection, e serão apresentadas suas vulnerabilidades e

como evita-los.

A análise dos códigos será feito no capítulo 3, quais as boas práticas de programação para se evitar os ataques Buffer Overflow, Cross-Site Request

Forgery e Command Injection. Os códigos serão analisados individualmente

com exemplos de códigos vulneráveis e códigos seguros.

As empresas de software para evitar que seus produtos sejam vulneráveis é ideal conhecer estes ataques. Utilizando uma aplicação segura à empresa terá mais confiança e credibilidade no mercado.

(6)

1. CONCEITOS

Para se entender sobre segurança em Java é importante saber o que é o Java e quais as suas plataformas. As primeiras versões do Java tiveram como intenção criar um dispositivo que pudesse ser facilmente programável e que tinham por finalidade o entretenimento doméstico. Contudo, com o passar do tempo e com a democratização da Internet o foco mudou e diferentes plataformas foram criadas. Além disso, para se falar de desenvolvimento confiável em Java é importante conhecer sobre normas e técnicas de programação.

1.1 LINGUAGEM DE PROGRAMAÇÃO JAVA

Lançado em 1995 pela Sun Microsystems, o Java, é uma linguagem e plataforma de computação encontrado em laptops, data centers, consoles de jogo, supercomputadores científicos, telefones celulares e até na Internet (JAVA, 2013). O Java não é apenas uma linguagem, mas sim uma plataforma de desenvolvimento, e com ela é possível desenvolver aplicações para diversos dispositivos diferentes como, por exemplo, aplicativos para celular. (DEVMEDIA 1, 2013).

O Java possui várias plataformas, cada uma com sua finalidade. Uma breve relação das plataformas (ORACLE, 2013):

 JRE (Java Runtime environment): Necessário para a execução de mini aplicativos e aplicativos que utilizam linguagem Java.

 JSE (Java Standard Edition): Necessário para a criação de aplicativos em desktop e computadores.

 JME (Java Micro Edition): Plataforma utilizada para desenvolvimento de aplicativos móveis.

 JEE (Java Enterprise Edition): Muito utilizado em empresas e aplicativos Web, pois suporta uma grande quantidade de usuários simultâneos.

(7)

 JFX: Auxilia o desenvolvimento, pois permite que o desenvolvedor reutilize bibliotecas Java em suas aplicações.

 Java Card: Permite a criação e execução com segurança de cartões inteligentes.

 JTV: Está presente na plataforma JME. Permite o desenvolvimento de aplicativos Java executados em dispositivos de TV e set-top box (conversor).

Observar-se que o Java é uma das principais linguagens para desenvolvimento de software, devido a sua quantidade de plataformas está presente na maior parte dos dispositivos, como computadores, celulares e até em dispositivos de TV. Para se entender melhor sobre o Java e suas plataformas é bom conhecer a sua história e o que foi feito para se tornar uma linguagem tão conhecida.

1.2 HISTÓRICO DAS APLICAÇÕES EM JAVA

Em 1991 foi criado dentro da Sun Microsystems um grupo chamado „‟Green Team‟‟ (Time Verde), que tinha como objetivo interligar dispositivos domésticos com computadores, auxiliando no entretenimento doméstico, porém, as linguagens existentes não eram suficientes. (ORACLE TIMELINE, 2011). O Green Team foi iniciado por Patrick Naughton, Mike Sheridan, e James Gosling em 01 de fevereiro de 1991, com o objetivo de inventar uma nova tecnologia que poderia levar à convergência de dispositivos de consumo controlados digitalmente e computadores. (EASY PROGRAMING, 2013)

O primeiro dispositivo em Java (até então conhecido como OAK – em português Carvalho) o Star7 foi criado em 1992, por James Gosling, era uma espécie de controle remoto para eletrodoméstico. (ORACLE TIMELINE, 2011). James Gosling chamou o Java primeiramente de OAK, por causa de uma árvore de carvalho crescendo fora da janela do seu escritório, porém teve que alterar, pois este nome não estava disponível. (HELIUM, 2008).

Utilizando a linguagem de programação OAK em 1994 foi criado o WebRunner (renomeado mais tarde para HotJava), o primeiro navegador que suporta objeto em movimento e conteúdo executável dinâmico. (ORACLE

(8)

TIMELINE, 2011). O desenvolvimento do navegador originalmente começou em 1994 sob o nome "WebRunner", e em 1996 foi o primeiro navegador capaz de suportar Applets Java. (COMPUTER HOPE, 2013)

Somente em 1995, quando o OAK foi então renomeado para Java, que o mundo começa a conhecer esta nova linguagem de programação. Em 1996 iniciou-se a JavaOne, uma conferência anual para se discutir a tecnologia Java. A partir deste ano a linguagem Java começou a ser utilizada mundialmente e com o passar dos anos novas plataformas foram sendo anunciadas. (ORACLE TIMELINE, 2011). E foi neste ano que foi lançado o Java Development Kit (JDK ou Java 1.0). (DEVMEDIA 2, 2013).

Em 1998 foi anunciado o Java Ring, um anel que continha um microprocessador que funcionava como dispositivo de segurança semelhante a um cartão inteligente. (ORACLE TIMELINE, 2011). Este anel foi produzido pela Dallas Semiconductor Corp e tinha um revestimento de aço inoxidável. (JAVA WORLD 1, 2013)

A máquina virtual HotSpot foi lançada em 1999, neste ano também é anunciado o JavaServer Pages, que simplifica a criação de conteúdo Web Dinâmico. Neste ano também surgem às plataformas JEE e JME. (ORACLE TIMELINE, 2011). Com o passar dos anos novas plataformas foram apresentadas e liberadas, e o Java foi se espalhando pelo mundo. Até que em 2009 a Oracle anuncia a aquisição da Sun. (INFOABRIL, 2009).

A ideia inicial da Sun era criar um grupo focado no desenvolvimento de dispositivos de entretenimento doméstico, mas acabou criando uma nova linguagem de programação. A cada tecnologia que surgia uma nova plataforma era criada pelo Java, tornando assim uma marca de valor, tanto que em 2009 a Oracle comprou a Sun por uma quantia milionária.

Para que se crie um software confiável é importante conhecer sobre normas de segurança, as duas mais conhecidas são a ITSEC (The Information Technology Security Evaluation Criteria, ou Tecnologia da Informação de critérios para avaliação da segurança) e OWASP (The Open Web Application Security Project, ou Projeto Aberto de Segurança de Aplicações Web).

(9)

1.3 NORMAS E TÉCNICAS DE SEGURANÇA EM JAVA

Colocado de forma simplificada, as normas e técnicas são uma forma acordada, repetível de se construir algo, elas tornam a criação de software mais fácil e aumentam a segurança e a efetividade do produto. Uma norma é um documento que contém uma especificação técnica e critérios precisos desenvolvidos para serem utilizados como padrão. (BSI, 2013).

Em 1991 uma comissão Européia formada por três países (Alemanha, França e Inglaterra), publicou uma norma para certificação de segurança denominada ITSEC (The Information Technology Security Evaluation Criteria), tornando-se depois de fato um padrão europeu voltado tanto para avaliação de sistema, como de produtos. Sua versão atual é a 1.2, publicada em 1991. (ABSOLUTA, 1999). Seu objetivo é demonstrar a conformidade de um produto ou sistema contra a sua meta de segurança. Primeiramente, definem-se vários Securitys Target (alvos de segurança) e após esse levantamento é realizado um teste de eficácia para cada alvo. Se necessário for, correções serão aplicadas para atingir os resultados definidos. (RYCOMBE, 2011).

A ITSEC (The Open Web Application Security Project) foi criada na Europa e é utilizada em vários países, porém é uma norma antiga. Outra norma que surgiu foi a OWASP (The Open Web Application Security Project), uma norma criada para auxiliar no desenvolvimento de um software seguro.

A OWASP (The Open Web Application Security Project) é uma norma criada por uma comunidade dedicada exclusivamente as empresas para adquirir, operar, conceber, desenvolver e manter aplicações com alto nível de confiabilidade e segurança. Todas as ferramentas e informações sobre a norma são gratuitas e abertas a qualquer indivíduo interessado em melhorar um produto de software. Esta norma foi estabelecida em 2001. (OWASP, 2010).

Segundo levantamento feito pela OWASP em 2010, os dez principais riscos para a segurança de uma aplicação web são:

(10)

Injection: O ataque é baseado em texto que exploram a sintaxe do intérprete alvejado, assim a aplicação executa comandos não desejáveis.

Cross-Site Scripting (XSS): O atacante envia os scripts de ataque baseados em texto que exploram o intérprete no navegador, que executa sem saber que se trata de um script não confiável.

Broken Authentication and Session Management: Usa vazamentos ou falhas nas funções de gerenciamento de autenticação ou sessão, podendo sequestrar uma sessão do usuário e assumir sua identidade.

Insecure Direct Object References: Um usuário do sistema autorizado, muda o valor do parâmetro que se refere diretamente a um objeto do sistema para outro objeto, podendo assim acessar dados que não está autorizado.

Cross-Site Request Forgery (CSRF): O usuário que está autenticado executa ações indesejadas, podendo comprometer os seus dados.

 Security Misconfiguration: Para obter acesso não autorizado o atacante acessa contas padrão, páginas não utilizadas, falhas não corrigidas, arquivos desprotegidos e diretórios.

 Insecure Cryptographic Storage: Armazenamento inseguro da criptografia devido ao seu uso inadequados ou mal projetado.

 Failure to Restrict URL Access: O atacante utilizada as falhas de restrição de acesso à URL, para acessar páginas sem autorização.

 Insufficient Transport Layer Protection: É a proteção insuficiente da camada de transporte, podendo expor dados de usuários individuais e levar ao roubo de conta.

 Unvalidated Redirects and Forwards: O atacante engana o usuário fazendo-o clicar em um link que redireciona e encaminha para url inválido que pode tentar instalar malware ou descobrir informações confidenciais da vítima.

Para se construir uma aplicação segura em Java, torna-se necessário o conhecimento das normas de segurança descritas. Torna-se improvável

(11)

certificar se um produto de software é seguro sem que ele atenda e respeite os critérios definidos em uma norma. Devem-se aplicar os conceitos e técnicas apresentado nas normas e validar se a aplicação atende aos requisitos de segurança definidos para garantir a confiabilidade da aplicação.

1.4 CONSIDERAÇÕES PARCIAIS

A OWASP levantou os dez principais riscos para a segurança de uma aplicação web, porém serão abordados apenas três destes, que são o

Cross-Site Request Forgery e Command Injection e Buffer Overflow. Serão

(12)

2. PROBLEMAS DE SEGURANÇA EM JAVA

Neste capítulo é explicado com mais detalhes o que é segurança em Java, a importância de utiliza-la e quais são os seus principais desafios no desenvolvimento. São apresentadas as vulnerabilidades das aplicações web

buffer overflow, cross-site request forgery e command injection, estes são

considerados os três principais ataques, sendo assim, serão informados como evitá-los.

2.1 SEGURANÇA EM JAVA

Princípios de segurança de aplicativos são coleções de propriedades desejáveis das aplicações de software, comportamentos, modelos e práticas de implementação que tentam reduzir a probabilidade de realização de ameaça e os impactos que essas ameaças têm sobre os aplicativos. Princípios de segurança são primitivamente independentes de linguagem e arquitetura, sendo assim, pode-se aproveitar vários modelos e práticas de programação para projetar e construir aplicações seguras. (OWASP, 2013)

Os princípios de segurança são importantes porque auxiliam a tomar decisões de segurança em situações novas com as mesmas ideias básicas. Ao considerar cada um desses princípios, pode-se derivar os requisitos de segurança, fazer arquitetura e implementação de decisões, e identificar possíveis deficiências nos sistemas. (OWASP, 2013)

Utilizando princípios de segurança tem-se um modelo de como desenvolver uma aplicação segura. Aplicando este modelo o desenvolvedor tem facilidade em encontrar os problemas de segurança da aplicação.

A vulnerabilidade é um problema ou uma fraqueza na aplicação, que pode ser uma falha de projeto ou um bug de implementação, que permite a um atacante para causar danos às partes de um aplicativo. As partes interessadas incluem o dono do aplicativo, os usuários de aplicativos e outras entidades que dependem da aplicação. (OWASP, 2013)

Desde que o Java começou a ser compilado, e foi desenvolvido para ser transmitido em formato binário através da rede, a programação segura

(13)

tornou-se importante para uma empresa de software. Nenhum usuário quer executar uma parte de um código que exista a possibilidade, na execução, acontecer algo como (GTA UFRJ, 2013):

Danificar hardware, software, ou informação na máquina do usuário;

 Passar informações não autorizadas para qualquer pessoa; e

 Tornar a máquina do usuário inutilizável através de esgotamento de recursos.

Quando tornar-se necessário criar códigos fonte em Java deve-se sempre levar em consideração os três itens citados. Assim, garante-se o mínimo de segurança possível para os dados da aplicação que está executando no ambiente do cliente, e também inibe o usuário de possíveis ameaças decorrentes de um código mal feito.

Os usuários que carregam arquivos do Java de servidores remotos, lugares pouco seguros, precisam se certificar que o código Java carregado em sua máquina não pode danificar ou inserir códigos maliciosos no seu ambiente. (GTA UFRJ, 2013). Diante desse ambiente será avaliado o contexto de segurança em Java no tocante a três vulnerabilidades (OWASP, 2013):

Buffer Overflow: A condição de estouro de buffer acontece quando um programa tenta colocar mais dados em um buffer do que ele pode conter;

Cross-Site Request Forgery: Um ataque CSRF inclui um código registrado no navegador da vítima para enviar um pedido HTTP forjado, incluindo o cookie de sessão da vítima e qualquer outra informação de autenticação; e

Command Injection: Falhas na injeção, tais como SQL, ocorrem quando dados não confiáveis são enviados para um intérprete, como parte de um comando ou consulta.

Foram escolhidos os três ataques listados devido à importância definida pela norma OWASP. Esses três ataques constam entre os cinco primeiros itens da lista, que contém dez itens, sendo os outros ataques (OWASP, 2013):

(14)

Broken Authentication and Session Management: Funções de aplicação relacionadas com autenticação e gerenciamento de sessão, muitas vezes não são implementadas corretamente, permitindo que os atacantes roubem senhas, chaves, fichas de sessão e assim o atacante assume a identidade do usuário no sistema em que ele está usando;

Insecure Direct Object References: A referência de objeto direta ocorre quando um programador expõe uma referência de um objeto de implementação interna, como um arquivo, diretório ou chave de banco de dados. O atacando pode acessar esse objeto para roubar dados da aplicação;

Security Misconfiguration: Boa prática de segurança é sempre manter todos os softwares utilizados pela aplicação atualizados, garantindo que nenhum atacante irá invadir, devido a uma falha que não está corrigida, pois o software não está atualizado;

Insecure Cryptographic Storage: Manter todas as informações que são de acesso pessoal como CFP, RG, chave de segurança e outros seguras, para que o atacante não roube essas informações e realize ataques como, por exemplo, clone um cartão de crédito;

Failure to Restrict URL Access: As aplicações necessitam fazer controle de acesso de todas as URLs para que atacantes não tenham acesso a conteúdo oculto permitido apenas a administradores do sistema, por exemplo;

Insufficient Transport Layer Protection: As aplicações devem autenticar, criptografar e proteger os dados quando os mesmo estão sendo transmitidos na rede. Muitas empresas pecam neste aspecto utilizando certificados já expirados; e

Unvalidated Redirects and Forwards: As aplicações devem validar as páginas de destino quando redirecionam um usuário para que o atacante não redirecione o usuário para o destino incorreto e tenha acesso a informações pessoais do usuário.

(15)

Muitos ataques podem ocorrer para danificar uma aplicação Java, portanto, as empresas de software devem atentar-se para a segurança do seu produto. Além disso, certos ataques podem comprometer dados exclusivos da empresa.

Os três principais ataques são buffer overflow, cross-site request forgery e

command injection, é importante saber como eles funcionam e qual a intenção

do atacante. Estes tipos de vulnerabilidades podem ser evitados com o desenvolvimento de um software seguro.

2.2 PRINCIPAIS PROBLEMAS DE SEGURANÇA EM JAVA

Nesta seção são explicadas as três vulnerabilidades definidas no plano do projeto, sendo descrito cada tipo de ataque. Além disso, como pode ser evitado, como se encaixa no atual ambiente web e quais as condições para que o ataque ocorra.

2.2.1 BUFFER OVERFLOW

Buffer overflow ocorre quando um programa tenta colocar mais dados em

um buffer do que ele pode conter, ou quando um programa tenta colocar os dados em uma área de memória após o buffer, conhecido também como estouro de pilha. Neste caso, um buffer é uma seção sequencial de memória alocada para conter qualquer coisa, desde uma cadeia de caracteres até um

array de inteiros. (OWASP, 2013).

De um modo geral, buffer overflow ocorre sempre que o programa grava mais informações no buffer do que o espaço que atribuiu na memória, conforme figura 2.1. Isso permite que um atacante possa substituir dados que controlam o caminho de execução do programa e roubar o controle do programa para executar código do atacante em vez do código de processo. (WINDOWSECURITY,2013).

(16)

Figura 2.1 – Como ocorre o Buffer Overflow

Fonte: UNDER-LINUX

A figura 2.1 é um exemplo de buffer overflow, (a) representa o programa em execução, já em (b) aparece o espaço do buffer e em (c) aparece o buffer

overflow. O usuário acredita ser um arquivo comum, porém o buffer overflow

acaba executando o código do invasor.( H-ONLINE, 2012)

Sabe-se que muitos desenvolvedores de software já ouviram falar sobre esses ataques, mas poucos realmente entendem a mecânica dos mesmos. Outros têm uma vaga ou nenhuma ideia do que um ataque de estouro de buffer realmente é. Há também aqueles que consideram que este problema é extremamente complicado e que apenas os especialistas em

software podem resolvê-lo. No entanto, isso não é nada, exceto um problema

de vulnerabilidade provocada por programadores descuidados. (WINDOWSECURITY,2013).

Atualmente é uma técnica comum aos desenvolvedores de software dar mais atenção à eficiência de programação e desempenho da aplicação do que preocupar-se com os aspectos de segurança. Logo, as empresas que se esquecem de alertar seus desenvolvedores dos riscos de uma programação voltada apenas ao desempenho, geram aplicações com grandes vulnerabilidades. (WINDOWSECURITY,2013).

O buffer overflow ocorre em programas em que não são feitas tratativas corretas dos dados. Portanto, o desenvolvedor deve estar atento para que o seu software além de desempenho tenha também segurança.

(17)

A solução mais simples e eficaz para o problema de estouro de buffer é construir códigos de software seguros. No mercado existem algumas soluções comerciais ou livres disponíveis, que efetivamente pode evitar a maioria dos ataques de buffer overflow. As duas práticas conhecidas são (WINDOWSECURITY,2013):

 Reimplementar códigos de não seguros, tornando-os seguros contra ataques de buffer overflow.

 Bibliotecas comerciais que identificam qualquer tentativa de estouro de pilhas emitindo um alerta ao administrador do sistema. Por fim, nas próximas seções será visto exemplos práticos de como garantir que a aplicação entenda quando está sendo atacada e consiga inibir esse tipo de vulnerabilidade do sistema. A elaboração de um código seguro pode evitar que os dados dos usuários sejam comprometidos.

2.2.2 CROSS-SITE REQUEST FORGERY

CSRF é um ataque que obriga o usuário final a executar ações maliciosas em uma aplicação web em que está logado. Com um pouco de ajuda das mídias sociais (como o envio de um hyperlink via e-mail / chat / facebook / outros), um atacante pode forçar os usuários de uma aplicação web a executar ações que irão comprometer os dados do usuário final. Se o usuário final tiver permissões de uma conta de administrador, isso pode comprometer a aplicação web inteira (OWASP, 2013).

A falsificação de solicitação entre sites envolve forçar uma vítima (usuário final) a enviar uma solicitação HTTP para um destino alvo, sem seu conhecimento ou aprovação. Muitos sites não levam em consideração essa vulnerabilidade e consecutivamente os desenvolvedores desses sites também não se preocupem em garantir que a aplicação esteja segura neste aspecto. (DJANGO PROJECT, 2013).

Para minimizar esse tipo de ataque o desenvolvedor deve fazer validações em todo o processo de requisição de páginas HTTP do site. A primeira validação deve ocorrer no que se chama de client-side ou lado do cliente onde geralmente executa código fonte que roda no navegador do

(18)

cliente. A segunda validação deve ocorrer no que se chama de client-server ou lado do servidor no qual executa código de servidor como o Java por exemplo. Pequenas validações podem garantir que uma aplicação fique protegida das maiorias das investidas de ataques CSRF. (DJANGO PROJECT, 2013).

O método mais comum para evitar a falsificação CSRF é acrescentar símbolos para cada pedido e associá-los com a sessão do usuário. Ao incluir um símbolo com cada solicitação, o desenvolvedor pode assegurar que o pedido é válido e não proveniente de outra fonte que não seja o usuário. (VERACODE, 2013).

Por fim, no próximo capítulo serão apresentados exemplos práticos de como a aplicação pode identificar que está sofrendo um ataque de CSRF. Seguindo alguns métodos é possível anular ou inibir o ataque, e assim, evitar que o seu usuário final seja prejudicado.

2.2.3 COMMAND INJECTION

Originalmente conhecido como injeção de comandos shell, o processo foi descoberto acidentalmente em 1997 por um programador na Noruega. A primeira injeção de comando resultou na eliminação de páginas web a partir de um site, removida tão facilmente quanto arquivos de um disquete ou disco rígido. (SEARCH SOFTWARE QUALITY, 2013).

O principal objetivo deste ataque é inserir e executar comandos específicos para conseguir autenticar ou até mesmo destruir uma aplicação, conforme figura 2.2. Vale ressaltar que se o usuário possuiu acesso de administrador, o atacando que tiver sucesso na sua injeção de comando terá os mesmos privilégios que o usuário final. No geral esse tipo de ataque poderia ser evitado caso, houvesse um uma validação nos dados de entrada do sistema. Muitos desenvolvedores, por falta de conhecimento, acabam não se importante com esse item de segurança. Raramente se vê nas empresas as equipes responsáveis por teste de sistema fazer esse tipo de verificação. O que torna cada vez mais aplicações vulneráveis a esse tipo de ataque. (OWASP, 2013)

(19)

Figura 2.2 – Como ocorre o Command Injection

Fonte: Veracode

A figura 2.2 mostra como seria uma operação normal e uma operação com command injection. Na primeira o usuário faz uma requisição e a aplicação mostra o resultado, já na segunda, ele insere um comando para obter uma informação adicional.

Um exemplo clássico é quando o atacante insere um comando para excluir todas as tabelas do banco de dados da aplicação. Quando esse tipo de ataque dá certo, efetivamente pode acabar com um sistema caso o mesmo não tenha backup (cópia da base de dados para eventuais problemas) (OWASP, 2013).

Por fim, no próximo capítulo será visto exemplos práticos de como a aplicação pode identificar que está sofrendo um ataque de command injection. Tratando as entradas de maneira correta evitará que o usuário seja afetado por este ataque.

(20)

2.3 CONSIDERAÇÕES PARCIAIS

É imprescindível que as aplicações tenham segurança, isto evita que o usuário final tenha problemas como perda de desempenho, inconsistência dos dados ou erros que danifiquem a sua aplicação. Seguindo algumas regras e conhecendo as principais formas de ataque o desenvolvedor tem mais facilidade em identificar o que deve ser feito para evitar estes ataques, e assim ter uma disponibilidade seletiva dos dados.

As principais formas de ataques às aplicações web são buffer overflow,

cross-site request forgery e command injection, porém podem ser evitados com

o desenvolvimento correto. No próximo capítulo será feita uma análise dos códigos em Java em consideração a estes três ataques.

(21)

3. ANÁLISE DE CODIFICAÇÃO EM JAVA

Como visto nos capítulos anteriores, a maioria dos problemas relacionados à segurança de uma aplicação Java, pode ser evitado com uma prática de programação segura. Muitos códigos inseguros são a causa de vulnerabilidades de grandes ou pequenas aplicações, sendo muito comum usuários de diversos tipos de sistemas terem, por exemplo, seus dados pessoais roubados para fins ilícitos e o pior é saber que tais ataques poderiam ter sido evitados com pequenos cuidados no momento da construção do

software.

Por isso é de extrema importância saber identificar um código fonte seguro. Não há como certificar se o código é seguro se não se aplica ao mínimo, os conceitos explicitados na norma OWASP. A análise e o teste dos requisitos torna-se de fato, um ato importantíssimo no desenvolvimento dos produtos de software, para assim, se garantir o mínimo de segurança para aplicações que rodam sobre a plataforma do Java.

Neste capítulo serão explicitados alguns exemplos de códigos fonte, onde se irá analisar e identificar à boa e a má prática de programação, para aquele pequeno trecho de programação, esclarecendo e explicitando assim alguns dos exemplos de ataques citados no presente trabalho.

3.1 ANÁLISE BUFFER OVERFLOW

Quando é alocado memória além do limite de uma aplicação, isso pode acarretar em uma execução de um código malicioso, travar o software ou até mesmo corromper os dados. Sobretudo, o Java foi projetado para evitar o estou de buffer, ou seja, caso ele identifique um acesso a uma parte da memória que não está alocada, ele dispara uma exceção que nada mais é uma condição anormal na execução do código. Sobretudo, os programadores ainda devem tratar e prevenir esse tipo de erro nos sistema para assim, tornar as aplicações mais seguras. (TOWSON, 2013).

(22)

3.1.1 ANÁLISE DE CÓDIGOS

Segue um exemplo de um código fonte que irá identificar uma tentativa de utilizar uma parte da memória que não foi alocada pela aplicação:

Código 3.1.1.1 – Código vulnerável de um buffer overflow public class Overflow

{

public static void main(String[] args)

{

int importantData =1;

int[] buffer = new int[10];

for (int i =0; i < 15; i++)

buffer[i] = 7;

System.out.println("Após o estouro de buffer");

System.out.println("Dados importantes = "+importantData);

}

}

Fonte: TOWSON

No código 3.1.1.1, é possível identificar a tentativa de buffer overflow. Foi instanciado um vetor de tamanho fixo, com 10 posições, sobretudo, quando a aplicação vai preencher o vetor de inteiros com os dados, nota-se que o loop está programado para ser executado quinze vezes. Quando o programa for inserir o número 7 na posição 10 do vetor, o Java irá identificar uma tentativa de acesso a uma memória não alocado e irá disparar uma exceção a aplicação.

Para evitar esse tipo de ataque deve-se verificar sempre, se o espaço de memória que se está querendo inserir uma informação está alocado e está disponível. Outra prática interessante é sempre verificar se tem memória suficiente para os dados que se deseja copiar.

Segue o mesmo exemplo do código anterior, sobretudo, feito de forma segura:

Código 3.1.1.2 – Código seguro de um buffer overflow public class Overflow

{

public static void main(String[] args)

{

int importantData =1;

int[] buffer = new int[10];

for (int i =0; i < buffer.length; i++)

(23)

System.out.println("Após o estouro de buffer");

System.out.println("Dados importantes = "+importantData);

}

}

Fonte: TOWSON

No código 3.1.1.2, pode-se notar que o mesmo vetor de dados instanciado no outro exemplo também é instanciado nesse exemplo, sobretudo, ao programar o loop, ao invés de se colocar um tamanho fixo, a aplicação o executa exatamente a quantidade de vezes necessárias, ou seja, o tamanho máximo do vetor que pode ser encontrado no atributo length do vetor. Nota-se que uma pequena mudança na forma de construir o código pode tornar a aplicação livre de erros e mais segura.

3.2 ANÁLISE CROSS-SITE REQUEST FORGERY

Os navegadores web (Internet Explorer, Fifefox, Chrome) permitem que as aplicações web solicitem requisições POST e GET entre vários sites. O ataque cross-site request forgery ocorre basicamente quando um usuário acessa uma página maliciosa, que faz com que o navegador envie solicitações para uma aplicação que o usuário não sabe ou não tinha a intenção. Esse tipo de ataque pode ser feito com as tags HTML (<image>, <frame>, entre outros). Assim sendo, o site malicioso pode executar ações sem a devida autorização do usuário. (VERACODE, 2013)

Basicamente todas as aplicações web são vulneráveis a ataque de CSRF, e os desenvolvedores precisam proteger as suas aplicações para não ser um alvo potencial de ataques.

3.2.1 ANÁLISE DE CÓDIGOS

Segue um exemplo de um código fonte que irá identificar uma tentativa de utilizar uma parte da memória que não foi alocada pela aplicação:

(24)

Código 3.2.1.1 – Código vulnerável de cross-site request forgery

Pode-se verificar nesse código fonte, que o atacante, dono da página Web, colocou um link com o nome “Veja minhas fotos”, sobretudo, quando o usuário clicar no link será redirecionado para página de um banco, na qual fará um depósito no valor de R$ 100.000,00. Sabe-se que se trata de um caso hipotético, sobretudo, é exatamente assim que acontecem os ataques aos sites. Na URL são passados alguns parâmetros, na qual faz a aplicação executar uma ação que não poderia.

Para conseguir corrigir esse tipo de erro, torna-se necessário criar uma chave (Token) para cada sessão iniciada pelo usuário. Toda vez que o usuário acessa uma página Web dentro da mesma aplicação, o programa irá validar o

token do usuário, caso as informações não batam, ele nega o acesso a página.

O token deve ser colocado em um campo hidden, que significa escondido. (JAVA SAPAO, 2013). Segue exemplo:

(25)

Código 3.2.1.2 – Código de tratamento do cross-site request forgery

Fonte: JAVA SAPAO

Ao acessar a página, a aplicação deve validar o token e se necessário for bloquear o acesso ao mesmo, como segue no código a seguir: (JAVA SAPAO, 2013).

Código 3.2.1.3 – Código validação de cross-site request forgery

(26)

Deve-se atentar, que sempre que usado o token deve ser descartado e a aplicação deve gerar um novo token. (JAVA SAPAO, 2013).

3.3 ANÁLISE COMMAND INJECTION

Os programas externos são chamados para executar uma função requerida pelo sistema global. Esta prática é uma forma de reutilização e pode até mesmo ser considerada uma forma grosseira de engenharia de software baseada em componentes. O ataque Command Injection ocorre quando um aplicativo não consegue limpar a entrada não confiável e usa-o na execução de programas externos. (SECURECODING, 2013).

A vulnerabilidade do Command Injection está na entrada dos comandos. Se o código for tratado de maneira correta evita que os dados do usuário sejam disponibilizados, excluídos ou alterados.

3.3.1 ANÁLISE DE CÓDIGOS

Segue um exemplo de um código fonte que poderá danificar os dados do cliente, caso seja executada uma entrada não confiável:

Código 3.3.1.1 – Código sem tratamento de command injection

String sql = "select * from tabela_usuarios where login='" + campo_login +"' and senha='" + campo_senha + "'";

Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(sql); if (rs.next())

System.out.println("Usuário Logado com sucesso."); else

System.out.println("Usuário ou Senha não conferem."); Fonte: DEVMEDIA 3

Deve se tomar cuidado ao usar consultas SQL para validar os campos, pois isto possibilita que o atacante execute comandos que afetem o banco de dados. Por exemplo, se o usuário passasse como parâmetro de login o valor ' OR 1=1 -- isto resulta no código (DEVMEDIA, 2013):

(27)

Código 3.3.1.2 – Código executando command injection

String sql = "select * from tabela_usuarios where login='' OR 1=1 --' and senha='" + campo_senha + "'";

Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(sql); if (rs.next())

System.out.println("Usuário Logado com sucesso."); else

System.out.println("Usuário ou Senha não conferem."); Fonte: Adaptado de DEVMEDIA 3

Desta maneira é possível acessar a aplicação sem saber o login, pois será verificado se o login é igual a vazio ou se 1=1, retornando verdade, o resto das validações serão ignoradas porque estão comentadas. (DEVMEDIA, 2013). O código a seguir é um exemplo de como este problema pode ser tratado:

Código 3.3.1.3 – Código com tratamento de command injection

String sql = "SELECT * FROM tabela_usuarios WHERE login = ? AND senha = ?";

PreparedStatement prepStmt = con.prepareStatement(sql); prepStmt.setString(1,login);

prepStmt.setString(2,senha);

ResultSet rs = prepStmt.executeQuery(); Fonte: DEVMEDIA 3

Neste exemplo é criado um PreparedStatement. Por vezes é mais conveniente usá-lo para enviar instruções SQL à base de dados, pois contém não apenas uma instrução SQL, mas uma instrução SQL que foi pré-compilada. (DOCS ORACLE 2, 2013).

Sendo assim, pode-se verificar que utilizando comandos definidos peplo Java é possível tratar as entradas corretamente. Desta forma evita-se inconsistências nos dados dos clientes.

3.4 CONSIDERAÇÕES PARCIAIS

Nota-se que o uso correto das linguagens de programação, combinado com diretrizes de seguranças, podem fazer toda a diferença no momento da construção de um software. Pequenos detalhes são o que separam um

(28)

disponibilizadas na rede mundial da internet, que podem ser de grande valia, como no caso da norma técnica OWASP, que disponibiliza uma série de informações de como fazer corretamente e como validar se o software realmente está seguro.

(29)

CONCLUSÃO

Neste trabalho foi abordado o que é a Programação Segura em Java. Conclui-se que são imprescindíveis que se sigam algumas regras para que a aplicação seja confiável.

Os objetivos propostos foram cumpridos, foram analisadas as dificuldades no desenvolvimento de uma aplicação segura em Java no contexto de três ataques (Buffer Overflow, Cross-Site Request Forgery, Command Injection). Além disso, foi apresentado o que é a aplicação Java, os seus principais produtos, como foi a sua evolução, e quais os principais ataques às aplicações web.

Este trabalho foi importante para o conhecimento das vulnerabilidades que podem ter em uma aplicação e como isto pode afetar os usuários. Foi possível conhecer e aperfeiçoar o desenvolvimento confiável das aplicações.

(30)

REFERÊNCIAS BIBLIOGRÁFICAS

ABSOLUTA. http://www.absoluta.org/seguranca/seg_padroes.htm, Acesso: 21/04/2013

BSI. http://www.bsibrasil.com.br/publicacoes/sobre_normas/normas/, Acesso: 21/04/2013

BUILD SECURITY IN, Disponível em https://buildsecurityin.us-cert.gov/bsi/home.html, Acesso em 20/03/2013

CGI SECURITY, Disponível em http://www.cgisecurity.com/java-security.html, Acesso em 13/03/2013

COMPUTER HOPE. Disponível em

http://www.computerhope.com/jargon/h/hotjava.htm, Acesso: 21/04/2013 DEVMEDIA 1, Disponível em http://www.devmedia.com.br/por-que-java/20384, Acesso em: 13/03/2013

DEVMEDIA 2, Disponível em http://www.devmedia.com.br/entendendo-e-conhecendo-as-versoes-do-java/25210, Acesso: 21/04/2013

DEVMEDIA 3, Disponível em http://www.devmedia.com.br/sql-injection-em-ambientes-web/9733, Acesso: 18/06/2013

DJANGO PROJECT, Disponível em

https://docs.djangoproject.com/en/dev/ref/contrib/csrf/, Acesso em 19/05/2013 DOCS ORACLE. Disponível em:

http://docs.oracle.com/javase/6/docs/api/, Acesso em 13/03/2013 DOCS ORACLE 2. Disponível em:

http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html, Acesso em 18/16/2013

EASY PROGRAMING. http://easyprograming.com/index.php/java/3-the-evolution-of-java-programing-language, Acesso: 20/04/2013.

GTA-UFRJ, Disponível em http://www.gta.ufrj.br/~flavio/java/security.html, Acesso em 07/05/2013.

HELIUM. http://www.helium.com/items/1101180-the-history-of-java, Acesso: 20/04/2013

(31)

H-ONLINE, Disponível em

http://www.h- online.com/security/news/item/Buffer-overflows-in-KOffice-and-Calligra-reported-1662884.html, Acesso em 30/05/2013

INFO ABRIL. http://info.abril.com.br/noticias/negocios/oracle-compra-sun-por-us-7-4-bilhoes-20042009-5.shl, Acesso: 17/04/2013

JAVA, Disponível em: http://www.java.com/pt_BR, Acesso em: 13/03/2013.

JAVA SAPAO, Disponível em: http://java.sapao.net/Home/evitar-ataques-de-csrf, Acesso em: 18/06/2013.

JAVA WORLD 1, Disponível em: http://www.javaworld.com/, Acesso em 13/03/2013.

JAVA WORLD 2, http://www.javaworld.com/jw-04-1998/jw-04-javadev.html, Acesso: 21/04/2013

ORACLE TIMELINE. http://oracle.com.edgesuite.net/timeline/java/. Acesso: 17/04/2013

ORACLE. Disponível em

http://www.oracle.com/us/technologies/java/overview/index.html, Acesso em 13/03/2013

OWASP, Disponível em: https://www.owasp.org, Acesso em 19/03/2013 RYCOMBE, Disponível em http://www.rycombe.com/itsec.htm, Acesso em 13/03/2013

SEARCH SOFTWARE QUALITY, Disponível em

http://searchsoftwarequality.techtarget.com/definition/command-injection, Acesso em 07/05/2013. SECURECODING , Disponível em https://www.securecoding.cert.org/confluence/display/java/IDS07-J.+Do+not+pass+untrusted,+unsanitized+data+to+the+Runtime.exec()+method , Acesso em 18/06/2013.

(32)

TOWSON, Disponível em

http://cis1.towson.edu/~cssecinj/modules/cs0/buffer-overflow-cs0-java/, Acesso em 17/06/2013

UNDER-LINUX, Disponível em https://under-linux.org/content.php?r=5132, Acesso em 03/06/2013

VERACODE, Disponível em http://www.veracode.com/security, Acesso em 03/06/2013

WINDOWSECURITY, Disponível em

http://www.windowsecurity.com/articles-tutorials/windows_os_security/Analysis_of_Buffer_Overflow_Attacks.html, Acesso em 19/05/2013

WINTRAC, Disponível em http://www.wintrac.com/courses/ijsepa.asp, Acesso em 13/03/2013

Referências

Documentos relacionados

Não podemos deixar de dizer que o sujeito pode não se importar com a distância do estabelecimento, dependendo do motivo pelo qual ingressa na academia, como

Para disciplinar o processo de desenvolvimento, a Engenharia de Usabilidade, também conceituada e descrita neste capítulo, descreve os métodos estruturados, a

Para a liga 30%Fe65Nb70%Cu foi possível observar uma distribuição de partículas de Fe65Nb ao longo de toda a matriz de Cu e não foi possível notar o processo difusão entre

Esta pesquisa tem como finalidade analisar como a cultura popular esta sendo trabalhada na formação profissional de Educação Física no Brasil, a partir de uma pesquisa

Dando continuadad a los cambios políticos que ocurrierón en Venezuela a partir de 1999. El Plan de Desarrollo Económico y Social de la Nación 2007-2013 contiene

Como hipótese, assumiremos que o desenvolvimento de um modelo matemático diferente do tradicional poderia, por permitir a criação de personagens com comportamentos adaptáveis a

Para atingir este fim, foram adotados diversos métodos: busca bibliográfica sobre os conceitos envolvidos na relação do desenvolvimento de software com

Quando os dados são analisados categorizando as respostas por tempo de trabalho no SERPRO, é possível observar que os respondentes com menor tempo de trabalho concordam menos que