• Nenhum resultado encontrado

Ricardo Silveira Moreira

N/A
N/A
Protected

Academic year: 2021

Share "Ricardo Silveira Moreira"

Copied!
95
0
0

Texto

(1)

UNIVERSIDADE DE LISBOA FACULDADE DE CIˆENCIAS DEPARTAMENTO DE INFORM ´ATICA

Aplica¸

ao para dete¸

ao de c´

odigo vulner´

avel

atrav´

es de an´

alise est´

atica

Ricardo Silveira Moreira

Mestrado em Seguran¸

ca Inform´

atica

Trabalho de projeto orientado por:

Prof. Doutor Naercio David Pedro Magaia

(2)
(3)

Agradecimentos

O trabalho apresentado nesta tese foi desenvolvido na empresa Escrita Digital. A sua concretiza¸c˜ao n˜ao teria sido poss´ıvel sem o apoio incondicional do seu diretor Tom´e Gil que acreditou no meu projecto e autorizou a utiliza¸c˜ao de recursos desta empresa.

Expresso tamb´em a minha gratid˜ao ao director de desenvolvimento Ant´onio Or-lando, meu orientador na empresa. A sua constante disponibilidade para esclarecer todas as minhas d´uvidas e as valiosas sugest˜oes nos temas relevantes para esta tese foram determinantes ao longo do desenvolvimento desta aplica¸c˜ao.

Ao meu orientador no Departamento de Inform´atica da FCUL, professor Na´ercio Magaia, agrade¸co a sua orienta¸c˜ao na estrutura¸c˜ao deste trabalho, no apontar de vias de desenvolvimento e na escrita da tese que melhoraram muito este manuscrito. Agrade¸co ainda o incentivo para a publica¸c˜ao dos resultados aqui apresentados.

Quero expressar tamb´em um agradecimento aos meus amigos e colegas de mes-trado e trabalho Guilherme Antunes e Inˆes Afonso, que tornaram a realiza¸c˜ao da tese mais f´acil nas alturas mais dif´ıceis.

Um grande obrigado `a minha fam´ılia por me terem ajudado e apoiado incondi-cionalmente durante todo o meu percurso escolar.

Finalmente, um obrigado especial `a minha namorada Margarida Monteiro por me ter dado for¸ca quando precisava e por estar sempre ao meu lado.

(4)
(5)

Resumo

Em empresas de desenvolvimento de software ´e cada vez mais necess´ario incluir valida¸c˜oes de seguran¸ca no fluxo de desenvolvimento. A falta destas pode ter con-sequˆencias danosas a n´ıvel de custos, isto porque a seguran¸ca ´e um requisito que ´e cada vez mais importante para clientes. Com este projecto prop˜oe-se a cria¸c˜ao de uma aplica¸c˜ao de an´alise de c´odigo est´atico e a sua integra¸c˜ao no ciclo de desenvol-vimento na empresa Escrita Digital (ED). Apesar de existirem diversas solu¸c˜oes no mercado para a detec¸c˜ao de vulnerabilidades, nenhuma das existentes actualmente ´e adequada para os problemas que existem na ED. Em primeiro lugar devido aos eleva-dos custos envolvieleva-dos numa solu¸c˜ao deste tipo. Em segundo lugar por n˜ao existirem no mercado muitas aplica¸c˜oes capazes de analisar a linguagem ASP, linguagem que ´e usada para desenvolver alguns dos produtos que a ED comercializa. Para isso, criou-se a aplica¸c˜ao Athena com a capacidade de analisar qualquer linguagem, desde que escritas as regras e l´exico para a mesma. O Athena requer a indica¸c˜ao dos padr˜oes de c´odigo potencialmente vulner´aveis pelo programador, colocando assim sobre ele a responsabilidade de identificar essas vulnerabilidades.

As regras e o l´exico s˜ao descritas recorrendo a ficheiros de configura¸c˜ao de Ex-tensible Markup Language (XML), que v˜ao alimentar o motor, ditando as opera¸c˜oes que este deve fazer. No l´exico est˜ao descritos os v´arios tokens que comp˜oem a lin-guagem a ser analisada. Este ficheiro ´e utililizado pelo motor de an´alise l´exical para extrair os tokens do ficheiro. Nas regras est˜ao as descri¸c˜oes dos v´arios padr˜oes que correspondem a vulnerabilidades e a fun¸c˜oes seguras. Padr˜oes esses que s˜ao cons-truidos a partir dos tokens declarados no ficheiro de l´exico. Este ficheiro de regras vai alimentar o motor de parsing sendo este respons´avel por devolver sequˆencias de tokens que tˆem uma vulnerabilidade e uma localiza¸c˜ao no ficheiro associada. O Athena usa estas duas bibliotecas para analisar ficheiros e devolver as v´arias vulnera-bilidades. Realizaram-se diversos testes tendo como objectivo evidenciar a vantagem da utiliza¸c˜ao da aplica¸c˜ao Athena, quantificar a efic´acia da solu¸c˜ao na detec¸c˜ao de vulnerabilidades e comparar os tempos envolvidos nessa mesma detec¸c˜ao. Os testes revelaram que a aplica¸c˜ao Athena apresenta claras vantagens face a uma an´alise manual ou mesmo recorrendo ao YASCA.

Palavras-chave: an´alise est´atica, an´alise lexical, vulnerabilidades, compiladores

(6)
(7)

Abstract

In software development companies, it is increasingly necessary to include secu-rity validations in the development flow. The lack of these can have very harmful consequences in terms of costs because security is a requirement that is increasingly important for customers. Thus, security is a fundamental aspect to take into ac-count when developing software. However, older companies find it more difficult to change and insert these validations and considerations into their software develop-ment process, as they will always cause a delay in the delivery of new versions. This project aims the creation of a static code analysis application and its integration in the development cycle at Escrita Digital (ED). Although there are several solu-tions on the market for the detection of vulnerabilities, none of the existing ones is currently adequate for the problems that exist in ED. Firstly, due to the high costs involved in such a solution and secondly, because there are not many applications on the market capable of analyzing ASP, a language that is used to develop some of the products that ED commercializes. To solve this problem, the Athena application was developed with the ability to analyze any language, as long as the rules and lexicon for it are written. Athena requires the programmer to indicate potentially vulnerable code patterns, thus placing on him the responsibility to identify those vulnerabilities.

The rules and the lexicon are described using XML configuration files, which will feed the engine, dictating the operations it must do. The lexicon describes the various tokens that make up the language to be analyzed. This file is used by the lexical analysis engine to extract the tokens from the file. In the rules are descriptions of the various standards that correspond to vulnerabilities and secure functions. These patterns are built from the tokens declared in the lexicon file. This rules file will feed the parsing engine, which is responsible for returning code sequences that have a vulnerability and a location in the associated file. Athena uses these two libraries to analyze files and to return the various vulnerabilities that are found by the parsing engine.

In the final part of the thesis, several tests were carried out with the objective of highlighting the advantage of using the Athena application, quantifying the solu-tion’s effectiveness in detecting vulnerabilities and also comparing the times involved in that detection. The comparison was made with manual analysis and with YASCA [15], a free use application. The tests revealed that the Athena application has clear advantages over a manual analysis or even using YASCA.

(8)
(9)
(10)
(11)

Conte´

udo

Lista de Figuras xiii

Lista de Tabelas xv 1 Introdu¸c˜ao 1 1.1 Motiva¸c˜ao . . . 1 1.2 Objectivos do trabalho . . . 2 1.3 Estrutura do documento . . . 2 1.4 Institui¸c˜ao de acolhimento . . . 3 1.5 Contribui¸c˜oes . . . 3

2 Contexto e trabalho relacionado 5 2.1 Vulnerabilidades em aplica¸c˜oes web . . . 6

2.1.1 Injection . . . 6

2.1.2 Cross-Site Scripting . . . 8

2.1.3 Utiliza¸c˜ao de Componentes com Vulnerabilidades Conhecidas . 9 2.1.4 Broken Authentication . . . 9

2.1.5 Sensitive Data Exposure . . . 10

2.1.6 XML Eternal Entities . . . 10

2.1.7 Broken Access Control . . . 10

2.1.8 Security Misconfiguration . . . 10

2.1.9 Insecure Desserialization . . . 10

2.1.10 Insufficient Logging & Monitoring . . . 10

2.1.11 Injection . . . 11

2.1.12 Cross-Site Scripting . . . 13

2.1.13 Utiliza¸c˜ao de Componentes com Vulnerabilidades Conhecidas . 14 2.2 M´etodos de An´alise . . . 14

2.2.1 An´alise Dinˆamica . . . 14

2.2.2 An´alise Est´atica . . . 15

2.2.3 An´alise Manual . . . 15

2.2.4 Discuss˜ao . . . 16

2.3 Ferramentas an´alise est´atica de c´odigo . . . 17

2.3.1 An´alise lexical . . . 18

2.3.2 Parsing . . . 23 ix

(12)

2.4 Redes neuronais . . . 28

2.4.1 Motiva¸c˜ao . . . 28

2.4.2 Vantagens e desvantagens . . . 29

2.5 Ferramentas . . . 29

2.5.1 An´alise lexical . . . 29

2.5.2 Parsing . . . 30

2.5.3 An´alise est´atica . . . 30

2.5.4 Compara¸c˜ao . . . 31

3 Aplica¸c˜ao Athena 33 3.1 Tecnologias utilizadas . . . 33

3.2 Arquitectura . . . 34

3.2.1 Motor de an´alise lexical . . . 35

3.2.2 Motor de parsing . . . 37

