Software X Segurança
O software é um conjunto de instruções de computador que visa auxiliar um processo qualquer humano. Na maioria das vezes ele auxilia um processo que já existe manualmente. Isso quer dizer que não existe um software separado do mundo, ele é parte de um processo.
O software não existe no vácuo. Ele é uma ferramenta a serviço de um processo, executado por pessoas.
- Existe um conjunto de atividades antes do software ser usado.
- Outro durante o uso do software.
- E um processo ao final do uso do software.
Um software de folha de pagamento, por exemplo, não cria o processo de pagar funcionários. Ele automatiza e auxilia um processo que já existia (cálculos manuais, emissão de cheques, etc.). As atividades de coletar as horas trabalhadas (antes), operar o software (durante) e distribuir os holerites e fazer os pagamentos (depois) continuam existindo. O software é apenas a peça central que otimiza o "durante".
Não existe segurança de software desacoplado dos processos em torno dele. É um erro achar que segurança resume-se somente ao software.
Este é o pilar da segurança da informação moderna. Um software pode ser tecnicamente perfeito, sem nenhuma vulnerabilidade, mas ainda assim ser comprometido por falhas nos processos ao seu redor.
Vamos exemplificar isso.
- Um sistema bancário pode ter a criptografia mais forte do mundo, mas se o processo permite que um funcionário anote a senha do cliente em um post-it, a segurança foi quebrada pelo processo, não pelo software.
- Um servidor na nuvem pode ser extremamente seguro, mas se o processo de configuração for mal executado e um administrador deixar uma porta de acesso aberta para toda a internet, o sistema se torna vulnerável. A falha não foi do software do servidor, mas do processo humano ao redor dele.
Todo software é uma mudança de cultura, antes faziam de um jeito, agora fará de outro. A implantação de um software exige mudança inclusive nos processos manuais em torno dele.
Podemos colocar como exemplo uma empresa que usava planilhas para controle de clientes e implanta um sistema de CRM (Customer Relationship Management). Muitos vendedores podem resistir, achando o sistema novo "complicado" ou "lento", e continuarão usando suas planilhas antigas "por segurança", criando uma inconsistência de dados e um risco de segurança (dados de clientes em arquivos soltos).
- O ser humano tem como hábito continuar tentando fazer algo do jeito que fazia antes.
- O usuário acha que o sistema é mais inseguro do que o jeito anterior.
Isso é uma questão de percepção e confiança. O processo manual, por ser familiar e tangível (uma pasta de papel em um armário), pode parecer mais seguro para o usuário do que um sistema digital "abstrato" na nuvem, mesmo que o armário pudesse ser arrombado facilmente e o sistema na nuvem tenha múltiplas camadas de criptografia e controle de acesso. A falta de compreensão gera desconfiança.
O usuário é frequentemente chamado de "a última linha de defesa" ou, se não for treinado, o "elo mais fraco" da segurança.
Quando Software é Considerado Seguro?
Por mais testes que tenham sido executado, o software é um mecanismo complexo e quase certeza que alguma falha não foi prevista, e ao longo do tempo elas vão sendo corrigidas.
Por que um sistema entra em produção mesmo com falhas? Por que é muito barato corrigir uma falha, ao contrário de uma empresa que produz carros que o sistema de recall seria extremamente danoso financeiramente podendo levar uma empresa a falência.
Claro que em algumas circunstâncias existem erros de software que são extremamente caros, como por exemplo um software de um avião que para de funcionar levando a queda e a morte de muitas pessoas.
A idéia é desenvolver software que as fallhas não gerem prejuízos catastróficos.
Processos de Desenvolvimento de Software
É necessário primeiro entender sobre como funciona o processo de desenvolvimento de sofware para que faça sentido o estudo sobre segurança em software. Se já conhece todo o processo, ótimo! Vou tentar fazer um resume de anos em poucas linhas.
Basicamente essas são as etapas de um desenvolvimento de softare, mas é necessário levar em consideração que a metodologia usada pode mudar a forma com que cada etapa é executada.
- Levantamento Inicial
- Especificação
- Análise e projeto
- Codificação
- Testes
- Implantação
- Manutenção
Antigamente tinhamos algumas metodologias (abaixo) que hoje são consideradas defasadas depois do que chamamos de Manifesto Ágil. Não vamos entrar em detalhes, sobre elas, se for do seu interesse basta pesquisar.
- Cascata
- Espiral Interativo
- Prototipagem evolucionária
- Codificação e correção
Manifesto Ágil
As metodologias acima geralmente não entregavam o software que o cliente pediu, pois o cliente não sabe o que quer de verdade ou não pensou em todos os aspectos. Muitas vezes o mercado mudava antes mesmo sofware ficar pronto. Era necessário uma metodologia que incluísse o cliente no processo e que fosse flexível e essa foi a base para o que chamamos de Manifesto Ágil.
- Indivíduos e interações sobre processos e ferramentas
- Isso foca o colaborador no projeto ao invés das burocracias envolvidas.
- Ferramentas e processos são importantes, mas eles devem servir às pessoas, e não o contrário.
- Software funcional sobre documentação extensa
- O software esta em constante evolução. Perder muito tempo documentando não faz sentido se isso mudará tão rápido. Isso não quer dizer que não se deve ter uma documentação mínima viável.
- Colaboração do cliente sobre negociação contratual
- O cliente deve fazer parte da equipe e ver o que esta acontecendo e o que esta sendo desenvolvivo. Isso evita contratos fechados com tempo determinado, mantém o cliente sempre informado e faz com que erros de especificação ou entendimento sejam encontrados rápido.
- Resposta a mudança sobre o planejamento
- Começa a produzir e responde a mudança como necessidade.
É muito importante observar que a arquitetura do software em desenvolvimento precisa ser pensada para responder as mudanças. Um software completamente acomplado em suas funções compromete esse fator e ou demanta mais tempo para a mudança.
As metologias ágeis mais usadas hoje são:
-
Scrum
- Baseado em sprints de trabalho curtos e estruturados
- As equipes de Scrum se comprometem a concluir um incremento de trabalho, que pode ser enviado, por meio de intervalos definidos, chamados de sprints. O objetivo é criar ciclos de aprendizagem para reunir e integrar com rapidez o feedback dos clientes. As equipes Scrum adotam papéis específicos, criam artefatos especiais e realizam cerimônias regulares para manter o avanço das coisas. O Scrum é definido melhor no Guia Scrum.
-
Kanban
- Torna o processo mais fluído
- Tem a ver com visualizar o trabalho, limitar o trabalho em andamento e maximizar a eficiência (ou fluxo). As equipes Kanban têm como foco a redução do tempo que leva para o projeto (ou história do usuário) ir do início ao fim. Para alcançar esse objetivo, elas usam o quadro Kanban e melhoram sempre o fluxo de trabalho.

