APIs e Microsserviços

1 dez, 2016

A importância do conhecimento avançado em programação e em segurança

Publicidade

Recentemente, durante um treinamento técnico para cerca de 30 engenheiros/especialistas a respeito de soluções de segurança para datacenters, ao iniciar uma conversa sobre a importância de que atualmente todos devem saber programar, eu dizia: “É muito mais fácil um profissional de segurança em redes aprender a programar do que um programador aprender sobre segurança”.

Neste exato momento, fui interrompido por uma dupla de engenheiros sentados na primeira fileira, explicando que não era bem assim, que era um absurdo etc. Lógico que ambos eram programadores que estavam se aprofundando no mundo de redes. Demorou um pouco para eu conseguir convencê-los de que eu ainda não tinha terminado meu raciocínio, e depois de acalmados os ânimos, concluí minha ideia: “Um engenheiro de redes pode saber pouco de programação, e eventualmente fazer um código nada otimizado ou organizado, mas que funcione; enquanto que o desenvolvedor precisa conhecer profundamente de segurança para poder criar códigos corretos”.

Sabendo que este é um portal cujos leitores são em maioria desenvolvedores, adiantarei a conclusão para evitar julgamentos à minha pessoa, já que este não é um artigo anônimo: eu estava totalmente enganado. Claro que levei um tempo para entender isso também, e muitas discussões com a mesma dupla de engenheiros, que hoje são meus amigos (espero!), e pretendo explicar como chegamos a este consenso.

Voltando ao assunto principal, vemos que cada vez mais o mercado busca profissionais que não estejam mais naquela dualidade velada, mas indiretamente imposta durante a faculdade ou cursos técnicos na área de computação, em que você precisa escolher entre seguir a linha de desenvolvimento de software ou especialização em redes.  Há também a opção de hardware, mas que no final acaba voltando ao tema de desenvolvimento e/ou redes, pois quase não existem mais hardwares “standalone” – tudo está conectado e interagindo.

Vemos cada vez mais produtos simples, ao mesmo tempo muito versáteis e completos, como os Arduínos, Raspberry, dentre outros. Com seus inúmeros módulos, sensores, atuadores e kits existentes, o foco acaba voltando sempre ao software. E estes kits normalmente possuem módulos GSM, wireless, bluetooth, xbee, zigbee, ou seja, com certa frequência realizam alguma interação com a rede.

O cenário fica ainda mais complexo quando falamos de IoT (Internet of Things), onde qualquer dispositivo pode estar na rede. SmartTVs, geladeiras com acesso à internet, sistemas de semáforos inteligentes, medidores de energia via rede, carros automatizados, entre outros que ainda serão inventados.

Há algum tempo que os maiores fabricantes de soluções de segurança possuem APIs (REST, SOAP, XML… Cada qual com sua opção) para gestão e configuração dos dispositivos. As APIs permitem que as empresas ou provedores de serviço criem portais ou aplicativos para seus clientes, ou ainda que integrem outras soluções existentes e criem automações de processos, melhorando, não só o serviço prestado em si, como também otimizando e garantindo maior segurança. Um dos exemplos mais comuns é o de um provedor de acesso que permite que seus clientes comprem um produto de segurança (firewall, IPS, filtro web, antispam, anti-malware etc) em um portal intuitivo e simples, criando automaticamente regras básicas para usar estes produtos.

Em uma aplicação web, em que exista formulário ou possibilidade de inserção de dados por parte de um usuário, é preciso que ela não esteja vulnerável à ataques de XSS (cross-site script), em que um atacante deixaria um código mal-intencionado para os demais usuários que acessarem o site. E não podemos esquecer de esconder informações sobre a aplicação em si (conhecido como “information disclosure”), pois elas podem ser usadas para direcionar o ataque de forma mais eficiente.

Existem vários dispositivos de segurança, tais como IPS e firewalls de aplicação web, que ajudam na proteção, caso o código tenha alguma falha, mas pode ocorrer do acesso ao serviço ou ao aplicativo não estar dentro do limite de atuação dessas soluções de rede.

E, voltando ao assunto de IoT, o cenário de proteção é ainda mais complicado, pois nem sempre existe a possibilidade física (ou lógica) de controlar todo o tráfego ao dispositivo, especialmente quando ele está geograficamente distribuído. Mesmo em uma aplicação genérica para smartphones ou laptops, deve-se ainda garantir que nenhuma variável estoure a memória, pois seria um vetor para um ataque de buffer overflow, permitindo execução de comandos diretamente no sistema operacional. Ou seja, os vetores de ataques são diversos.