3.2.3 Athena . . . 39

3.3 Ficheiros de configura¸c˜ao . . . 39

3.3.1 Schema dos ficheiros de configura¸c˜oes . . . 40

3.3.2 L´exico . . . 41

3.3.3 Regras . . . 45

3.4 Funcionamento . . . 48

3.4.1 Motor de an´alise lexical . . . 48

3.4.2 Motor de parsing . . . 50

3.5 Decis˜oes Tomadas . . . 52

3.6 Integra¸c˜ao na empresa . . . 52

3.7 Problemas encontrados . . . 52

4 Avalia¸c˜ao 55 4.1 Metodologia de avalia¸c˜ao . . . 55

4.1.1 Ferramentas usadas para fazer testes . . . 56

4.1.2 Padr˜oes de vulnerabilidades . . . 56

4.1.3 Ficheiros de regras xml para testes . . . 59

4.1.4 M´etricas de testes . . . 59

4.2 Procedimento de An´alise . . . 60

4.2.1 A aplica¸c˜ao Athena versus a an´alise manual . . . 60

4.2.2 Identifica¸c˜ao de vulnerabilidades . . . 61

4.2.3 Tempo de an´alise e correc¸c˜ao . . . 61

4.3 Resultados de Testes . . . 61

4.4 Discuss˜ao dos resultados . . . 65 x

(13)

5 Conclus˜oes e trabalho futuro 67

5.1 Conclus˜oes . . . 67

5.2 Trabalho futuro . . . 67

5.2.1 Integra¸c˜ao no visual studio . . . 68

5.2.2 Melhorias no motor . . . 68

Gloss´ario 71

Siglas 73

Bibliografia 77

(14)
(15)

Lista de Figuras

2.1 Representa¸c˜ao de alto n´ıvel de um compilador . . . 17

2.2 Representa¸c˜ao de alto n´ıvel de uma ferramenta de an´alise est´atica de c´odigo . . . 18

2.3 Diagrama de estados para reconhecimento de um identificador . . . . 20

2.4 M´aquina de estados que reconhece a express˜ao abc(a|b|c)*a . . . 22

2.5 M´aquina de estados simplificada que reconhece a express˜ao abc(a|b|c)*a 22 2.6 M´aquina de estados que reconhece a express˜ao abc(a|b|c)*a . . . 23

2.7 Rela¸c˜ao entre a an´alise lexical e o parser . . . 24

2.8 Arvore de parsing da express˜ao (1 + 4) ∗ 5 + 3 . . . 27

3.1 Arquitectura do Athena . . . 34

3.2 Motor de an´alise l´exical . . . 36

3.3 Arquitectura do motor de parsing . . . 37

3.4 Exemplo de convers˜ao de tokens . . . 39

3.5 Exemplo de funcionamento do motor de an´alise l´exical . . . 49

3.6 Exemplo de funcionamento de motorParsing . . . 51

3.7 Menu de contexto . . . 52

4.1 Histograma do n´umero de vulnerabilidades encontradas pelo Athena e pelo Yasca (tabela 4.3) . . . 63

4.2 Resultado da an´alise no n´umero de vulnerabilidades em fun¸c˜ao do tempo . . . 64

(16)
(17)

Lista de Tabelas

2.1 Tabela de s´ımbolos . . . 19 2.2 Regras de produ¸c˜ao para opera¸c˜oes aritm´eticas . . . 24 2.3 Tradu¸c˜ao de regras de produ¸c˜ao para regras de semantica . . . 26 2.4 Ferramentas existentes no mercado para an´alise de c´odigo ASP . . . . 31 4.1 Significado dos resultados no contexto de vulnerabilidades . . . 59 4.2 N´umero de vulnerabilidades encontradas pelo Athena face `as manuais. 62 4.3 N´umero de vulnerabilidades encontradas pelo Athena e pelo YASCA. 63 4.4 M´etricas calculadas para as aplica¸c˜oes Athena e YASCA . . . 63 4.5 Tempos de an´alise mais corre¸c˜ao das vulnerabilidades acusadas. . . . 64

(18)
(19)

Cap´ıtulo 1

Introdu¸

ao

1.1

Motiva¸

ao

Temos assistido nos ´ultimos anos a um aumento na preocupa¸c˜ao, investimento de dinheiro e recursos humanos na seguran¸ca inform´atica de aplica¸c˜oes web, isto de-vido ao crescimento no n´umero de ataques inform´aticos a empresas, motivado pela grande quantidade de informa¸c˜ao a que estas aplica¸c˜oes web muitas vezes tem acesso. Apesar desta crescente preocupa¸c˜ao e da evolu¸c˜ao de linguagens de programa¸c˜ao as-sim como frameworks para o desenvolvimento de aplica¸c˜oes web, vulnerabilidades derivadas de m´a programa¸c˜ao continuam a existir.

Estas vulnerabilidades est˜ao bem documentadas e s˜ao bem conhecidas no mundo inform´atico. A organiza¸c˜ao Open Web Application Security Project (OWASP) [28] documenta vulnerabilidades de aplica¸c˜oes web, desenha solu¸c˜oes de suporte `a de-tec¸c˜ao e t´ecnicas para as resolver. Ela publica ainda relat´orios onde re´une vulne-rabilidades cr´ıticas. Nestes relat´orios est˜ao documentadas as dez vulnerabilidades mais cr´ıticas presentes em aplica¸c˜oes web. No relat´orio de 2017 [29], vulnerabilida-des como Structured Query Language (SQL) injection e Cross-site scripting (XSS) continuavam a fazer partes das 10 maiores vulnerabilidades, podendo contudo ser de-tectadas facilmente na fase de desenvolvimento do c´odigo. S˜ao muitas vezes tamb´em aquelas que surgem derivadas do fluxo de desenvolvimento normal duma empresa e que, tal como o relat´orio indica, podem ter impactos muito danosos para a mesma empresa.

Em empresas de desenvolvimento de software, o conhecimento e a forma¸c˜ao passada entre programadores levam ao aparecimento de um padr˜ao de produ¸c˜ao de c´odigo. Isto aliado a um certo desleixe quanto a quest˜oes de seguran¸ca, derivado muitas vezes de alguma pressa em colocar funcionalidades em produ¸c˜ao por falta de tempo, leva a que muitas vulnerabilidades se repitam. A desvantagem disto ´e a grande prolifera¸c˜ao de vulnerabilidades que derivam do mesmo padr˜ao. Isto pode ser contudo uma vantagem, se o padr˜ao for identificado numa fase embrion´aria, sendo poss´ıvel alertar o programador para corrigir esta vulnerabilidade.

Por exemplo, a Escrita Digital, cujo foco ´e o desenvolvimento destes produtos de software na forma de aplica¸c˜oes web, ´e v´ıtima disto. Nesta existe um vazio no

(20)

que diz respeito a cuidados de seguran¸ca, tanto no decorrer do desenvolvimento de funcionalidades como na fase de testes. Tipicamente as aplica¸c˜oes nesta empresa s˜ao desenvolvidas em C#.NET e Activer Server Pages (ASP) (cl´assico). O C#.NET ´e uma linguagem compilada `a semelhan¸ca do JAVA, e o ASP (cl´assico) uma linguagem interpretada `a semelhan¸ca do PHP. Ambas as linguagens, tal como qualquer outra, s˜ao propensas ao surgimento de vulnerabilidades, contudo de maneiras diferentes.

1.2

Objectivos do trabalho

Nesta tese ´e apresentado o processo de desenvolvimento de uma solu¸c˜ao de an´alise de c´odigo est´atico para a detec¸c˜ao de c´odigo C#.NET e ASP (cl´assico) vulner´avel e com possibilidade de ser estendido para outras linguagens. A necessidade do desenho de uma nova solu¸c˜ao prende-se, essencialmente com dois factores: i) o facto de as solu¸c˜oes j´a existentes n˜ao serem adequadas para a empresa, e terem custos muito elevados; ii) Algum facilitismo com vulnerabilidades existentes nas aplica¸c˜oes da empresa Escrita Digital.

A aplica¸c˜ao proposta ´e a de an´alise de c´odigo est´atico e vai ser introduzida numa nova fase para valida¸c˜ao de seguran¸ca. Esta aplica¸c˜ao n˜ao descura a an´alise manual mas complementa-a. O seu prop´osito ´e fornecer um aux´ılio ao programador e alertar contra c´odigo potencialmente vulner´avel.

1.3

Estrutura do documento

A estrutura ´e a seguinte:

• No Cap´ıtulo 2 s˜ao abordados os conceitos te´oricos necess´arios para a realiza¸c˜ao da aplica¸c˜ao de detec¸c˜ao de vulnerabilidades assim como o contexto do traba-lho. S˜ao apresentadas e discutidas as v´arias categorias de aplica¸c˜oes de an´alise de seguran¸ca. S˜ao explicadas as v´arias fases de an´alise de uma ferramenta de c´odigo est´atica, assim como os m´etodos que esta usa para fazer a detec¸c˜ao de vulnerabilidades. Finalmente s˜ao apresentadas ferramentas j´a existentes para an´alise e s˜ao definidas m´etricas para an´alise da aplica¸c˜ao aqui apresentada. • No Cap´ıtulo 3 ´e apresentada a arquitectura do motor de an´alise l´exical e

