Usando os padrões de codificação SEI CERT para melhorar a segurança da Internet das Coisas
A Internet das Coisas (IoT) é insegura. O hack da Jeep recebeu muita publicidade, e há várias maneiras de hackear caixas eletrônicos,com incidentes ocorrendo com maior regularidade. Impressoras em instalações seguras têm sido usadas para exfiltrar dados dos sistemas aos quais estavam conectados, e até mesmo um termômetro no aquário de um cassino foi usado para obter acesso à infraestrutura do cassino e extrair dados sobre clientes, jogadores, etc. Neste post no blog, descrevo como funcionam os Padrões de Codificação SEI CERT e como eles podem reduzir o risco em sistemas conectados à Internet. Esta é a primeira parte de uma série de duas partes; na Parte 2, descreverei como usar a análise estática para aplicar as regras de codificação CERT.
Automóveis ilustram os riscos intrínsecos à IoT. O número de computadores incorporados e a quantidade de código nos carros aumenta a cada ano: os carros high-end hoje têm mais de 100 milhões de linhas de código. Também sabemos que os incidentes relatados de cibersegurança aumentaram constantemente entre 2006 e 2014, anos em que o Centro de Coordenação do CERT manteve e relatou esses dados. O número de incidentes de cibersegurança continuou a aumentar desde 2014 e é improvável que diminua tão cedo. Levando em conta os benchmarks para números de defeitos por mil linhas de código (KLOC), mais código geralmente equivale a mais oportunidades de vulnerabilidades.
Figura 1: CERT Incidentes anuais de cibersegurança relatados, 2006-2014
Existem várias maneiras hoje de os atacantes entrarem em um carro - Bluetooth, WiFi, conectividade celular e identificação por radiofrequência (RFID) – e os ataques cibernéticos estão aumentando em frequência e sofisticação. Por exemplo, um atacante pode usar o sistema de monitoramento de pressão dos pneus de um carro para entrar no carro e mudar as coisas.
Os sistemas de infotainment em carros requerem comunicação com o mundo exterior. Os sistemas de navegação precisam se comunicar com o Sistema de Posicionamento Global (GPS) e com redes celulares e satélites, e os rádios AM/FM precisam se comunicar através de canais de rádio. Muitos outros recursos requerem acesso à Internet. Os sistemas de infotainment também permitem que os usuários conectem seus próprios dispositivos ao carro através de portas USB, Bluetooth e até mesmo para jogar CDs antiquados.
Embora essas capacidades sirvam a propósitos legítimos, toda essa conectividade com o mundo exterior expõe uma série de interfaces que podem ser atacadas para se comunicar com o carro de maneiras não intencionais e potencialmente perigosas. Ao explorar vulnerabilidades em sistemas de infotainment, os atacantes podem ter acesso ao computador de infotainment do carro, e através disso para o barramento da rede de área do controlador (CAN). Uma vez que os atacantes têm acesso a isso, há poucas, se houver, funções do veículo que eles não podem controlar.
Codificação segura
Práticas de codificação segura podem reduzir os riscos que acabei de descrever. As pessoas gostam de pensar que os codificadores são simplesmente tradutores que pegam um design de software e criam fielmente um programa seguro e funcional a partir do design. Infelizmente, a fase de codificação do ciclo de vida do desenvolvimento de software é onde a maior parte das vulnerabilidades são introduzidas. De fato, um estudo mostrou que 64% das vulnerabilidades se originam durante a fase de codificação. Embora algumas vulnerabilidades se originem na fase de design, os problemas de codificação são responsáveis por muitas vulnerabilidades comumente exploráveis, incluindo estouros de buffer, injeção de vulnerabilidades e scripting entre sites. Bugs de segurança também são problemas de qualidade, uma consequência de desenvolvedores cometerem erros de codificação (juntamente com alguns erros de design). Então, para resolver este problema, devemos
- Treine os desenvolvedores em codificação segura para que eles possam prevenir ou pelo menos encontrar e corrigir problemas de segurança.
- Projetar e construir sistemas com foco deliberado em qualidade e segurança.
- Coletar e medir dados de defeitos (sobre qualidade e segurança de código) e usá-los para avaliar e melhorar as práticas de desenvolvimento.
Para resolver esses problemas, construímos o SEI CERT C Coding Standard, um dos vários padrões de codificação desenvolvidos pela equipe de Codificação Segura CERT para linguagens de programação comumente usadas, como C, C++, Java e Perl, e a plataforma Android. Esses padrões são desenvolvidos através de um amplo esforço comunitário por membros das comunidades de desenvolvimento de software e segurança de software. A primeira edição do padrão CERT C foi publicada em 2008, e a 3ª edição, publicada em 2016, está disponível gratuitamente como PDF para download. A versão mais atualizada está disponível gratuitamente em nossa wiki, que também pode ser usada para enviar comentários, fazer perguntas ou erros de bandeira.
Existem 103 regras e 169 recomendações no SEI CERT C Coding Standard. As regras da norma devem atender aos seguintes critérios:
- É provável que a violação resulte em um defeito que pode afetar negativamente a segurança de um sistema e também pode causar problemas de segurança e confiabilidade.
- A regra não se baseia em anotações ou suposições de código-fonte.
- A conformidade pode ser determinada através de análise automatizada (estática ou dinâmica), métodos formaisou inspeção manual.
Regras de codificação SEI CERT
A maioria das regras de codificação SEI CERT tem uma estrutura consistente. Cada regra tem um identificador único, que está incluído no título. O título e os parágrafos introdutórios definem a regra e são normalmente seguidos por um ou mais pares de exemplos de código não conformes e soluções compatíveis. Cada regra também inclui uma avaliação de risco, diretrizes relacionadas e uma bibliografia. As regras também podem incluir um parágrafo descrevendo vulnerabilidades relacionadas.
As recomendações são organizadas de forma semelhante. Referimo-nos às regras e recomendações coletivamente como diretrizes.
Exemplos de código não conformes ilustram código que viola a diretriz em discussão. Exemplos de código não conformes são normalmente seguidos por soluções compatíveis, que mostram como o exemplo de código não compatível pode ser recodificado de forma segura e compatível.
Qualquer diretriz pode especificar um pequeno conjunto de exceções detalhando as circunstâncias em que a diretriz não é necessária para garantir a segurança, confiabilidade ou segurança do software. As exceções são apenas informativas e não são necessárias para serem seguidas.
Figura 2: SEI CERT Secure Coding Rules, Avaliação de Risco
Cada regra tem uma avaliação de risco, cujos valores são explicados pela Figura 2. Os desenvolvedores de sistemas IoT podem usar as regras de codificação SEI CERT para avaliar o risco para seus sistemas. Ter essa priorização das regras permite a triagem de vulnerabilidades quando há muitas para corrigir ao mesmo tempo.
A avaliação de risco consiste em três métricas.
- Gravidade. Se uma vulnerabilidade é designada como de baixa gravidade, significa que o pior que pode fazer é fazer com que o programa falisse ou se enforcasse. Isso pode ser ruim se, por exemplo, o programa estiver mantendo um servidor web ou executando seu marca-passo, mas na maioria das circunstâncias, travar ou pendurar não é necessariamente tão ruim; você acabou de reiniciar o programa. Nível 2, gravidade média, significa que seria possível extrair dados do sistema ou modificar os dados nele, mas não executar código. Nível 3, alta gravidade, indica que código arbitrário ou malicioso poderia ser executado no sistema. A razão pela qual classificamos essas gravidades é que se você tem gravidade nível 2, você quase sempre terá também nível 1. Se alguém pode exfiltrar informações do seu código, quase certamente pode queá-lo. Da mesma forma, se você tem gravidade nível 3, se alguém pode executar seu próprio código, ele pode ver qualquer informação que eles querem ver e pode travar programas à vontade.
- Probabilidade. Improvável, provável ou provável.
- O custo é que o preço. Como é difícil corrigir o código? Ou seja, a vulnerabilidade pode ser detectada automaticamente? Pode ser corrigido automaticamente por algum mecanismo de reescrita de código? O nível mais alto é, na verdade, o mais fácil e mais barato de corrigir, todo automático, e o nível mais baixo é o mais difícil de corrigir, todos manuais.
Figura 3: Níveis de prioridade
Cada uma dessas três métricas produz um número agregado entre 1 e 3, como mostrado na Figura 3. Multiplicamos os números de gravidade, probabilidade e custo para obter uma prioridade, que será um número entre 1 e 27. A prioridade 27 é a mais alta, e representa os problemas mais críticos, enquanto a prioridade1 é a mais baixa. Finalmente dividimos essas prioridades em três níveis, 1, 2 e 3. Novamente, 1 é o mais grave, o mais importante para corrigir, e 3 o menos importante para corrigir. Os maiores números agregados nesta avaliação de risco, os de maior prioridade para fixação primeiro, indicam vulnerabilidades sobre quais código arbitrário poderia ser executado e que são fáceis de detectar e corrigir. As prioridades mais baixas indicam vulnerabilidades que têm baixa gravidade - elas levam apenas a acidentes - e isso é improvável de acontecer e difícil de corrigir.
Olhando para o futuro: O Valor da Análise Estática
Para apoiar um padrão de codificação em seus esforços de desenvolvimento, você deve aplicá-lo no código produzido pela sua equipe de desenvolvimento. A menos que você esteja usando análise estática para impor seu padrão de codificação, então você deve aplicá-lo manualmente ou através de revisão por pares. Ambas as opções são muito trabalho, são propensas a erros, e em um sistema como um único carro, com cem milhões de linhas de código, são simplesmente intratáveis. Além disso, ao contrário da revisão por pares, a análise estática é automaticamente exequível e pode confirmar que uma vulnerabilidade, uma vez identificada, foi adequadamente corrigida.
A disparidade entre o uso de normas como as regras de Codificação SEI CERT e o uso de análise estática para identificar desvios dessas regras é ilustrada por dados do Relatório de Segurança Embarcada do Grupo Barr de 2017 e 2018 (ver Figura 4 abaixo).
Figura 4: Relatório de Segurança Embarcada do Grupo Barr 2017 e 2018
As barras à direita mostram uma lacuna entre pessoas que usam padrões de codificação e pessoas executando uma ferramenta de análise estática, especialmente em 2017, onde a lacuna é enorme.
Na parte 2 deste post no blog, entrarei em detalhes sobre como desenvolvedores de sistemas de grande escala, como sistemas de IoT em automóveis, podem usar análises estáticas para impor regras de codificação CERT.
Recursos adicionais
Acesse versões atuais dos Padrões de Codificação Segura DO CERT.
Assista ao Webinar, How Can I Enforce the SEI CERT C Coding Standard Using Static Analysis de David Svoboda e Arthur Hicken.
Leia outros posts de blog sei relacionados à codificação segura.
Autor: DAVID SVOBODA