- Nº
- 18
- Tag
- Segurança
- Data
- Leitura
- 4 min
- Autor
- Arthur Dutra
Onde uma atualização ruim é barrada: integridade de atualizações para dispositivos offline e regulados
Um dispositivo sem internet ainda precisa receber atualizações, e cada uma é uma chance de rodar código que ninguém aprovou. Seis formas de uma atualização dar errado, uma em que ela dá certo, e a estação do caminho que barra cada falha. Um padrão genérico, não a implementação de nenhum fornecedor.
A maior parte das recomendações sobre segurança de atualizações assume que o dispositivo consegue falar com um servidor. Ele consulta, baixa um manifesto por TLS e confia no transporte para o resto. Tire a rede e esse modelo inteiro cai. A atualização continua precisando chegar, mas agora chega pela mão de pessoas que você não controla, até uma máquina que precisa decidir sozinha se o que recebeu é exatamente o que foi aprovado.
Dispositivos regulados deixam a pergunta mais afiada. Não basta a atualização vir do fornecedor. Ela precisa ser exatamente o build que um laboratório independente testou, para o mercado em que o dispositivo está licenciado, e nunca mais antiga do que a versão que já está rodando. Cada um desses pontos é uma verificação separada, e cada uma existe porque as outras podem ser satisfeitas por algo que ainda assim deveria ser recusado.
O explicador abaixo é o caminho que uma atualização percorre, do build até o momento em que vira o sistema em execução. Escolha um cenário e veja onde ele é pego.
Escolha o que acontece com uma atualização a caminho de um dispositivo offline e veja onde ela é pega.
Todas as verificações passam. A atualização só vira o sistema em execução depois de inicializar e provar que está saudável.
- Buildpassou
Build reproduzível a partir de código revisado.
- Assinaturapassou
Chave offline sob custódia dividida.
- Certificaçãopassou
Um laboratório independente certifica os hashes exatos.
- Distribuiçãopassou
Operadores levam até dispositivos sem internet.
- Verificação no dispositivopassou
Assinatura, hash certificado, versão, mercado.
- assinatura: passou
- hash certificado: passou
- versão: passou
- mercado: passou
- Instalação no slot Bpassou
Gravada no slot inativo enquanto o A segue rodando.
- Health checkpassou
O B inicializa e precisa provar que está saudável.
- Commitpassou
O B passa a ser o ativo e o A fica como reserva.
Todos os cenários de uma vez
| Cenário | Barrada em | Resultado |
|---|---|---|
| Atualização válida | passa por tudo | Instalada |
| Alterada no caminho | Verificação no dispositivo (assinatura) | Rejeitada antes da instalação |
| Versão antiga | Verificação no dispositivo (versão) | Rejeitada antes da instalação |
| Rebuild de um byte | Verificação no dispositivo (hash certificado) | Rejeitada antes da instalação |
| Mercado errado | Verificação no dispositivo (mercado) | Rejeitada antes da instalação |
| Queda de energia | Instalação no slot B | Interrompida, nova tentativa depois |
| Falha no health check | Health check | Revertida |
Assinar é necessário, mas não suficiente
O cenário que separa um projeto sério de uma caixinha marcada é o rebuild de um byte. Alguém com acesso à chave de assinatura, ou a um pipeline que a usa, gera um binário que difere do certificado em um único byte. A assinatura está perfeita. Um dispositivo que só verifica assinaturas instala.
O que barra é o segundo fato, independente: o hash dos bytes exatos que o laboratório certificou. O dispositivo carrega essa lista, assinada pelo laboratório e não pelo fornecedor, e recusa qualquer coisa que não esteja nela. A chave do fornecedor diz quem construiu. O hash certificado diz que este build específico é o que foi examinado. Você precisa dos dois, nas mãos de partes diferentes, ou um único comprometimento basta.
O anti-rollback fecha a porta mais antiga
Uma versão anterior é, por definição, uma versão com problemas conhecidos que foram corrigidos depois. E ela tem assinatura válida, porque foi um lançamento de verdade. Sem uma regra de versão mínima, quem consegue entregar um arquivo ao dispositivo não precisa forjar nada. Basta reinstalar o bug do ano passado. O dispositivo precisa lembrar a maior versão que já aceitou e recusar qualquer coisa abaixo dela.
Vínculo com o mercado
O mesmo build pode estar certificado para uma jurisdição e não para outra. Vincular cada pacote aprovado aos mercados em que ele é permitido transforma essa regra de obrigação burocrática em algo que o próprio dispositivo aplica. Uma atualização válida e certificada para o mercado errado é rejeitada exatamente como uma adulterada.
Dois slots, para a falha ser entediante
Nenhuma das verificações acima ajuda se a própria instalação pode deixar o dispositivo pela metade. A atualização vai para um slot inativo enquanto o sistema atual segue rodando intacto. A energia pode cair a qualquer momento e o dispositivo simplesmente inicializa o que já tinha. Depois que o novo slot inicializa, ele precisa provar que está saudável antes de virar o padrão; se não conseguir, o boot loader volta sozinho. Ninguém precisa ir até a máquina.
O que isso não cobre
Uma chave do fornecedor roubada, sozinha, é pega: o rebuild acima é exatamente esse caso. O que passa é um build malicioso que chega ao laboratório e é certificado mesmo assim, ou uma chave do fornecedor roubada junto com o controle da chave do laboratório. Esses casos são tratados antes: chaves offline sob custódia dividida, builds reproduzíveis que permitem a uma segunda parte recompilar e comparar, e uma lista certificada assinada pelo laboratório, para que nenhuma organização sozinha aprove os próprios bytes.
Toda verificação deste caminho também roda uma única vez, antes da instalação. Quem consegue gravar o disco diretamente nunca passa por elas. Esse é o trabalho do verified boot: o boot loader confere cada slot a cada inicialização contra uma chave ancorada na raiz de confiança do hardware. É uma camada separada, e este explicador não a desenha.
O sentido de desenhar o caminho é que cada estação responde a uma pergunta diferente, e cada cenário acima é um que uma única verificação, por mais esperta, teria deixado passar.