motor de parsing, os ficheiros de configura¸c˜ao, a forma como os ficheiros de configura¸c˜ao influenciam o comportamento dos motores, decis˜oes que foram tomadas, o processo de integra¸c˜ao na empresa e finalmente os problemas en-contrados durante o desenvolvimento da aplica¸c˜ao. Dado que os ficheiros de configura¸c˜ao s˜ao a parte mais relevante do trabalho, optou-se por explicar primeiro o que comp˜oe os ficheiros de configura¸c˜ao. A motiva¸c˜ao para a sua organiza¸c˜ao e o efeito que tem nos motores. ´E apresentado a arquitectura dos dois motores. Finalmente ´e apresentado o processo de integra¸c˜ao na empresa e os v´arios problemas encontrados

(21)

Cap´ıtulo 1. Introdu¸c˜ao 3

• No Cap´ıtulo 4 ´e apresentado a metodologia de testes e o resultados destes. Os testes apresentados tinham como objectivo mostrar a validade da aplica¸c˜ao desenvolvida, a mais valia de usar a ferramenta face a uma an´alise manual e finalmente ´e feita uma compara¸c˜ao dos tempos com o YASCA, uma an´alise manual e a aplica¸c˜ao com diferentes ficheiros de configura¸c˜ao.

• No Cap´ıtulo 5 s˜ao feitas as conclus˜oes finais sobre o trabalho desenvolvido e s˜ao feitas propostas de trabalho futuro.

1.4

Institui¸

ao de acolhimento

Este projecto foi desenvolvido ao abrigo da empresa Escrita Digital. Esta empresa foi fundada em Outubro de 2001 e tem como objectivo desenvolver produtos de software que facilitem o trabalho e gest˜ao de empresas. Os seus produtos s˜ao desenvolvidos na forma de aplica¸c˜oes web.

1.5

Contribui¸

oes

(22)
(23)

Cap´ıtulo 2

Contexto e trabalho relacionado

A primeira vers˜ao da web, a web 1.0, surgiu na d´ecada de 90. Esta consistia ape-nas em websites est´aticos, porque estes funcionavam apenas como reposit´orios de informa¸c˜ao. Nestes websites n˜ao existia qualquer tipo de interac¸c˜ao e as p´aginas serviam apenas para ir buscar informa¸c˜ao a um servidor. As vulnerabilidades de websites est´aticos existem apenas do lado do servidor, porque a informa¸c˜ao era a mesma para cada cliente e este n˜ao tinha forma de interagir com ele. Actualmente, o mesmo n˜ao acontece e grande parte dos websites s˜ao na realidade aquilo a que se chamam de aplica¸c˜oes web.

Estas aplica¸c˜oes web funcionam num paradigma em que existe um cliente, tipi-camente um brower e um servidor que fornece algum tipo de servi¸co. O servidor providencia este servi¸co sob a forma de uma aplica¸c˜ao web, que escreve c´odigo

Hy-perText Markup Language (HTML) que depois vai ser interpretado pelo browser.

Estas aplica¸c˜oes s˜ao desenvolvidas com recurso a linguagens web (i.e., PHP, ASP) ou atrav´es de alguma web framework (i.e., .NET, JSF, Spring MVC).

O funcionamento de grande parte destas aplica¸c˜oes web ´e feito atrav´es da sub-miss˜ao de formul´arios para um servidor. Estes formul´arios s˜ao p´aginas web que tipicamente tˆem campos de entrada que o cliente consegue popular com valores. Os valores dos campos de entrada v˜ao ser depois submetidos para o servidor atrav´es de pedidos HTTP. O servidor vai receber estes valores e vai utiliz´a-los em servi¸cos que ir˜ao devolver respostas.

O problema de seguran¸ca surge quando n˜ao ´e feita a correcta sanitiza¸c˜ao destes valores quando est˜ao a ser submetidos para o servi¸co; ou ent˜ao quando n˜ao ´e feita a sua codifica¸c˜ao quando est˜ao a ser devolvidos na resposta. A incorrecta, ou falta de sanitiza¸c˜ao ou codifica¸c˜ao pode permitir a um cliente malicioso a altera¸c˜ao do comporamente normal da aplica¸c˜ao, permitindo que esta tenha comportamentos diferentes daquele para a qual foi desenhada.

Outro tipo de vulnerabilidades recorrentes adv´em da implementa¸c˜ao incorrecta de mecanismos de autentica¸c˜ao, ou da inclus˜ao de componentes que contˆem eles pr´oprios vulnerabilidades.

As vulnerabilidades acima descritas, que aparecem no relat´orio referenciado ante-riormente [28] s˜ao: SQL Injection, Broken Authentication, Sensitive Data Exposure,

(24)

XXE injection, Broken Access Control, Security Miscofiguration, Cross-site scripting (XSS), Insecure Deserialization, utiliza¸c˜ao de componentes com vulnerabilidades co-nhecidas e falta de monitoriza¸c˜ao e registo de logs.

Na pr´oxima sec¸c˜ao s˜ao descritas, com maior detalhe, algumas vulnerabilidades, nomeadamente XSS, SQL injection e utiliza¸c˜ao de componentes com vulnerabilida-des conhecidas, consideradas mais relevantes no contexto vulnerabilida-deste projecto.

Devido ao processo natural de desenvolvimento de uma aplica¸c˜ao e de funciona-lidades, as vulnerabilidades surgem naturalmente, existindo portanto a necessidade de validar as p´aginas, utilizando m´etodos de an´alise de seguran¸ca.

Podemos distinguir trˆes tipos de an´alise: an´alise dinˆamica, an´alise est´atica e an´alise manual. Na an´alise dinˆamica s˜ao efectuados os testes contra a aplica¸c˜ao enquanto esta est´a a correr. Na an´alise de c´odigo est´atico ´e poss´ıvel identificar situa¸c˜oes que potencialmente v˜ao dar origem a vulnerabilidades. Todas as aplica¸c˜oes de an´alise de c´odigo est´atica recorrem a t´ecnicas de compiladores para analisar c´odigo e muitas vezes usam mais do que uma t´ecnica para o fazer: an´alise de fluxo de dados, an´alise de controlo de fluxo, an´alise lexical, taint analysis e pattern matching. Por ´

ultimo, a an´alise manual, em que ´e feita a an´alise ao c´odigo sem recorrer a qualquer tipo de ferramenta.

2.1

Vulnerabilidades em aplica¸

oes web

As vulnerabilidades aqui apresentadas em primeiro lugar e em maior detalhe s˜ao aquelas em que a aplica¸c˜ao desenvolvida ´e capaz de ajudar a detectar e prevenir. As outras, apesar de fugirem ao ˆambito deste projecto, s˜ao apresentadas de forma resumida. ´E explicada a sua origem, assim como a raz˜ao pela qual n˜ao podem ser detectadas com este tipo de aplica¸c˜oes.

2.1.1

Injection

Vulnerabilidades de Injection existem quando ´e poss´ıvel um utilizador malicioso enviar conte´udo malicioso para um interpretador. A superf´ıcie de ataque desta vulnerabilidade pode incluir vari´aveis de ambiente, parˆametros, servi¸cos externos e internos e tipos de utilizadores. Podemos distinguir v´arios tipos de vulnerabilidades dentro desta, SQL, Lightweight Directory Access Protocol (LDAP), Non relational

SQL (NoSQL), Operating System (OS) Injection. Na pr´oxima sec¸c˜ao ser´a fornecido mais informa¸c˜ao sobre este tipo de vulnerabilidade.

SQL Injection

Em aplica¸c˜oes web s˜ao utilizadas bases de dados para guardar informa¸c˜ao. O tipo de informa¸c˜ao que ´e guardada varia de acordo com o tipo de aplica¸c˜ao e com as funcio-nalidades que oferece. Estas bases de dados s˜ao manipuladas atrav´es de linguagens descritivas tal como o SQL.

(25)

Cap´ıtulo 2. Contexto e trabalho relacionado 7

O SQL permite fazer pedidos as tabelas para alterar e listar informa¸c˜ao. O exemplo mais simples disto ´e

-- Query para listar todas as colunas e todas as linhas da tabela utilizadores

select * from utilizadores

Na query acima ´e feito um pedido para listar todas as linhas na tabela utiliza-dores.

SQL injection ´e uma vulnerabilidade que j´a existe h´a muitos anos e continua a fazer parte das mais perigosas em aplica¸c˜oes web. ´E um tipo de vulnerabilidade que explora inputs que constroem querys baseadas no seu conte´udo ou usam o input como parˆametro de um procedimento. Nesta vulnerabilidade um utilizador malicioso injecta c´odigo SQL no input que ao ser utilizado vai levar a que a uma funcionalidade efectue opera¸c˜oes para as quais n˜ao foi pensada. Esta vulnerabilidade pode ser prevenida atrav´es de sanitiza¸c˜ao do conte´udo que ´e usado para construir a query ou procedimento. A sanitiza¸c˜ao pode ser feita de v´arias formas, uma delas ´e a subsitui¸c˜ao de caracteres que terminem strings em SQL por caracteres que transformem a express˜ao inteira a ser passada numa string. O car´acter depende da linguagem de SQL. Este problema n˜ao se prende apenas com inputs. Se um URL de uma p´agina tiver parˆametros que s˜ao usados directamente num procedimento ou para construir uma query, sem que seja feita a correcta sanitiza¸c˜ao o problema vai ser o mesmo.

<%

nome = request.queryString["nome"]

objdb.query("select * from utilizadores where nome=" & nome) %>

No exemplo acima temos um caso de c´odigo vulner´avel em que um parˆametro da query string ´e passado directamente para uma query. O parˆametro ´e o nome do utilizador e vai listar todas as linhas que tenham um nome igual ao do valor passado. Esta opera¸c˜ao ´e feita sem que ocorra qualquer tipo de sanitiza¸c˜ao. Neste caso, um utilizador malicioso pode usar o parˆametro nome para modificar o conte´udo da query [43].