Mas, afinal, como foi que eu percebi que eu estava errado naquela minha discussão com os desenvolvedores? Nada como sofrer na pele… Apesar de ter trabalhado como programador por alguns meses pouco antes de me formar, na época mal existia orientação a objetos e tive certa dificuldade em aprender a programar no SDK do Google Docs para criar uma planilha automatizada. Pensava, “esqueça a otimização, o importante é que funcione”.

Mas aí veio a primeira surpresa: vi que meu script demorava tanto que o Google dava timeout e o cancelava antes de finalizar. Resumindo, tive que otimizar o código (ainda demora, mas agora consome 80% menos tempo). Nesse caso, o importante foi: e se o Google não criasse esse timeout? E se ele esperasse o script terminar? Pior, e se vários usuários se dessem conta disso e executassem os scripts em paralelo? Será que o servidor suportaria?

Obviamente que o Google faz sua lição de casa e limita recursos aos usuários e scripts, mas a consequência inicial de quem não otimiza os códigos é óbvia: criamos um vetor de negação de serviço (conhecido como DoS = Denial of Service)! E num segundo passo, dependendo de como o sistema for tratar essa negação, ele pode vir a corromper um banco, um arquivo aberto, ou quem sabe acarretar um buffer overflow e sobrescrever memória executando comandos indevidos. Ainda que o consumo de recursos não seja alto suficiente para indisponibilizar o servidor, ao menos causaria lentidão aos usuários. Disponibilidade é um dos pilares de segurança – ou seja, seria considerado um ataque.

E quando você finalmente percebe algo (por exemplo, quando deixa de ser teimoso e escuta os outros), parece uma avalanche. Estava buscando na Play Store do Google um aplicativo de Voz sobre IP, testei vários para ver qual era mais interessante e notei que todos tinham exatamente a mesma estrutura, mesmas opções, alguns até as mesmas telas, só mudava a cor ou o pano de fundo. Ou seja, todos aplicativos usam a mesma base de código! E, me desculpem, acho improvável que o desenvolvedor tenha analisado aquela base procurando por possíveis overflows, variáveis não limitadas, otimizações de código etc. Ou seja, sua aplicação já vem cheia de possíveis brechas.

Quer um exemplo mais prático? Faça testes de invasão nos DVRs (aquelas centrais de câmeras que muitos colocam em casas ou escritórios); você vai notar que praticamente todos estão vulneráveis às mesmas falhas de PHP, ou seja, usam o mesmo código base. Não é à toa que os DVRs de grandes fabricantes possuem preços mais elevados, porque eles (teoricamente) são minuciosamente avaliados e, consequentemente, mais seguros.

E se aquele portal que usa uma API para configurar automaticamente um dispositivo de rede não for otimizado? E se um simples script que eu criei para configurar um serviço simples na rede, ou fazer um mero teste, for mal escrito? E se ele usar muita memória? E se não validar corretamente um dado de entrada digitado pelo usuário? Significa que muito provavelmente ele será um vetor para um ataque.

Imagine então no cenário de IoT, em que dispositivos são reduzidos em custo e muitas vezes em capacidade computacional.  Será que realmente todos os desenvolvedores revisam cuidadosamente seus códigos e inserem todos os controles de variáveis, limites, entre outros, ainda mais quando a quantidade de memória é limitada e o preço final do dispositivo é tão baixo?

Frequentemente vemos profissionais de segurança discutirem com os gestores das empresas sobre soluções que protegem as redes e aplicações contra eventuais vulnerabilidades que os desenvolvedores possam não ter visto nos códigos. E ainda pedem ao gestor para não comentar com os desenvolvedores, evitando deixá-los chateados (eu mesmo confesso ter feito isso algumas vezes). É sim muito importante ter soluções na rede como firewalls, IPS, WAF etc., mas enquanto não tivermos a visão de que somos uma mesma equipe com um mesmo objetivo, dificilmente conseguiremos criar soluções mais seguras. Em um mundo onde cada vez mais as interações se darão entre dispositivos com software via web, ainda temos muito que aprender uns com os outros.