| Scrum | Kanban | |
|---|---|---|
| Origem | Desenvolvimento de software | Fabricação lean |
| Ideologia | Aprenda por meio de experiência, auto-organização e priorização e reflita sobre os ganhos e as perdas para sempre melhorar. | Use recursos visuais para melhorar o trabalho em andamento |
| Ritmo | Sprints regulares, de duração fixa (ex.: duas semanas) | Fluxo contínuo |
| Práticas | Planejamento de sprint, sprint, scrum diário, revisão de sprint, retrospectiva do sprint | Visualize o fluxo do trabalho, limite o trabalho em andamento, gerencie e fluxo e incorpore loops de feedback |
| Funções | Proprietário do produto, mestre scrum, equipe de desenvolvimento | Sem funções obrigatórias |
Vale um estudo aprofundado sobre essas metodologias para trabalhar com software hoje em dia, principalmente o Scrum. Geralmente as empresas adaptam o scrum às suas necessidades diminuindo algumas cerimônias. Existe até um mix entre Scrum e Kanban chamda Scrumban.
Existem muitas ferramentas que ajudam na aplicação das metodologias ágeis.
Software Legado
Um software legado é um sistema, tecnologia ou aplicação que, embora ainda esteja em uso e muitas vezes seja crítico para as operações, é considerado obsoleto. Ele permanece ativo principalmente por duas razões: suporta processos de negócio vitais ("ainda funciona") e o custo ou o risco de substituí-lo ou modernizá-lo é considerado proibitivo pela organização.
- Documentação inexistente ou Desatualizada tornando qualquer modificação um processo lento e arriscado.
- Escrito em linguagens obsoletas que possuem poucos desenvolvedores disponíveis no mercado.
- Possui alto custo de manutenção
- Foi desenvolvido sem seguir os padrões modernos de engenharia de software, resultando em um código.
Representa um grande risco para a segurança da informação, pois não recebe atualizações e muitas vezes possui vulnerabilidades conhecidas e não corrigidas.
Linguagens de programação
O processador só entende binário 0 e 1 e os seres humanos tem dificuldade de programar diretamente assim.
Para isso são definidas linguagens de alto nível que criam um algoritmo (fluxo lógico) que consegue ser lido facilmente por seres humanos.
O compilador (outros software) lê esta linguagem de alto nível e transcreve para binário.
As linguagens pode ser:
-
Compiladas (C, C++, Delphi, Python, Rust, etc)
- Pega o código fonte de alto nível e gera o executável que já está em linguagem de máquina (0 e 1)
- É necessário recompilar em cada mudança do código fonte
- É necessário compilar para a arquitetura correta do processador
- Costuma ser linguagens mais rápidas por já estar tudo pronto.
-
Código Intermediário (Java, C#)
- Gera um código intermediário para rodar sobre uma máquina virtual que é preparado para ler esse pré compilado e compilar corretamente para a arquitetura do processador que a máquina virtual está rodando, fazendo os ajustes necessários e até melhorias.
- Costuma otimizar o código para a compilação final de acordo com o processador sendo uma vantagem sobre o código interpretado.
- Linguagem se preocupa em gerar máquinas virtuais para cada arquitetura de processador.
- Maior flexibilidade
- É mais fácil de fazer a engenharia reversa com o código pré compilado gerando um problema de segurança.
-
Interpretada (PHP, Java Script, Beanshell, etc)
- Lê o código fonte em tempo de execução e gera o código de máquina em tempo real.
- Não necessita gerar executáveis preparados para cada arquitetura
- Menos performático
Desenvolvimento de Aplicativos Mobile
O desenvolvimento de aplicativos mobile frequentemente utiliza um código intermediário. Este código, por sua vez, passa por um processo de compilação final que o otimiza para a arquitetura específica dos processadores móveis, visando maximizar a performance e, principalmente, a eficiência energética para preservar a vida útil da bateria.

Para garantir a autenticidade e a integridade do aplicativo, protegendo-o contra adulterações e falsificações, o código final é assinado digitalmente com um certificado digital.

Tanto o Android quanto o iOS realizam rigorosamente essa validação. Caso o código do aplicativo seja modificado de qualquer forma, a assinatura digital se torna inválida, e o sistema operacional recusa a instalação ou a atualização do app, protegendo o usuário.
A filosofia da Apple é mais restritiva: além da assinatura do desenvolvedor, a própria Apple revisa e "notariza" cada aplicativo, centralizando a distribuição na App Store (com exceções recentes para lojas alternativas na União Europeia). Já o Android permite a instalação de apps de fontes externas (processo conhecido como sideloading), desde que o aplicativo possua uma assinatura digital válida.
Do ponto de vista da segurança para o usuário comum, essa abordagem centralizada faz com que o ecossistema do iPhone seja amplamente considerado mais seguro, pois elimina o principal vetor de malwares: a instalação de apps de fontes não confiáveis.
O risco no Android reside no fato de que, embora não se possa atualizar um app com uma assinatura diferente, um invasor pode adulterar um aplicativo legítimo e distribuí-lo como um novo app, assinado com seu próprio certificado. Por essa razão, a recomendação de segurança fundamental para usuários de Android é instalar aplicativos exclusivamente a partir da loja oficial, a Play Store.
É importante ressaltar que toda essa estrutura de segurança é válida para aparelhos em seu estado original (iPhone sem jailbreak e Android não rooteado). Realizar essas modificações quebra as barreiras de proteção do sistema, permitindo a instalação de qualquer software, inclusive os maliciosos.
Este princípio de verificação não é exclusivo dos sistemas mobile. O Windows, através do SmartScreen, alerta sobre aplicações não assinadas, e os repositórios do Linux utilizam chaves criptográficas para validar a autenticidade e a integridade dos pacotes, garantindo que a fonte é confiável.
Arquitetura de sistema (Visão Geral)
Toda aplicação de software, em sua essência, pode ser dividida em três componentes lógicos fundamentais:
- Interface: A camada com a qual o usuário interage.
- Lógica: Onde as regras, processamentos e cálculos são executados.
- Dados: A camada responsável pelo armazenamento e recuperação das informações.
A forma como esses componentes são organizados e se comunicam define a arquitetura do sistema.
Mainframe
Neste modelo totalmente centralizado, todos os três componentes (apresentação, lógica e dados) residem e são processados em um único servidor de grande porte, o Mainframe. Os usuários interagem com o sistema através de "terminais burros" (dumb terminals), que servem apenas para exibir informações e enviar comandos, sem capacidade de processamento local.
Stand Alone
É a arquitetura clássica dos softwares de desktop. Aqui, todos os componentes são instalados e executados na máquina do próprio usuário. Não há, por padrão, uma comunicação em rede para acessar uma camada de dados ou lógica externa. Exemplos incluem editores de texto ou planilhas em seu modo offline.
Cliente Servidor
Neste modelo, a camada de Dados é centralizada em um servidor de banco de dados. No entanto, as camadas de Apresentação e Lógica de Negócio são executadas na máquina do cliente.
Essa arquitetura está em grande parte obsoleta devido a uma falha de segurança fundamental: a aplicação cliente precisa se conectar diretamente ao banco de dados pela rede, o que significa que as credenciais de acesso ficam armazenadas na máquina do usuário. Um atacante poderia facilmente usar um sniffer de rede para capturar esses dados de autenticação ou, tendo acesso à máquina, extrair as credenciais e manipular o banco de dados diretamente.
Arquiteturas Modernas e Padrões Comuns
Arquitetura em 3 Camadas e N Camadas
A arquitetura de 3 Camadas é a base para a maioria dos sistemas modernos. Ela separa fisicamente os três componentes lógicos:
- Camada de Apresentação: Responsável pela interface do usuário (ex: um navegador web, um app mobile).
- Camada de Aplicação/Lógica: Um servidor onde as regras de negócio são processadas.
- Camada de Dados: Um servidor de banco de dados que armazena as informações.
A arquitetura em N Camadas é uma evolução deste modelo, permitindo a criação de camadas intermediárias adicionais para funções especializadas, como caching, filas de mensagens ou gateways de segurança.

-
N Camadas

-
Mobile
- WebApp que na verdade é verdade um app que por baixo roda no navegador. É uma casca somente. A maior parte é esse tipo de app.
- Nativos são os apps reais.
- Hibridos, sendo que algumas funções são tratadas de forma web
-
3 Camadas
Arquitetura Web
A arquitetura web é a implementação mais comum do modelo de 3 camadas. O fluxo funciona da seguinte forma:
- O navegador (Apresentação) envia uma requisição via protocolo HTTP/HTTPS.
- O Servidor de Aplicação (Lógica), rodando tecnologias como Java, C#, Python, Node.js, etc., recebe a requisição, processa as regras de negócio e interage com o banco de dados.
- O servidor então envia uma resposta de volta para o navegador, que a renderiza para o usuário.
Este modelo de comunicação é síncrono e conhecido como Request-Response. Estilos arquiteturais como o REST são amplamente utilizados para estruturar essa comunicação de forma padronizada.
Arquitetura Mobile
- Nativo: Aplicativos desenvolvidos especificamente para um sistema operacional (iOS ou Android), utilizando suas linguagens e ferramentas nativas. Oferecem a melhor performance e acesso total aos recursos do dispositivo.
- Web App: Na prática, é um site projetado para se parecer e se comportar como um aplicativo, rodando dentro do navegador do celular.
- Híbrido: Uma combinação dos dois mundos. Utiliza uma "casca" nativa (WebView) para rodar tecnologias web (HTML, CSS, JavaScript), mas consegue acessar algumas funcionalidades nativas do aparelho através de pontes (bridges).
Comunicação Assíncrona: Publish-Subscribe (Pub/Sub)
Em contraste com o modelo síncrono, o padrão Pub/Sub utiliza um intermediário, como uma fila de mensagens (message broker), para a comunicação.
- Um serviço ("Publisher") publica uma mensagem em um tópico, sem saber quem a receberá.
- Outros serviços ("Subscribers"), que têm interesse naquele tópico, recebem a mensagem e a processam em seu próprio tempo.
- Este modelo é assíncrono, desacoplando os serviços e sendo ideal para tarefas que não exigem uma resposta imediata.
Microserviços
A arquitetura de Microserviços estrutura uma aplicação como uma coleção de pequenos serviços independentes, cada um responsável por uma área de negócio específica. A comunicação entre esses serviços é um ponto crucial, e eles utilizam uma combinação de padrões:
Comunicação Síncrona (ex: APIs REST): Para comandos diretos que necessitam de uma resposta imediata.
Comunicação Assíncrona (ex: Pub/Sub): Para notificar outros serviços sobre eventos, garantindo desacoplamento e resiliência.