Por exemplo, o utilizador malicioso poderia terminar a query e colocar uma tau-tologia, isto ´e uma condi¸c˜ao que ´e sempre correcta, por exemplo, 1 = 1, para isso bastaria colocar um parˆametro que fosse ” or010 = 010 o resultado disso seria:

select * from utilizadores where nome="" or ’1’=’1’

(26)

indiscri-minadamente. A sanitiza¸c˜ao neste caso deveria ser feita atrav´es da subsitui¸c˜ao das plicas por duas plicas, de modo a tornar toda a express˜ao que ´e passada para a

query numa string.

NoSQL Injection

NoSQL ´e um tipo de base de dados n˜ao relacional, onde n˜ao existe o conceito de tabelas como nas bases de dados cl´assicas. Numa base de dados n˜ao relacional os valores s˜ao guardados em registos, que podem ser organizados de v´arias formas,como grafos, pares chaves-valor, documento, entre outros. Este tipo de bases de dados oferece algumas vantagens em rela¸c˜ao `as bases de dados tradicionais, nomeadamente na escalabilidade e desempenho.

O tipo de ataques que s˜ao feitos a este tipo de base de dados podem inclusive-mente ser mais danosos do que numa base de dados tradicional, porque os ataques ocorrem numa linguagem que n˜ao ´e declarativa.

Isto faz com que seja poss´ıvel potencialmente executar ataques na camada apli-cacional, enquanto que no SQL Injection os ataques est˜ao limitados `a camada da base de dados.

LDAP Injection

O LDAP ´e um protocolo de aplica¸c˜ao que permite manter e aceder a direct´orios de servi¸cos de informa¸c˜ao distribu´ıdos. Essencialmente, ´e uma forma de organizar informa¸c˜ao de utilizadores, grupos ou outro tipos de entidades. Esta organiza¸c˜ao ´e feita atrav´es de hierarquias e permite definir atributos que caracterizam instˆancias de cada um dos tipos de entidades.

O tipo de ataques que ´e feito aqui consiste, `a semelhan¸ca com outro tipo de ataques da mesma classe, na introdu¸c˜ao de conte´udos que v˜ao modificar as querys LDAP. Neste caso vai permitir potencialmente a altera¸c˜ao de comandos que levem `

a altera¸c˜ao de permiss˜oes e do conte´udo que est´a na ´arvore LDAP.

2.1.2

Cross-Site Scripting

Ocorre quando ´e poss´ıvel a um utilizador enviar scripts maliciosos para outro uti-lizador, utilizando os campos de entrada da aplica¸c˜ao. As consequˆencia podem ser v´arias, por exemplo o acesso a cookies de sess˜ao que podem permitir ao atacante roubar a sess˜ao de outro utilizador. Pode tamb´em servir como m´etodo para levar o utilizador a fazer o download de ficheiros potencialmente maliciosos. Isto deve-se `a ausˆencia de uma correcta sanitiza¸c˜ao ou codifica¸c˜ao destes inputs ou parˆametros de um url.

Podemos distinguir dois tipos de XSS: client XSS e server XSS

O client XSS ocorre quando s˜ao usados dados de campos de entrada do lado do cliente para a actualiza¸c˜ao de conte´udo do Document Object Model (DOM) sem que seja feita codifica¸c˜ao. Este conte´udo pode estar a ser usado directamente na

(27)

Cap´ıtulo 2. Contexto e trabalho relacionado 9

p´agina, atrav´es de JavaScript, para a constru¸c˜ao de elementos no DOM, podendo levar `a execu¸c˜ao de c´odigo potencialmente vulner´avel.

<input ID="nome" value="<%=Nome%>"></input> <script>

