Há muitos erros arquitetônicos e de design básicos que podem comprometer a segurança de um sistema:
- Falta algo importante em recursos de segurança, como requisitos de auditoria, privacidade e conformidade de controle de acesso;
- Erros técnicos na compreensão e implementação de defesa se segurança contra as “artes do mal”, como criptografia, gerenciamento de segredos e gerenciamento de sessão (você não sabe o suficiente para fazer algo ou para fazê-lo direito);
- Incompreensão de responsabilidades arquitetônicas e zonas de confiança, como contar com a validação do lado do cliente ou “Eu pensei que os dados já tinham sido higienizados”;
- Deixar a superfície de ataque maior do que tem que ser – porque a maioria dos desenvolvedores não entende o que é superfície de ataque de um sistema ou sabe que precisa estar atenta quando mudá-la;
- Permitir acesso por padrão, então quando acontece um erro ou alguém se esquece de adicionar a verificação certa no lugar certo, as portas e as janelas são deixadas abertas, e os bandidos podem entrar;
- Escolher uma plataforma de desenvolvimento inseguro ou uma pilha de tecnologia, ou um framework, ou uma API, e herdar o design e os erros de codificação de alguém;
- Cometer erros estúpidos em fluxos de trabalho de negócios que permitem que os atacantes ignorem as verificações e os limites, e roubem dinheiro ou informações .
Aprendendo sobre design de software seguro
Se você quer construir um sistema seguro, você precisa entender de design seguro. Espero que você não comece lendo Secure Software Design, de Richardson e Thies. Enquanto o livro descreve muitas das principais questões em segurança de aplicações de segurança e TI em geral, e algumas ameaças e vulnerabilidades comuns, ele (ironicamente , dado o título ) não explica como fazer design de software seguro. E muito da “informação prática” no livro é no mínimo perigosa, mas não totalmente correta: a seção sobre XSS, por exemplo, que menciona o escape da saída, não explica como fazê-la corretamente, ou que é muito mais importante que ficar limpando a entrada, removendo caracteres desnecessários ou alterando caracteres necessários, mas possivelmente perigosos” (no entanto, você iria fazer isso de forma segura). Ou o principalmente errado: a seção de design de banco de dados seguro – não, “Uma das maneiras mais simples de proteger uma aplicação web de um ataque de injeção de SQL é validar todos os parâmetros de entrada” não é correto, e “Você também deve evitar a dinâmica SQL e usar procedimentos parametrizados armazenados” não está perto o suficiente de ser correto para ser compreendido ou seguido corretamente. O livro faz aumentar a conscientização sobre as questões de segurança de aplicativos e, logo no início, os autores apontam os leitores para CERT , SANS e OWASP, então não há esperança de que os alunos vão encontrar e utilizar esses recursos em vez de confiar nesse livro.
Princípios – o que realmente importa
Cada livro que leva a design de software seguro, mesmo um bom livro como Secure and Resilient Software Development, de Merkow e Raghavan, passa o tempo falando sobre princípios básicos de design de software seguro: a importância de C e I e talvez A. Modularidade e compartimentalização, separação de responsabilidades, a economia de mecanismo (uma forma nada simples de dizer simplicidade), menos privilégio, defesa em profundidade, mas não de segurança através da obscuridade, mediação completa e aceitabilidade psicológica, e tudo o mais que Saltzer e Schroeder escreveram há 40 anos.
Todas são ideias boas, verdadeiras e sábias as quais dá para seguir , mas você pode ler essas coisas todos os dias (se conseguir ficar acordado), e elas não vão ajudá-lo a projetar um sistema mais seguro. Não há nada claro ou acionável aqui – está pregando um aceno de mão de alto nível . Você não pode dizer ter feito o suficiente, nunca vai saber se deu certo ou o que você perdeu, ou o que é realmente importante e o que não é.
Ameaças, ataques e riscos – Aprender a ter medo de algo…
O resto do design de software seguro se refere principalmente a ameaças, ataques e exploits – exercícios de modelagem de ameaças focados em risco. Desenvolvedores projetam algo agradável e, em seguida, um especialista em segurança chega e ataca sua concepção, procura fraquezas e omissões, enumera ameaças e caminha através das árvores de ataque e vulnerabilidades, e diz aos desenvolvedores onde um atacante teórico pode ser capaz de tirar vantagem e comprometer o sistema.
Isso é uma coisa difícil para os desenvolvedores entenderem e difícil para eles ficarem animados: você está pedindo para desenvolvedores – solucionadores de problemas concretos – pensarem sobre os problemas que irão “provavelmente nunca” acontecer. E para fazer isso corretamente é necessário que você não só entenda como funciona o sistema (e a tecnologia sobre a qual funciona), mas também quais são os tipos possíveis de ataques em quais contextos, o que significa que você precisa de experiência e conhecimento especializados, que a maioria dos desenvolvedores não tem e não pode obter facilmente.
Mas mesmo se você souber essas coisas e seguir uma abordagem estruturada,como STRIDE ou Trike, não há nenhuma maneira de saber se você fez um bom trabalho de modelagem de ameaças, se você fez o suficiente, e se já identificou todos os problemas importantes, ou se você perdeu algum vetor de ataque importante ou vulnerabilidade crítica e se vai ser pwned (derrotado) de qualquer maneira.
Modelagem de ameaças, pelo menos da forma como é comumente entendida, com reuniões caras nas quais arquitetos, desenvolvedores, testadores, especialistas em segurança e gerentes de projeto se reúnem para falar metodicamente sobre documentos de projeto e então escreverem a papelada CYA depois, não se encaixa com a forma como a maioria dos desenvolvedores realmente trabalha – especialmente os desenvolvedores em equipes Agile que fazem a maior parte do trabalho de design de forma incremental e iterativa, constantemente se aperfeiçoando à medida que o trabalho se desenvolve. Ou desenvolvedores mantendo sistemas legados sob constante pressão para corrigir ou mudar algo que já está o mais rápido e barato que puderem. Não há tempo ou espaço para caber em reuniões de modelagem de ameaças ou toda a documentação e papelada, e provavelmente não é o melhor uso do tempo, se pudessem encontrar algum.
Mesmo modelagem de ameaças mais leves não faz mais do que uma incursão em lojas de desenvolvimento, e eu não estou convencido de que isso acontecerá.
Lista de verificação de design seguro, colas e padrões
Quando os desenvolvedores estão projetando e construindo um sistema, eles querem olhar para a frente: compreender o problema que estão tentando resolver e o que eles precisam para construir e como eles podem construí-lo rapidamente. Em vez de olhar para trás, para o que perderam ou fizeram de errado, é mais valioso, prático e de baixo custo se concentrarem no que podem e devem fazer antecipadamente, como parte do projeto – as práticas, os padrões e as ferramentas que eles devem usar e o que eles não devem, os problemas para os quais têm que olhar quando eles estão tomando decisões de design e trade-offs.
Eu já falei antes o quão importantes e úteis checklists podem ser em segurança de software: passos simples e coisas para pensar quando se trabalha em diferentes problemas de projeto, para se certificar de que você não está perdendo alguma coisa importante ou fazendo algo estúpido.
O site Padrões e Práticas, da Microsoft, inclui uma (infelizmente “aposentada”) lista de verificação de arquitetura e design de segurança que cobre a maior parte das coisas que você precisa pensar ao projetar um aplicativo seguro. No caso de essa lista desaparecer em alguns dias, uma cópia completa disso está incluída no livro de Merkow e Raghavan em Secure and Resilient Software Development.
OWASP tem uma lista de verificação de design software seguro, mas não é voltada para desenvolvedores – é uma ferramenta para ajudar um auditor a fazer reviews de design de segurança em um ambiente de documentação pesada. Há uma OWASP Application Architecture Cheat Sheet (atualmente em fase de projeto ), que inclui algumas boas perguntas a serem feitas na arquitetura inicial e design de alto nível. O resto das OWASP Cheat Sheets pode ser usado para ajudar designers e programadores com problemas de segurança de aplicativos específicos – desde que você saiba quais problemas que você precisa resolver.
Também houve algum trabalho sobre padrões de segurança, que poderia ser útil para os desenvolvedores que têm uma abordagem baseada em padrões de design de software. O catálogo padrão de design seguro do SEI é uma tentativa de incluir segurança em alguns padrões de design de software comuns (versões seguras de Factory, Strategy, Builder, Chain of Responsibility…), ou para aplicar padrões para alguns problemas comuns de segurança de software. E há um par de livros como Core Security Patterns (uma lista intimidante de mais de mil páginas de padrões de segurança para apps J2EE baseados em padrões) e Security Patterns in Practice. No entanto, esses padrões não fazem isso para o mainstream – eu não conheço muitos desenvolvedores da vida real que estão mesmo cientes desses padrões, então nem tente aplicá-los.
Uma das ferramentas mais úteis que eu vi no espaço de design seguro é SD Elements, um serviço de software online que ajuda equipes de desenvolvimento a tomar decisões de segurança na aplicação. Você começa por descrevendo seu projeto, seus requisitos de segurança, de compliance e a linguagem(s)/plataforma que você está usando, e o SD Elements orienta você através de um conjunto de perguntas e opções sobre como lidar com os importantes aspectos de segurança do projeto, implementação e testes do sistema. Ele ajuda você a entender as decisões que você precisa tomar.
Segurança em design, design não seguro
Design seguro não deve ser sobre coisas que você não entende ou sobre as quais não pode fazer nada a respeito. Design seguro deve ser sobre a compreensão dos problemas com os quais você pode e deve tomar cuidado, e aqueles que não deve.
Entender a aparência da superfície de ataque do seu sistema e o que procurar quando você alterá-la.
Como zonas de confiança trabalham.
Onde, por que e como você deve usar frameworks de segurança de aplicativos comprovados e bibliotecas como Shiro ou ESAPI, ou como aproveitar adequadamente os recursos do seu framework de aplicações de segurança (Rails, Play ou Spring, entre outros).
O primeiro passo – e o mais importante – é fazer com que os designers e arquitetos de software pensem em segurança quando eles estiverem pensando em design, da mesma forma que eles pensam sobre o time-to-market e desenvolvem conveniência, ou o desempenho, ou a confiabilidade, ou a futura prova ou elegância técnica. Não apenas os recursos de segurança devem ter histórias, mas a segurança como uma thread contínua em arquitetura e design.
Quando eles selecionam as ferramentas, as linguagens, os frameworks e as plataformas.
Quando eles pensam sobre as responsabilidades arquitetônicas, camadas e padrões.
E quando eles trabalham com dados : identificação, detecção e proteção de informações confidenciais e privadas e segredos, tendo o cuidado de validar os dados corretamente, e pensar sobre o acesso aos dados seguros e armazenamento de dados.
Design de software seguro tem que se encaixar no projeto e em como o design é feito. Tem que ser parte das decisões de como as decisões de projeto estão sendo tomadas, não ser acrescentado depois de auditorias e revisões.
***
Artigo traduzido pela Redação iMasters, com autorização do autor. Publicado originalmente em http://swreflections.blogspot.com.br/2013/06/what-is-important-in-secure-software.html