OpenCyber Academy
Engenharia · Capítulo 4 · Português
Código do curso: OCA-133Capítulo 04: OCA-133-C004

Capítulo 4 — Programação I

Ensino gratuito e aberto para quem deseja proteger pessoas e tecnologias. Não é preciso criar uma conta para estudar ou consultar as respostas.

Mapa da aula

Aula 04 publicada. Mapa, exemplo, EX010.

flowchart TD
  N0["4.1 Registros como dicionários"]
  N1["4.2 Funções puras primeiro"]
  N2["4.3 Texto desarmado"]
  N3["4.4 Testes"]
  N4["4.5 O que não programar"]
  N5["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5
  N5 --> EX["Exemplo resolvido"]
  EX --> Q["Exercício EX010"]

Desenho lógico

flowchart LR
  N0["4.1 Registros como dicionários"]
  N1["4.2 Funções puras primeiro"]
  N2["4.3 Texto desarmado"]
  N3["4.4 Testes"]
  N4["4.5 O que não programar"]
  N5["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> Q["EX010"]
[4.1 Registros como dicionários]
    |
    v
[4.2 Funções puras primeiro]
    |
    v
[4.3 Texto desarmado]
    |
    v
[4.4 Testes]
    |
    v
[4.5 O que não programar]
    |
    v
[Síntese]
    |
    v
[Exemplo resolvido] --> [Exercício EX010]

Objetivos de aprendizagem

Você vai (1) escrever funções pequenas e puras que transformam registros de inteligência; (2) usar os tipos da biblioteca padrão para strings, conjuntos e dicionários; (3) testar funções contra entradas conhecidas; (4) recusar-se a escrever código de coleta que viole termos de uso ou a privacidade.

4.1 Registros como dicionários

Um indicador já interpretado é naturalmente um dicionário: {"type": "domain", "value": "c2.example", "source": "partner-A", "tlp": "TLP:GREEN"}. Funções que recebem um registro e devolvem um novo são fáceis de testar e de compor. O dicionário mantém cada campo nomeado, então o código fica legível e campos ausentes podem ser verificados. As funções de Kofi nunca alteram o registro que recebem; elas devolvem um novo, o que significa que uma versão anterior continua disponível se uma etapa posterior der errado. Um registro sem fonte ou sem rótulo TLP é rejeitado nesta etapa, em vez de armazenado sem eles.

4.2 Funções puras primeiro

Uma função pura não tem efeitos colaterais: dada a mesma entrada, devolve a mesma saída e não escreve nada. Normalizar um domínio para minúsculas é puro. Gravar no banco de dados não é. Mantenha as partes puras separadas, para que a maior parte do código possa ser testada sem infraestrutura. O parser de Kofi segue essa divisão. As funções que limpam e validam um registro são puras e têm dezenas de testes rápidos. Uma camada externa fina lê do feed e grava no repositório, e essa camada é testada com menos frequência, contra um banco de dados de teste. Quando aparece um bug, os testes puros costumam localizá-lo em segundos.

4.3 Texto desarmado

Relatórios muitas vezes "desarmam" (defang) indicadores — hxxp, [.] — para que ninguém clique neles. Um parser deve rearmá-los apenas dentro da plataforma, nunca em saídas que pessoas vão colar em navegadores. O Lantern armazena a forma normal e exibe a forma desarmada nos relatórios. As duas formas nunca podem ser confundidas. Se um relatório mostra um link ativo e um analista clica nele, o clique pode chegar à infraestrutura do atacante, o que o limite ético do livro proíbe. A função de exibição de Kofi desarma todo domínio e endereço, e um teste falha se qualquer saída de relatório contiver um esquema funcional.

4.4 Testes

Para cada função, escreva três casos de resposta conhecida: um valor normal, um caso-limite e uma entrada malformada. A entrada malformada deve produzir um erro explícito ou uma marca de rejeição, nunca um valor adivinhado. Para uma função que normaliza um domínio, o caso normal pode ser um nome com maiúsculas e minúsculas misturadas que deve voltar em minúsculas. O caso-limite pode ser um nome com um ponto final, e o caso malformado, uma string com um espaço no meio. Escrever esses três testes antes da própria função muitas vezes revela o que ela deve fazer quando a entrada é estranha, que é onde os feeds reais causam problemas.

4.5 O que não programar

Às vezes os estudantes perguntam como raspar uma plataforma social em busca de dados pessoais de agentes de ameaça. O código do Lantern coleta apenas de fontes cujos termos o permitem, e apenas os campos necessários. Coleta automatizada que burla limites de taxa, logins ou termos está fora do escopo. A regra protege as pessoas tanto quanto a BEN. Os dados pessoais de um suposto agente podem pertencer a alguém sem envolvimento, e reuni-los pode violar a legislação de privacidade e os termos das plataformas. As fontes do Lantern são listadas com os termos que permitem seu uso, e acrescentar uma nova fonte exige a aprovação do líder de CTI antes que qualquer código seja escrito. As revisões de código de Kofi conferem essa lista.

Exemplo resolvido

Kofi escreve refang(s), que substitui hxxp e [.]. Seus testes: "hxxp://a[.]example" → "http://a.example"; "a.example" inalterado; "" → rejeitado. A versão de um colega devolvia uma string vazia para entrada vazia; a de Kofi a rejeita, para que valores vazios nunca virem indicadores armazenados.

Caso sintético. A função e os testes de Kofi são inventados.

Erros e limites

Trechos de parsing copiados e colados podem conter chamadas de rede; leia-os. Strings rearmadas em relatórios convidam a cliques acidentais.

Exercícios

Síntese

Funções pequenas e puras, rejeição explícita, saídas desarmadas e código de coleta que respeita os termos de uso.

Continue estudando — capítulo 04 de 50

← Capítulo 03 (rascunho) · Índice de capítulos do curso · Capítulo 05 (rascunho) →

Respostas comentadas

EX010. Não. Gravar em um arquivo de log é um efeito colateral, então a função não é pura; separe a normalização do log.

EX011. Os valores rearmados são usados dentro do parsing e do armazenamento do Lantern; relatórios e mensagens mostrados a pessoas mantêm a forma desarmada.

EX012. Uma rejeição (erro ou marca), porque uma string vazia nunca pode ser armazenada como indicador.