document.write("<div>document.getElementById("#nome").val()</div>"); </script>

O caso acima constitui um exemplo . Nele temos um script que est´a a desenhar um

div directamente no DOM,e se houver conte´udo malicioso no input nome ent˜ao ser´a colocado no div atrav´es da chamada de javascript que ´e feita.

O server XSS ocorre quando s˜ao usados dados que vˆem do servidor directamente na p´agina, porque o servidor n˜ao est´a a fazer nenhuma sanitiza¸c˜ao ou codifica¸c˜ao.

<div ID="nome"><%=dr["nome"]%></div>

O exemplo acima ´e um dos casos mais simples de server XSS, onde temos o valor que vem da base de dados que ´e colocado directamente no DOM. No caso de um utilizador malicioso alterar o seu nome para, por exemplo, < script >

alert(”Conteudomuitomau”); < /script >, faria com que o conteudo a ser

exe-cutado fosse o que abaixo se mostra.

<div ID="nome"><script>alert("Conteudo muito mau");</script></div>

2.1.3

Utiliza¸

ao de Componentes com Vulnerabilidades

Co-nhecidas

Estas vulnerabilidades surgem quando s˜ao inclu´ıdos componentes que tˆem, eles pr´oprios, vulnerabilidades. Estas s˜ao muitas vezes algumas das acima. O problema surge quando s˜ao adicionados componentes sem que seja feita a an´alise devida so-bre as vulnerabilidades que estes podem conter. Estas s˜ao mais predominante em empresas cujo desenvolvimento de software seja maioritariamente dependente de bi-bliotecas externas, sem que estas sejam actualizadas ou verificadas da forma correcta antes de serem utilizadas.

2.1.4

Broken Authentication

Broken authentication [30] ´e uma vulnerabilidade que resulta de mecanismos de autentica¸c˜ao que n˜ao est˜ao implementados da forma correcta, ou seja, apesar de poderem estar correctamente programados, usam t´ecnicas de design fracas, tais como a aplica¸c˜ao de protocolos de hash que j´a foram quebrados, regras de cria¸c˜ao de passwords pouco exigentes, entre outros.

(28)

2.1.5

Sensitive Data Exposure

Sensitive Data Exposure [31] ´e uma vulnerabilidade que resulta da falta de utiliza¸c˜ao de protocolos de cifra em dados sens´ıveis de utilizadores, da utiliza¸c˜ao de protocolos de cifra e/ou de hash, de mecanismos de gest˜ao e gera¸c˜ao e/ou de chaves que s˜ao fracos e portanto facilmente quebr´aveis. Mais uma vez esta n˜ao pode ser validada atrav´es do c´odigo fonte.

2.1.6

XML Eternal Entities

XXE injection[32] tˆem origem na utiliza¸c˜ao de processadores antigos de XML. Este tipo de vulnerabilidades devem-se `a possibilidade de injec¸c˜ao de ficheiros de XML de fontes externas ou da inclus˜ao de conte´udo malicioso em documentos XML, permi-tindo explorar c´odigo vulner´avel, dependˆencias ou integra¸c˜oes. Esta vulnerabilidade, dada a sua natureza, tamb´em n˜ao pode ser detectada com uma ferramenta de an´alise de c´odigo est´atica.

2.1.7

Broken Access Control

O Broken Access Control [33] ´e uma vulnerabilidade que adv´em do incumprimento da regra de negar o acesso por defeito, que deriva do design incorrecto de princ´ıpios de separa¸c˜ao de privil´egios em aplica¸c˜oes web. Esta vulnerabilidade s´o pode ser validada atrav´es de testes de funcionalidade. Apesar de poder ser detectada por alguns tipos de ferramentas de an´alise est´atica que fa¸cam an´alise de fluxo n˜ao pode ser detectada pela ferramenta aqui apresentada.

2.1.8

Security Misconfiguration

Security Misconfiguration [34] tal como o nome indica, surge da configura¸c˜ao in-correcta de servi¸cos, podendo consistir, por exemplo, em contas configuradas pelo fabricante de um servi¸co, que nunca s˜ao alteradas. Esta tamb´em n˜ao pode ser detectada atrav´es de uma ferramenta de an´alise de c´odigo est´atica.

2.1.9

Insecure Desserialization

Insecure Desserialization [35] surge quando uma aplica¸c˜ao aceita objectos serializa-dos de fontes desconhecidas ou permite tipos de daserializa-dos n˜ao primitivos. S˜ao vulnera-bilidades dif´ıceis de encontrar e validar e a sua detec¸c˜ao implica ferramentas capazes de detectar falhas ao desserializar. Mais uma vez, tamb´em n˜ao pode ser detectada por uma ferramenta de an´alise de c´odigo est´atico.

2.1.10

Insufficient Logging & Monitoring

Insufficient Logging & Monitoring [36] tal como o nome indica, refere-se a falta de

(29)

Cap´ıtulo 2. Contexto e trabalho relacionado 11

web. Isto porque a monitoriza¸c˜ao e registo de logs pode ajudar a minimizar um ataque em curso, ou evitar o mesmo. Esta vulnerabilidade n˜ao pode ser detec-tada atrav´es de uma aplica¸c˜ao de an´alise de c´odigo est´atica, mas sim por meio de auditorias de seguran¸ca.

2.1.11

Injection

Vulnerabilidades de Injection existem quando ´e poss´ıvel um utilizador malicioso enviar conte´udo malicioso para um interpretador. A superf´ıcie de ataque desta vulnerabilidade pode incluir vari´aveis de ambiente, parˆametros, servi¸cos externos e internos e tipos de utilizadores. Podemos distinguir v´arios tipos de vulnerabilidades dentro desta, SQL, Lightweight Directory Access Protocol (LDAP), Non relational

SQL (NoSQL), Operating System (OS) Injection. Na pr´oxima sec¸c˜ao ser´a fornecido mais informa¸c˜ao sobre este tipo de vulnerabilidade.

SQL Injection

Em aplica¸c˜oes web s˜ao utilizadas bases de dados para guardar informa¸c˜ao. O tipo de informa¸c˜ao que ´e guardada varia de acordo com o tipo de aplica¸c˜ao e com as funcio-nalidades que oferece. Estas bases de dados s˜ao manipuladas atrav´es de linguagens descritivas tal como o SQL.

O SQL permite fazer pedidos as tabelas para alterar e listar informa¸c˜ao. O exemplo mais simples disto ´e

-- Query para listar todas as colunas e todas as linhas da tabela utilizadores

select * from utilizadores

Na query acima ´e feito um pedido para listar todas as linhas na tabela utiliza-dores.

SQL injection ´e uma vulnerabilidade que j´a existe h´a muitos anos e continua a fazer parte das mais perigosas em aplica¸c˜oes web. ´E um tipo de vulnerabilidade que explora inputs que constroem querys baseadas no seu conte´udo ou usam o input como parˆametro de um procedimento. Nesta vulnerabilidade um utilizador malicioso injecta c´odigo SQL no input que ao ser utilizado vai levar a que a uma funcionalidade efectue opera¸c˜oes para as quais n˜ao foi pensada. Esta vulnerabilidade pode ser prevenida atrav´es de sanitiza¸c˜ao do conte´udo que ´e usado para construir a query ou procedimento. A sanitiza¸c˜ao pode ser feita de v´arias formas, uma delas ´e a subsitui¸c˜ao de caracteres que terminem strings em SQL por caracteres que transformem a express˜ao inteira a ser passada numa string. O caractere depende da linguagem de SQL. Este problema n˜ao se prende apenas com inputs. Se um URL de uma p´agina tiver parˆametros que s˜ao usados directamente num procedimento ou

(30)

para construir uma query, sem que seja feita a correcta sanitiza¸c˜ao o problema vai ser o mesmo.

<%

nome = request.queryString["nome"]

objdb.query("select * from utilizadores where nome=" & nome) %>

No exemplo acima temos um caso de c´odigo vulner´avel em que um parˆametro da query string ´e passado directamente para uma query. O parˆametro ´e o nome do utilizador e vai listar todas as linhas que tenham um nome igual ao do valor passado. Esta opera¸c˜ao ´e feita sem que ocorra qualquer tipo de sanitiza¸c˜ao. Neste caso, um utilizador malicioso pode usar o parˆametro nome para modificar o conte´udo da query [43].

Por exemplo, o utilizador malicioso poderia terminar a query e colocar uma tau-tologia, isto ´e uma condi¸c˜ao que ´e sempre correcta, por exemplo, 1 = 1, para isso bastaria colocar um parˆametro que fosse ” or010 = 010 o resultado disso seria:

select * from utilizadores where nome="" or ’1’=’1’

Isto faria com que a informa¸c˜ao de todos os utilizadores fosse listada indiscrimi-nadamente. A sanitiza¸c˜ao neste caso deveria ser feita atrav´es da substitui¸c˜ao das plicas por duas plicas, de modo a tornar toda a express˜ao que ´e passada para a

query numa string.

NoSQL Injection

NoSQL ´e um tipo de base de dados n˜ao relacional, onde n˜ao existe o conceito de tabelas como nas bases de dados cl´assicas. Numa base de dados n˜ao relacional os valores s˜ao guardados em registos, que podem ser organizados de v´arias formas,como grafos, pares chaves-valor, documento, entre outros. Este tipo de bases de dados oferece algumas vantagens em rela¸c˜ao `as bases de dados tradicionais, nomeadamente na escalabilidade e desempenho.

O tipo de ataques que s˜ao feitos a este tipo de base de dados podem inclusiva-mente ser mais danoso do que numa base de dados tradicional, porque os ataques ocorrem numa linguagem que n˜ao ´e declarativa.

Isto faz com que seja poss´ıvel potencialmente executar ataques na camada apli-cacional, enquanto que no SQL Injection os ataques est˜ao limitados `a camada da base de dados.

LDAP Injection

O LDAP ´e um protocolo de aplica¸c˜ao que permite manter e aceder a direct´orios de servi¸cos de informa¸c˜ao distribu´ıdos. Essencialmente, ´e uma forma de organizar

(31)

Cap´ıtulo 2. Contexto e trabalho relacionado 13

informa¸c˜ao de utilizadores, grupos ou outro tipos de entidades. Esta organiza¸c˜ao ´e feita atrav´es de hierarquias e permite definir atributos que caracterizam instˆancias de cada um dos tipos de entidades.

O tipo de ataques que ´e feito aqui consiste, `a semelhan¸ca com outro tipo de ataques da mesma classe, na introdu¸c˜ao de conte´udos que v˜ao modificar as querys LDAP. Neste caso vai permitir potencialmente a altera¸c˜ao de comandos que levem `

a altera¸c˜ao de permiss˜oes e do conte´udo que est´a na ´arvore LDAP.

2.1.12

Cross-Site Scripting

Ocorre quando ´e poss´ıvel a um utilizador enviar scripts maliciosos para outro uti-lizador, utilizando os campos de entrada da aplica¸c˜ao. As consequˆencia podem ser v´arias, por exemplo o acesso a cookies de sess˜ao que podem permitir ao atacante roubar a sess˜ao de outro utilizador. Pode tamb´em servir como m´etodo para levar o utilizador a fazer o download de ficheiros potencialmente maliciosos. Isto deve-se `a ausˆencia de uma correcta sanitiza¸c˜ao ou codifica¸c˜ao destes inputs ou parˆametros de um url.

Podemos distinguir dois tipos de XSS: client XSS e server XSS

O client XSS ocorre quando s˜ao usados dados de campos de entrada do lado do cliente para a actualiza¸c˜ao de conte´udo do Document Object Model (DOM) sem que seja feita codifica¸c˜ao. Este conte´udo pode estar a ser usado directamente na p´agina, atrav´es de JavaScript, para a constru¸c˜ao de elementos no DOM, podendo levar `a execu¸c˜ao de c´odigo potencialmente vulner´avel.

<input ID="nome" value="<%=Nome%>"></input> <script>

document.write("<div>document.getElementById("#nome").val()</div>"); </script>

O caso acima constitui um exemplo . Nele temos um script que est´a a desenhar um

div directamente no DOM,e se houver conte´udo malicioso no input nome ent˜ao ser´a colocado no div atrav´es da chamada de javascript que ´e feita.

O server XSS ocorre quando s˜ao usados dados que vˆem do servidor directamente na p´agina, porque o servidor n˜ao est´a a fazer nenhuma sanitiza¸c˜ao ou codifica¸c˜ao.

<div ID="nome"><%=dr["nome"]%></div>

O exemplo acima ´e um dos casos mais simples de server XSS, onde temos o valor que vem da base de dados que ´e colocado directamente no DOM. No caso de um utilizador malicioso alterar o seu nome para, por exemplo, < script >

alert(”Conteudomuitomau”); < /script >, faria com que o conteudo a ser

(32)

<div ID="nome"><script>alert("Conteudo muito mau");</script></div>

2.1.13

Utiliza¸

ao de Componentes com Vulnerabilidades

Co-nhecidas

Estas vulnerabilidades surgem quando s˜ao inclu´ıdos componentes que tˆem, eles pr´oprios, vulnerabilidades. Estas s˜ao muitas vezes algumas das acima. O problema surge quando s˜ao adicionados componentes sem que seja feita a an´alise devida so-bre as vulnerabilidades que estes podem conter. Estas s˜ao mais predominante em empresas cujo desenvolvimento de software seja maioritariamente dependente de bi-bliotecas externas, sem que estas sejam actualizadas ou verificadas da forma correcta antes de serem utilizadas.

2.2

etodos de An´

alise

Os m´etodos de an´alise s˜ao utilizados para aumentar a confian¸ca na seguran¸ca da aplica¸c˜ao, atrav´es da detec¸c˜ao e correc¸c˜ao de vulnerabilidades. Estes m´etodos de-vem ser utilizados no ciclo de desenvolvimento das aplica¸c˜oes para que qualquer funcionalidade que ´e adicionada seja correctamente validada.

Existem v´arias ferramentas diferentes para este efeito, que variam no tipo de an´alise que fazem, na linguagem que analisam e no pre¸co. No caso de empresas de menor dimens˜ao o aconselhado ´e o uso de ferramentas de utiliza¸c˜ao livre ou o desenvolvimento de ferramentas que melhor se adaptem ao respectivo ciclo de desenvolvimento.

2.2.1

An´

alise Dinˆ

amica

Na an´alise dinˆamica a aplica¸c˜ao ´e analisada em tempo de execu¸c˜ao (i.e., runtime). Este m´etodo tamb´em ´e conhecido como black-box, porque a aplica¸c˜ao ´e frequente-mente tratada como uma caixa negra, onde quem est´a a testar apenas tem acesso `

as entradas e sa´ıdas.

Esta an´alise utiliza t´ecnicas de fuzzing para testar o comportamento da aplica¸c˜ao quando alvo de inputs inv´alidos e inesperados[20]. A an´alise dinˆamica oferece uma perspectiva do lado do atacante e permite descobrir m´etodos para explorar vul-nerabilidades, o que poderia n˜ao ser poss´ıvel descobrir com an´alises est´aticas ou manuais.

Por exemplo, durante uma an´alise interna de seguran¸ca que foi feita a uma das aplica¸c˜oes na Empresa Digital foi utilizada a ferramenta de an´alise dinˆamica wasp zap [37]. Com esta aplica¸c˜ao foi poss´ıvel injectar valores nos parˆametros da p´agina e atrav´es da resposta da p´agina perceber se existiam vulnerabilidades ou n˜ao.

(33)

Cap´ıtulo 2. Contexto e trabalho relacionado 15

2.2.2

An´

alise Est´

atica

Na an´alise est´atica, o c´odigo fonte ´e analisado sem que seja feita a sua execu¸c˜ao. Por esta raz˜ao ferramentas de an´alise de c´odigo est´atico s˜ao apropriadas em qualquer ciclo de desenvolvimento dado que s˜ao capazes de chegar `a raiz do problema de seguran¸ca e identificar potenciais problemas muito antes de o c´odigo ser executado. Permitem fazer uma an´alise do c´odigo sem o bias do programador e oferecem ainda a capacidade de rever o c´odigo legado contra novas vulnerabilidades. Dado que muitas destas ferramentas funcionam directamente sobre o c´odigo, oferecem v´arias vantagens n˜ao s´o em termos de tempo mas tamb´em em termos de custos e d˜ao a oportunidade ao programador de aprender a fazer c´odigo mais seguro, prevenindo assim potencias vulnerabilidades no futuro [19]. Na secc¸c˜ao 2.2.4 s˜ao discutidas em maior detalhe as vantagens de cada um dos tipos de an´alise.

Uma ferramenta de an´alise est´atica de c´odigo deve ser ent˜ao capaz de identificar blocos de c´odigo que s˜ao potencialmente vulner´aveis e reportar a sua severidade, sendo sempre da responsabilidade do programador ou analista determinar se se trata de um falso positivo ou um verdadeiro positivo.

Dado que a an´alise est´atica trabalha com o c´odigo fonte, tem um comporta-mento muito similar ao de um compilador. Esta necessita de ser capaz de transfor-mar c´odigo numa representa¸c˜ao abstracta para depois conseguir comparar com os padr˜oes que ´e capaz de reconhecer. Dependendo das capacidades da ferramenta, es-tes padr˜oes podem ser estendidos, oferecendo a possibilidade de serem criados novos padr˜oes ou de n˜ao poderem ser alterados. Isto leva potencialmente ao surgimento de falsos negativos, que constituem uma desvantagem j´a que levam ao surgimento de vulnerabilidades que deveriam ter sido identificadas como erros, mas que n˜ao geram nenhum alerta. Esta rela¸c˜ao entre o n´umero de falsos positivos, verdadeiros positivos e falsos negativos ´e o que permite inferir a qualidade de uma ferramenta de an´alise est´atica de c´odigo e ´e o que ´e usado muitas vezes como m´etrica.

Todos estes factores acarretam uma s´erie de desafios `a constru¸c˜ao de uma ferra-menta de an´alise de c´odigo. Estes s˜ao:

• Desenho de um bom modelo de programa que seja capaz de reconhecer a gram´atica da linguagem alvo, de forma coerente, ou pelo menos ser capaz de reconhecer e identificar os potenciais erros.

• Resultados apresentados devem ser f´aceis de interpretar pelo programador. • Ter a capacidade de ser alterada face a novas vulnerabilidades ou de ser

cor-rigida caso seja necess´ario.

2.2.3

An´

alise Manual

Na an´alise de c´odigo manual ´e feita a an´alise percorrendo os ficheiros e procurando ”`a m˜ao” por vulnerabilidades.

(34)

Este tipo de an´alise foi feita a uma das aplica¸c˜oes da empresa Escrita Digital, que implicou a an´alise manual a mais de 3 mil ficheiros.

O grande problema deste tipo de an´alise ´e que primeiro que tudo implica a forma¸c˜ao de programadores sobre vulnerabilidade, sobre o que procurar, como cor-rigir e o que n˜ao fazer no futuro. ´E tamb´em um trabalho moroso e pode ser poten-cialmente dispendioso em termos financeiros em empresas de pequena dimens˜ao que tˆem de alocar recursos humanos, i.e., programadores, que de outra maneira estariam a desenvolver novas funcionalidades. Implica tamb´em por vezes um conhecimento mais aprofundado da linguagem que se est´a a analisar.

2.2.4

Discuss˜

ao

Cada um dos m´etodos acima referidos tem vantagens e desvantagens. Contudo, em qualquer ciclo de desenvolvimento de uma aplica¸c˜ao, a decis˜ao n˜ao deve ser sobre que m´etodo usar, mas sim que ferramenta usar em cada um dos m´etodos.

Tal como referido acima, as ferramentas de an´alise dinˆamica operam sobre o programa em execu¸c˜ao e apresentam a grande vantagem de n˜ao necessitarem de acesso ao c´odigo fonte. Al´em disso, mostram, na perspectiva do atacante, a forma de explorar vulnerabilidades. Muitas vezes est˜ao integradas com outras ferramentas de auditoria e permitem criar relat´orios completos sobre o estado da aplica¸c˜ao, as suas capacidades, e os servi¸cos que estejam desactualizados, entre outros.

A grande desvantagem das ferramentas de an´alise dinˆamica ´e, por esta n˜ao possi-bilitar acesso ao c´odigo fonte, tornar dif´ıcil a localiza¸c˜ao da vulnerabilidade quando esta ´e identificada.

Existe tamb´em o problema destas ferramentas muitas vezes n˜ao serem capazes de fazer an´alise de fluxos de dados, podendo dar origem a potenciais falsos negativos. [45]

As ferramentas de an´alise est´atica usam o c´odigo fonte ou compilado e analisam-no directamente. Tˆem a vantagem de serem capazes de descobrir vulnerabilidades muito antes de elas se revelarem e s˜ao muito mais f´aceis de integrar directamente no ambiente de desenvolvimento do que ferramentas de an´alise dinˆamica.

´

E necess´ario referir que a an´alise est´atica de c´odigo ´e um problema de indecidi-bilidade porque, em absoluto, ´e imposs´ıvel saber com certeza o fluxo de execu¸c˜ao de um programa sem nunca o executar [43][44]. Se os padr˜oes de an´alise n˜ao estiverem correctamente configurados podem surgir falsos positivos ou mesmo falsos negativos. Outro problema das ferramentas de an´alise est´atica ´e o de n˜ao serem capazes de validar os casos em que protocolos de autentica¸c˜ao ou criptogr´aficos n˜ao estejam correctamente desenhados. Pode tamb´em ser dif´ıcil provar se uma vulnerabilidade identificada pode ser explorada ou n˜ao. Por exemplo, uma p´agina a que um utiliza-dor n˜ao consegue aceder pode estar vulner´avel, mas esta poder´a nunca ser explorada. Por ´ultimo temos a an´alise manual, cujos problemas atr´as referidos s˜ao ´obvios. N˜ao obstante ´e uma fase necess´aria e que deve, portanto, complementar as an´alises est´atica e dinˆamica. No entanto, este tipo de an´alise ´e muito suscept´ıvel a erro

(35)

Cap´ıtulo 2. Contexto e trabalho relacionado 17

humano.

2.3

Ferramentas an´

alise est´

atica de c´

odigo

Qualquer ferramenta de an´alise est´atica de c´odigo recebe como input ficheiros de c´odigo fonte ou ficheiros j´a compilados. Constr´oi um modelo que representa o pro-grama, analisa-o seguindo uma base de regras e padr˜oes e devolve o resultado ao utilizador.

´

E interessante estabelecer o paralelismo entre o funcionamento de um compilador, representado figura 2.1, e o funcionamento de uma ferramenta de an´alise est´atica, representada na figura 2.2, porque grande parte das t´ecnicas usadas em ferramentas de an´alise est´atica s˜ao retiradas dos compiladores.

Figura 2.1: Representa¸c˜ao de alto n´ıvel de um compilador

Podemos observar que muitas das fases s˜ao as mesmas, `a excep¸c˜ao das fases finais, porque o prop´osito de um compilador ´e gerar um execut´avel enquanto que o de uma aplica¸c˜ao de an´alise ´e tirar conclus˜oes sobre o c´odigo sem o executar.

A aplica¸c˜ao que ser´a desenvolvida neste projecto n˜ao vai conter todas as fases mencionadas na figura 2.2. Dentro da constru¸c˜ao do modelo apenas vai conter a an´alise lexical e v˜ao ser utilizadas algumas t´ecnicas de parsing. Isto porque para fazer uma ferramenta gen´erica com mais fases seria necess´ario fazer a gram´atica de qualquer linguagem alvo que se quisesse analisar. A vantagem de se fazer apenas a

(36)

Figura 2.2: Representa¸c˜ao de alto n´ıvel de uma ferramenta de an´alise est´atica de c´odigo

an´alise lexical e parte de um parser ´e que n˜ao ´e necess´ario especificar a gram´atica mas apenas ´e necess´ario especificar os padr˜oes que queremos identificar na linguagem alvo. A an´alise vai depois processar-se atrav´es do reconhecimento de padr˜oes. Esta fase pode tamb´em ser desenvolvida atrav´es de redes neuronais, como explorado na sec¸c˜ao 2.4).

