◇ OpenCyber Academy
Graduação · Capítulo 3 · Português

Capítulo 3 — 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.

Capítulo 3 — Programação I

Mapa da aula

Aula 03 publicada. Mapa, exemplo, EX007.

flowchart TD
  N0["3.1 Por que a programação importa para a segurança d"]
  N1["3.2 Construções básicas"]
  N2["3.3 Tratamento seguro de entradas"]
  N3["3.4 Testes"]
  N4["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4
  N4 --> EX["Exemplo resolvido"]
  EX --> Q["Exercício EX007"]

Desenho lógico

flowchart LR
  N0["3.1 Por que a programação importa para a segurança d"]
  N1["3.2 Construções básicas"]
  N2["3.3 Tratamento seguro de entradas"]
  N3["3.4 Testes"]
  N4["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX007"]
[3.1 Por que a programação importa para a segurança d]
    |
    v
[3.2 Construções básicas]
    |
    v
[3.3 Tratamento seguro de entradas]
    |
    v
[3.4 Testes]
    |
    v
[Síntese]
    |
    v
[Exemplo resolvido] --> [Exercício EX007]

Objetivos de aprendizagem

Você vai (1) escrever programas simples em Python com variáveis, condições, laços, funções e listas; (2) ler os laboratórios deste livro; (3) tratar entradas com segurança; e (4) testar funções pequenas.

3.1 Por que a programação importa para a segurança de IA

O trabalho de segurança precisa de evidências, e as evidências vêm de executar coisas: avaliar um modelo num conjunto de teste, analisar logs, verificar arquivos. Mesmo programas curtos deixam você mais rápido e mais preciso. Os laboratórios deste livro usam apenas a biblioteca padrão do Python, para rodar em qualquer computador. O primeiro script útil de Rina mediu com que frequência as respostas de teste do Ask Lumen citavam um documento das clínicas, uma verificação que levaria horas à mão. Escrevê-lo também a obrigou a definir o que contava como citação, uma pergunta mais precisa do que aquela com que havia começado. Laboratórios só com a biblioteca padrão evitam problemas de dependências, de modo que um colega pode reexecutar o trabalho dela e obter os mesmos números.

3.2 Construções básicas

Variáveis guardam valores; if escolhe; for repete; funções empacotam passos; listas e dicionários guardam coleções. Leia o laboratório de evasão abaixo: ele cria dados sintéticos, treina com um laço um pequeno modelo de regressão logística e depois mede a acurácia à medida que uma perturbação cresce. Você ainda não precisa entender cada linha — concentre-se na estrutura: dados, treinamento, avaliação, impressão.

"""Lab E: evasion of a toy linear classifier (synthetic data, stdlib only).
Trains logistic regression on two synthetic clusters, then applies a
fast-gradient-sign (FGSM-style) perturbation of size eps to every test point
and reports clean vs adversarial accuracy. Teaching model only."""
import math, random
rng = random.Random(7)
def point(label):
    cx = 1.0 if label else -1.0
    return [rng.gauss(cx, 0.7), rng.gauss(cx, 0.7)], label
train = [point(i % 2) for i in range(400)]
test = [point(i % 2) for i in range(200)]
w, b = [0.0, 0.0], 0.0
sig = lambda z: 1 / (1 + math.exp(-z))
for epoch in range(200):
    gw, gb = [0.0, 0.0], 0.0
    for x, y in train:
        p = sig(w[0]*x[0] + w[1]*x[1] + b)
        gw[0] += (p - y)*x[0]; gw[1] += (p - y)*x[1]; gb += p - y
    w = [w[i] - 0.1*gw[i]/len(train) for i in range(2)]; b -= 0.1*gb/len(train)
def acc(data, eps):
    ok = 0
    for x, y in data:
        # gradient of the loss w.r.t. x is (p - y) * w; FGSM steps along its sign
        p = sig(w[0]*x[0] + w[1]*x[1] + b)
        xa = [x[i] + eps*math.copysign(1, (p - y)*w[i]) for i in range(2)]
        ok += (sig(w[0]*xa[0] + w[1]*xa[1] + b) >= 0.5) == bool(y)
    return ok / len(data)
print(f"weights w=({w[0]:.3f}, {w[1]:.3f}) b={b:.3f}")
for eps in (0.0, 0.25, 0.5, 0.75, 1.0):
    print(f"eps={eps:.2f} accuracy={acc(test, eps):.3f}")

Saída esperada:

weights w=(1.795, 1.756) b=-0.080
eps=0.00 accuracy=0.985
eps=0.25 accuracy=0.950
eps=0.50 accuracy=0.840
eps=0.75 accuracy=0.660
eps=1.00 accuracy=0.505

A saída mostra o padrão com clareza: a acurácia é 0.985 sem perturbação e cai para 0.505 quando eps chega a um, perto de um palpite ao acaso. A semente aleatória fixa faz toda execução imprimir os mesmos números.

3.3 Tratamento seguro de entradas

Programas que leem arquivos, dados de rede ou saídas de IA devem tratá-los como não confiáveis. Converta texto em números com cuidado, verifique intervalos e nunca execute texto como código. Um erro comum em aplicações com LLM é passar a saída do modelo para um comando ou uma página web sem verificações; o OWASP LLM 2025 chama isso de tratamento inadequado de saídas (LLM05). No Ask Lumen, a marcação sugerida pelo modelo é uma entrada como qualquer outra: precisa ser analisada como dado, verificada contra regras e só então passada ao sistema de agendamento. O exemplo resolvido deste capítulo faz exatamente isso, com três verificações sobre o código da clínica, a data e o identificador do paciente.

3.4 Testes

Escreva testes pequenos com assert: assert classify(0.9) == "high". Teste casos-limite — entrada vazia, valores extremos, tipos errados. Testes tornam seguro alterar o código depois. Na verificação de marcações de Rina, os casos-limite incluem uma data exatamente 90 dias à frente, uma data no passado, um código de clínica desconhecido, um identificador de paciente ausente e um pedido com o identificador de outro paciente. Cada caso recebe um teste com o resultado esperado escrito ao lado. Quando ela mais tarde muda a regra de datas, os testes existentes mostram na hora se algo mais quebrou.

3.5 Exemplo resolvido (caso sintético da LCH)

Rina escreveu uma função que verifica um pedido de marcação produzido pelo Ask Lumen antes que ele chegue ao sistema de agendamento: o código da clínica deve ser um dos cinco códigos conhecidos, a data deve estar dentro de 90 dias e o identificador do paciente deve corresponder ao usuário conectado. Seus testes incluíram um pedido com o identificador de outro paciente, que a função rejeitou. Verificar em código, fora do modelo, significa que a regra vale mesmo que um prompt convença o modelo a pedir a marcação de outro paciente.

3.6 Erros e limites

Três erros são comuns: copiar código sem entender o que ele faz; confiar na saída da IA como se fosse o seu próprio código; e testar apenas o caso normal. Código copiado pode incluir comportamentos que quem copiou nunca notou, como uma chamada insegura que executa texto como comando. Confiar na saída da IA como se fosse o seu próprio código repete esse erro com um autor menos cuidadoso. Testar apenas o caso normal deixa sem teste exatamente os caminhos que um atacante usa; o teste de Rina com o identificador de outro paciente é o tipo que pega problemas reais.

Exercícios

Síntese

A programação transforma ideias de segurança em evidências. Leia os laboratórios pela estrutura, trate toda entrada externa — inclusive a saída da IA — como não confiável e teste os limites.

Continue estudando — capítulo 03 de 40

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