2.3.1

An´

alise lexical

A an´alise lexical tem como objectivo definir tokens e traduzir o c´odigo num conjunto de instˆancias desses tokens. Em compiladores estas instˆancias tˆem o nome de lexemes e a identifica¸c˜ao dos tokens ´e feita recorrendo a express˜oes regulares.

Listing 2.1: C´odigo de exemplo

<%

’’Vai buscar o nome a query string ao parametro name

name = request.queryString["name"]

’’Isto vai imprimir para o ecra o name retirado do url

response.write name %>

Na analise lexical todas as linhas em branco e coment´arios no bloco de c´odigo 2.1 s˜ao ignorados. O foco desta an´alise, neste caso, ´e apenas o que est´a no bloco de

(37)

Cap´ıtulo 2. Contexto e trabalho relacionado 19

c´odigo 2.2.

Listing 2.2: C´odigo de exemplo sem coment´arios

<%

name = request.queryString["name"] response.write name

%>

Aplicando os padr˜oes dos tokens, s˜ao extra´ıdos v´arios lexemes que v˜ao ser colo-cados na tabela de s´ımbolos.

Tipicamente existem em todas as linguagens palavras reservadas, i.e., keywords, que n˜ao podem ser utilizadas como vari´aveis, nomes de instˆancias ou classes, como ´e o caso de if, else, true, f alse, int entre outros. Nestas palavras reservadas n˜ao existem instˆancias e portanto a descri¸c˜ao do token ´e o lexemme em si.

Temos ainda os literais que s˜ao aquilo a que se pode chamar de strings e que est˜ao entre “ ” . Finalmente, temos ainda os lexemes que s˜ao guardados em tabelas de s´ımbolos, juntamente com alguns dados como a linha e/ou a coluna onde apareceu pela primeira vez e ainda outro tipo de informa¸c˜ao.

Do bloco de c´odigo 2.2 podemos ent˜ao extrair os seguintes tokens e lexemmes; ID(name,1) - Lexemme = - Token ID(request,2) - Lexemme . - Token ID(queryString,3) - Lexemme ( - Token LITERAL(”name”) - Lexemme ) - Token ID(response,4) - Lexemme . - Token ID(write,5) - Lexemme ID(name,1) - Lexemme

A tabela de s´ımbolos que extra´ımos desta an´alise est´a representada na tabela abaixo Lexemme Position name 1 request 2 queryString 3 response 4 write 5

Tabela 2.1: Tabela de s´ımbolos

Nesta fase de an´alise lexical ´e interessante mencionar a ferramenta flex. Esta ferramenta permite especificar padr˜oes atrav´es de express˜oes regulares e escrever

(38)

c´odigo que vai ser executado quando uma express˜ao ´e reconhecida. Tipicamente a sua ac¸c˜ao ´e retornar um token para uma ferramenta de parsing.

Express˜oes regulares

A maneira mais f´acil de reconhecer padr˜oes ´e atrav´es de express˜oes regulares. Ex-press˜oes regulares s˜ao um conjunto de anota¸c˜oes constru´ıdas a partir de operadores de concatena¸c˜ao, fecho e uni˜ao, assim como tokens que descrevem alfabetos (con-juntos de um ou mais s´ımbolos). A grande vantagem das express˜oes regulares ´e a capacidade de poderem descrever qualquer linguagem que pode ser constru´ıda aplicando os operadores aos s´ımbolos de um alfabeto.

Um alfabeto no contexto de express˜oes regulares ´e definido como um conjunto finito de s´ımbolos, por exemplo o conjunto {0,1} pode ser definido como o alfabeto bin´ario.

O exemplo mais simples numa linguagem de programa¸c˜ao ´e a express˜ao regular que descreve um identificador em linguagem c, neste caso ´e [ a-zA-Z][ a-ZA-Z0-9]{0,31}.

Esta express˜ao regular ´e capaz de identificar qualquer conjunto de s´ımbolos que comece com um underscore ou por uma letra mai´uscula ou min´uscula e que seja seguida de uma combina¸c˜ao de underscores, letras mai´usculas ou min´usculas ou n´umeros que podem ter entre zero a trinta e um s´ımbolos. Esta express˜ao regular serviria para identificar ent˜ao express˜oes no c´odigo fonte como lexemmes de tokens do tipo identificadores.

A grande vantagem das express˜oes regulares ´e serem simplific´aveis utilizando os conceitos de alfabetos.

Por exemplo, se definirmos o alfabeto letras como o conjunto [a-zA-Z ] e o alfabeto numeros como o conjunto [0-9], podemos reescrever a regra [ zA-Z][ a-zA-Z0-9]{0,31} como (letras )(letras |numeros){0,31}.

´

E interessante tamb´em mencionar aqui m´aquinas de estado ou FSA(finite state

automaton), atrav´es da qual ´e poss´ıvel descrever visualmente o comportamento de uma express˜ao regular. Nas m´aquinas de estado temos estados que s˜ao representados como c´ırculos, transi¸c˜oes que s˜ao representados como setas e descrevem ac¸c˜oes me-diante uma condi¸c˜ao. A express˜ao de cima pode ser traduzida na seguinte m´aquina de estado:

(39)

Cap´ıtulo 2. Contexto e trabalho relacionado 21

A leitura da m´aquina de estados da Figura 2.3 ´e feita da seguinte maneira: quando ´e reconhecido um caractere que esteja compreendido no alfabeto letras ´e feita a transi¸c˜ao para o estado 1, quando deste ´e reconhecido qualquer caractere que esteja compreendido no alfabeto letras ou no alfabeto numeros, a m´aquina permanece no estado 1 at´e que identifique qualquer outro s´ımbolo (representado pelo alfabeto other ). Nesta fase, termina o reconhecimento de um identificador e pode-se chegar a um estado final representado por um c´ırculo, com um c´ırculo mais pequeno concˆentrico. Este t´opico ser´a mais aprofundado na sec¸c˜ao seguinte.

M´aquinas de estado

O reconhecimento interno de ferramentas de an´alise lexical ´e feito a partir destas m´aquinas de estado. Uma m´aquina de estado ´e o que se chama um aceptor de uma linguagem regular. ´E um modelo matem´atico de um computador que potencialmente ´e capaz de reconhecer qualquer programa, dentro das quais podemos distinguir dois tipos [42]:

• Aut´omato finito n˜ao determin´ıstica (AFND) - n˜ao tˆem restri¸c˜oes quanto aos s´ımbolos nas transi¸c˜oes podendo ter v´arias transi¸c˜oes com o mesmo s´ımbolo a partir do mesmo estado. Podem ainda ter transi¸c˜oes , que representa um caracter vazio. ´E destas mesmas labels em transi¸c˜oes diferentes que surge o n˜ao determinismo porque do mesmo estado com o mesmo s´ımbolo pode-se ir para estados diferentes.

• Aut´omato finito determinista (DFA),- n˜ao podem ter o mesmo s´ımbolo em diferentes transi¸c˜oes a partir de um mesmo estado.

Os programas que s˜ao capazes de reconhecer express˜oes regulares converter in-ternamente a express˜ao regular para uma destas m´aquinas de estado, e de seguida alimentam a m´aquina com a string que tˆem a express˜ao regular a ser reconhecida.

Existem outras variantes destas como o Posix AFND. A grande diferen¸ca desta para a AFND ´e que no Posix AFND ´e feito backtracking (voltar para um estado anterior para testar uma transi¸c˜ao diferente) at´e ser descoberta a maior express˜ao poss´ıvel. Existe tamb´em uma variante para o DFA, e existem ainda h´ıbridos que tentam fazer os dois.

M´aquinas de estado n˜ao deterministas (AFND)

Uma m´aquina de estados n˜ao determinista consiste num n´umero finito de estados, um alfabeto que ´e reconhec´ıvel pela m´aquina, um fun¸c˜ao de transi¸c˜ao para cada estado (que permite atribuir para cada s´ımbolo um estado seguinte), um estado inicial e um conjunto de estados finais.

Para desenhar uma m´aquina de estado capaz de reconhecer a express˜ao regu-lar, ”abc(a|b|c)*a” que corresponde a qualquer express˜ao que come¸ca com ”abc” e termina com ”a” e que pode ter no meio uma combina¸c˜ao qualquer de a,b ou c, a m´aquina de estados correspondente seria:

(40)

Figura 2.4: M´aquina de estados que reconhece a express˜ao abc(a|b|c)*a

Se considerarmos que as transi¸c˜oes  na figura 2.4 podem ser ignoradas, a m´aquina de estado acima ´e trivial. Podemos simplificar a vers˜ao acima

Figura 2.5: M´aquina de estados simplificada que reconhece a express˜ao abc(a|b|c)*a

Apartir desta m´aquina de estados se fizermos passar qualquer express˜ao na forma ”abc(a|b|c)*a”, como abcbbbbccccaaaaaaaa, abcbbaabaa entre outras, chegamos sempre a um estado final 13 na m´aquina de estados da figura 2.4 ou 4 na m´aquina de estados da figura 2.5, o que indica que a express˜ao dada ´e reconhecida pela m´aquina de estados, dado que podemos chegar a um estado de aceita¸c˜ao.

M´aquinas de estados deterministas (DFA)

Numa m´aquina de estados determinista, cada s´ımbolo est´a associada apenas a uma transi¸c˜ao e n˜ao existem transi¸c˜oes associadas ao s´ımbolo . Para se desenhar uma m´aquina de estados deterministas parte-se sempre de uma m´aquina de estados n˜ao deterministas. A mesma express˜ao regular referida em 2.3.1, representada neste tipo de m´aquina de estados, daria origem `a m´aquina de estados mostrada na figura 2.6.

A convers˜ao para este tipo ´e tamb´em bastante pesada. A ideia base de convers˜ao ´e calcular para cada estado a transi¸c˜ao poss´ıvel associada a cada s´ımbolo e perceber quais destas d˜ao origens a estados novos. Computacionalmente este processo ´e muito trabalhoso porque de cada vez que surge um estado novo ´e preciso re-calcular as transi¸c˜oes para cada s´ımbolo e perceber se o estado a que d´a origem j´a existe ou n˜ao. Se n˜ao existir ´e necess´ario continuar a calcular.

(41)

Cap´ıtulo 2. Contexto e trabalho relacionado 23

Figura 2.6: M´aquina de estados que reconhece a express˜ao abc(a|b|c)*a

Compara¸c˜ao

A grande vantagem das DFA ´e, dado que para cada estado existe apenas uma transi¸c˜ao para cada s´ımbolo, um estado de aceita¸c˜ao (final) pode ser alcan¸cado muito mais rapidamente. Por outro lado, em compara¸c˜ao com as AFND, onde ´e poss´ıvel ter v´arias transi¸c˜oes de um estado com o mesmo s´ımbolo, nestas pode vir a ser necess´ario fazer backtracking.

Outra desvantagem dos DFA ´e o espa¸co que ocupam. Qualquer AFND para uma linguagem Ln deve ter pelo menos 2n estados [16]. Isto pode ser um problema

se existirem alfabetos com muitos s´ımbolos e express˜oes regulares muito complexas, porque pode ser necess´ario utilizar espa¸co em disco se o espa¸co em mem´oria n˜ao for suficiente para armazenar a tabela de transi¸c˜ao.

Isto ´e uma das vantagens de utilizar as bibliotecas de express˜oes regulares do C# que fazem a tradu¸c˜ao da express˜ao regular para AFND e permitem a pr´e compila¸c˜ao de express˜oes regulares, convers˜ao do AFND para DFA. Isto faz com que a m´aquina de estados resultante seja mantida em mem´oria durante o tempo de execu¸c˜ao e n˜ao seja necess´ario estar sempre a reconstruir a mesma [24][25].

Algumas ferramentas de an´alise est´atica de c´odigo terminam a sua an´alise nesta fase. Ferramentas como o RATS, FLAWFINDER, YASCAA entre outras, tˆem al-gumas fun¸c˜oes identificadas como potencialmente vulner´aveis a ataques e quando as identificam recorrendo simplesmente a an´alise lexical, lan¸cam alertas.

2.3.2

Parsing

Este processo serve para, recorrendo a tokens obtidos pela an´alise lexical (figura 2.7), transformar o c´odigo fonte numa parse tree.

A parse tree ´e constru´ıda a partir daquilo a que se chama uma gram´atica livre de contexto, tipicamente representada na nota¸c˜ao Backus-Naur Form (BNF). Esta forma de especificar gram´aticas ´e f´acil de ler, de expandir e de especificar qualquer

(42)

Figura 2.7: Rela¸c˜ao entre a an´alise lexical e o parser

linguagem.

Gram´aticas livres de contexto

Este formato ´e o que permite especificar a sintaxe de uma linguagem atrav´es daquilo a que se chamam produ¸c˜oes, que se constroem a partir de s´ımbolos terminais e n˜ao terminais.

S´ımbolos terminais s˜ao os tokens obtidos atrav´es do reconhecimento de express˜oes regulares pela an´alise lexical. N˜ao terminais s˜ao os s´ımbolos que permitem especi-ficar a hierarquia de uma linguagem e s˜ao uma combina¸c˜ao de s´ımbolos terminais e/ou n˜ao terminais. Produ¸c˜oes especificam o m´etodo como s´ımbolos terminais e n˜ao terminais, podem ser combinados para formar strings.

A melhor forma de perceber gram´aticas livres de contexto ´e representando a gram´atica de opera¸c˜oes aritm´eticas. Neste caso, a an´alise lexical vai devolver os

tokens ou s´ımbolos terminais id, +, −, ∗, /, (, ). Um id ´e qualquer n´umero de zero a nove. Neste caso o que a gram´atica deve representar ´e a sintaxe correcta de uma opera¸c˜ao matem´atica. Esta gram´atica est´a representada na tabela 2.2. Com esta

1a express˜ao express˜ao + termo

2a express˜ao → express˜ao - termo 3a express˜ao termo

4a termo termo * factor

5a termo termo / factor

6a termo → factor

7a factor ( express˜ao )

8a factor {id}

Tabela 2.2: Regras de produ¸c˜ao para opera¸c˜oes aritm´eticas

gram´atica ´e poss´ıvel especificar a estrutura que qualquer opera¸c˜ao aritm´etica tem de seguir.

(43)

Cap´ıtulo 2. Contexto e trabalho relacionado 25

Se tomarmos como exemplo a seguinte express˜ao (1 + 4) ∗ 5 + 3, esta express˜ao vai come¸car por aplicar a primeira regra, que vai resultar em express˜ao + termo.

Sendo a express˜ao igual a (1 + 4) ∗ 5 e o termo igual a 3. De seguida vai ser aplicada

a terceira regra a (1 + 4) ∗ 5, que vai resultar em termo, que por sua vez vai aplicar a quarta regra termo ∗ f actor. O termo ainda pode ser mais simplificado, o que vai resultar em f actor, que vai resultar em (express˜ao). Sobre esta podemos aplicar

a primeira express˜ao que vai resultar em express˜ao + termo. Estas depois v˜ao ser simplificadas at´e `a oitava regra, que vai ser traduzida no token id. Estas regras s˜ao aplicadas aos tokens seguintes. Isto mostra-nos que a express˜ao (1 + 4) ∗ 5 + 3 ´e uma express˜ao v´alida, porque pode ser derivada recorrendo ´as express˜oes da tabela 2.2 da seguinte forma

express˜ao → express˜ao + termo express˜ao + termo → termo + termo termo + termo → termo ∗ f actor + termo

termo ∗ f actor + termo → f actor ∗ f actor + termo f actor ∗ f actor + termo → (express˜ao) ∗ f actor + termo

(express˜ao) ∗ f actor + termo → (express˜ao + termo) ∗ f actor + termo

(express˜ao + termo) ∗ f actor + termo → (id + termo) ∗ f actor + termo

(id + termo) ∗ f actor + termo → (id + id) ∗ f actor + termo (id + id) ∗ f actor + termo → (id + id) ∗ id + termo

(id + id) ∗ id + termo → (id + id) ∗ id + id (id + id) ∗ id + id → (1 + 4) ∗ 5 + 3

A deriva¸c˜ao aqui feita ´e `a esquerda e existe ainda uma variante `a direita. Com estas deriva¸c˜oes ´e depois poss´ıvel fazer aquilo a que se chama ´arvores de parsing ou sint´actica, sobre as quais ´e poss´ıvel fazer an´alises. Existem tamb´em muitas vezes representa¸c˜oes directas do c´odigo tal como o programador escreveu.

A ´area de parsing dentro de compiladores ´e uma ´area muito vasta existem v´arios tipos de gram´aticas que especificam o m´etodo como ´e feito o parsing, se ´e da esquerda para a direita assim como o n´umero de lookaheads (s´ımbolos que s˜ao vistos antes de ser aplicada uma regra de produ¸c˜ao). Estas considera¸c˜oes contudo j´a n˜ao s˜ao relevantes para este projecto. No entanto, s˜ao retiradas algumas ideias como a cria¸c˜ao de uma gram´atica de regras que representam padr˜oes de c´odigo vulner´avel.

2.3.3

Arvore sint´

´

actica

Uma ´arvore sint´actica ou de parsing ´e aquilo que permite representar sob a forma de ´

arvore, a estrutura de um c´odigo fonte escrita numa linguagem de programa¸c˜ao. A vantagem desta representa¸c˜ao ´e que permite perceber os v´arios caminhos que uma fun¸c˜ao pode tomar, de acordo com valores ou condi¸c˜oes diferentes. ´E sobre esta ´

arvore que s˜ao depois aplicadas as t´ecnicas de an´alise de controlo de fluxo, dados e a variante desta, i.e, taint analysis.

Para fazer a convers˜ao ´e necess´ario fazer a tradu¸c˜ao das v´arias regras de produ¸c˜ao que v˜ao especificar a cria¸c˜ao de n´os e de folhas na ´arvore. Neste contexto, um

Referências

Documentos relacionados

No segundo grupo mencionado, ocupações com ensino superior, a vantagem se desloca dos homens brancos para as mulheres brancas, sendo que 11,4% delas estão nesse grupo,

MURIALDO CANTO GASTALDON, Prefeito Municipal de Içara, no uso das atribuições que lhe confere o inciso VI do Artigo 73 da Lei Orgânica do

O perfil da produção de óxidos de terras-raras passou por uma profunda transformação ao longo das últimas décadas. Conforme mostrado na Figura 2.1, houve um decréscimo

domínio da palavra escrita e das habilidades funda- mentais para a reprodução do capital, mediante uma intensificação da divisão social do trabalho. Na sociedade burguesa, a

Durval de Almeida Souza Instituição: IFBA – Campus Vitória da Conquista Público-Alvo: Estudantes dos cursos superior e Técnicos. Local: Sala 01 (corredor do laboratório de

Para defender uma ideia de forma completa (uma tese), é preciso desenvolver muitos argumentos. Inclusive, cada argumento requer uma série de elementos, dados

No que, não é difícil perceber, Macedo serviria de interlocutor fundamental para que Machado forjasse o método narrativo de seus romances pós-Memórias póstumas de

eletrônicos, devem considerar a inter-relação com outros órgãos e entidades, a fim de oferecer serviços integrados. Artigo 14 - A contratação de empresas para