O Gatekeeper faz esta verificação automaticamente na primeira vez que abre uma aplicação transferida, e a maior parte das vezes nunca vê os pormenores — aparece uma janela, clica para avançar, pronto. Este laboratório é sobre ver o que o Gatekeeper viu: que programador assinou a aplicação, se essa assinatura está intacta, se o serviço de notarização da Apple a verificou, e o que ela tem permissão para fazer assim que corre. Todos os comandos aqui vêm com as ferramentas de linha de comandos do Xcode (xcode-select --install se ainda não as tiver), e todos são apenas de leitura — está a inspecionar, não a alterar, a aplicação.
A própria assinatura: codesign -dvvv
O codesign é a ferramenta da Apple para criar e inspecionar assinaturas de código. A opção -d mostra informação sobre o código assinado num caminho, e, segundo a sua página de manual, "Níveis crescentes de verbosidade produzem mais saída" — por isso -dvvv (display, três níveis de verbosidade) dá-lhe a imagem completa num único comando:
codesign -dvvv /Applications/Example.app
# example output, trimmed to the fields that matter
Executable=/Applications/Example.app/Contents/MacOS/Example
Identifier=com.example.app
Format=app bundle with Mach-O universal (x86_64 arm64)
CodeDirectory v=20500 size=... flags=0x10000(runtime) hashes=...
Signature size=4741
Authority=Developer ID Application: Example Software LLC (ABCDE12345)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Team Identifier=ABCDE12345
Runtime Version=14.0.0Quatro campos a ler sempre. Authority é a cadeia de certificados: uma aplicação externa normal deve terminar em Apple Root CA, passando por Developer ID Certification Authority, com a linha do topo a nomear o programador. Team Identifier é o identificador de dez caracteres da Apple para a conta do programador — o valor a comparar entre aplicações que acredita virem da mesma empresa, já que não muda entre os seus lançamentos. flags=0x10000(runtime) significa que o runtime reforçado está ativado, um conjunto de restrições adicionais (como resistir à injeção de código no processo) que a Apple exige para a notarização. E a ausência de qualquer linha Authority — apenas Signature=adhoc — significa que a aplicação não está assinada, ou está autoassinada sem nenhuma cadeia até à Apple.
A assinatura continua a corresponder aos ficheiros: --verify --deep --strict
Uma assinatura é uma promessa sobre um conjunto específico de bytes no momento da assinatura. --verify verifica se essa promessa ainda se mantém — segundo a página de manual, confirma "que o código nesses caminhos está assinado, que a assinatura é válida, e que todos os componentes selados não foram alterados." Duas opções extra importam para um pacote de aplicação, que é uma pasta cheia de recursos, frameworks e executáveis auxiliares aninhados, e não um único ficheiro:
codesign --verify --deep --strict --verbose=2 /Applications/Example.app
/Applications/Example.app: valid on disk
/Applications/Example.app: satisfies its Designated Requirement--deep importa porque, segundo a página de manual, a verificação de conteúdo aninhado está por defeito "limitada a uma investigação superficial que pode não detetar alterações ao código aninhado" — o modo profundo verifica recursivamente cada framework e ferramenta auxiliar incorporados, não apenas o pacote exterior. --strict acrescenta verificações extra que a Apple considera importantes o suficiente para não estarem ativas por defeito, incluindo que qualquer atalho (symlink) dentro do pacote "aponte para ficheiros selados dentro do seu próprio pacote", rejeitando um que aponte para fora da aplicação ou para algo não selado — um truque conhecido para contrabandear uma carga útil não assinada dentro de um pacote de resto legitimamente assinado. Se qualquer verificação falhar, verá code failed to satisfy specified code requirement, ou uma nota a identificar exatamente qual o item aninhado que não corresponde ao que foi originalmente selado — leia essa linha, ela identifica o ficheiro.
Ler os entitlements
Os entitlements são as permissões específicas que a assinatura de uma aplicação lhe concede — acesso à câmara, a capacidade de alcançar a rede fora da sandbox, desativar a validação de bibliotecas, e assim por diante. codesign -d --entitlements - extrai-os; segundo a página de manual, "Os dados de entitlement incorporados serão também extraídos e escritos" no caminho dado, e - significa saída padrão:
codesign -d --entitlements - /Applications/Example.app
# example output, trimmed
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>A maioria dos entitlements não é notável e corresponde ao que a aplicação obviamente precisa — uma aplicação de videochamada a pedir acesso à câmara não é um achado. O que vale a pena parar para observar é o disable-library-validation: significa que a aplicação vai carregar código de fora do seu próprio pacote assinado, o que é uma necessidade normal para algum software baseado em extensões e uma porta mais larga do que a maioria das aplicações precisa. É um pormenor a anotar, não um sinal de alerta automático, e é exatamente o tipo de pormenor que não consegue ver sem perguntar.
O serviço de notarização da Apple verificou-a de facto? spctl e stapler
Uma assinatura válida só prova que uma aplicação não foi alterada desde que um programador a assinou — nada diz sobre se a Apple a examinou. É isso que a notarização acrescenta. A própria documentação da Apple descreve o serviço automatizado de notarização como aquele que verifica "o seu software à procura de componentes maliciosos, confere problemas de assinatura de código, e devolve-lhe os resultados rapidamente." Quando passa, "o serviço de notarização gera um bilhete para agrafar (staple) ao seu software; o serviço de notarização também publica esse bilhete online, onde o Gatekeeper o pode encontrar."
spctl --assess é a forma prática de pedir o veredito ao próprio motor de políticas do Gatekeeper, em vez de o inferir sozinho. Segundo a sua página de manual, --assess "realiza uma avaliação sobre os ficheiros indicados," e -v / --verbose, repetido para mais detalhe, é descrito simplesmente como um pedido de "saída mais detalhada":
spctl --assess -vv /Applications/Example.app
/Applications/Example.app: accepted
source=Notarized Developer IDsource=Notarized Developer ID é o resultado que quer ver — significa que o Gatekeeper encontrou uma assinatura Developer ID válida e um bilhete de notarização, quer esse bilhete esteja agrafado à aplicação ou tenha sido encontrado online. Um resultado de source=Unnotarized Developer ID significa que a aplicação está assinada mas a Apple ainda não a notarizou, e um simples rejected significa que o Gatekeeper a bloquearia de arrancar na sua configuração por defeito.
Para verificar especificamente o agrafo, o xcrun stapler validate procura o bilhete fisicamente anexado à aplicação, em vez de pedir ao Gatekeeper que o procure online — útil para confirmar que uma aplicação continuará a ser avaliada corretamente sem nenhuma ligação à internet:
xcrun stapler validate /Applications/Example.app
Processing: /Applications/Example.app
The validate action worked!O sinalizador de quarentena: de onde vem a verificação da primeira execução
O guia de Segurança de Plataforma da Apple explica que "o Gatekeeper também acompanha a proveniência de ficheiros escritos por software transferido" e "pede a aprovação do utilizador antes de abrir software transferido pela primeira vez." O mecanismo por trás disso é um atributo estendido, com.apple.quarantine, que o Safari, o Mail e outras aplicações anexam automaticamente a tudo o que guardam a partir da rede. xattr -l lista-o, e, segundo a página de manual, esta opção "faz com que tanto os nomes dos atributos como os valores correspondentes sejam mostrados":
xattr -l ~/Downloads/Example.dmg
com.apple.quarantine: 0081;65e1a2b3;Safari;Nenhuma saída significa que o ficheiro não transporta nenhum sinalizador de quarentena — ou foi criado localmente, ou chegou por um caminho que não define o atributo (algumas ferramentas de arquivo e gestores de pacotes saltam-no), ou o sinalizador foi removido manualmente com xattr -d com.apple.quarantine. Esse último caso vale a pena conhecer por uma razão diferente: é uma forma documentada de as pessoas contornarem por completo a verificação da primeira execução do Gatekeeper, em ficheiros em que confiam ou julgam confiar, e vale a pena ser deliberado quanto a isso, em vez de colar instruções de terminal de uma fonte desconhecida.
Uma comparação trabalhada: duas aplicações que reclamam o mesmo programador
Uma forma concreta de usar tudo isto em conjunto: digamos que tem duas cópias de uma aplicação, ambas alegando vir da mesma empresa, uma do sítio do próprio programador e outra de uma ligação que alguém lhe enviou. Corra codesign -dvvv em ambas e compare a linha Team Identifier — é uma cadeia de dez caracteres associada a uma conta específica de Apple Developer e, ao contrário de um nome de exibição ou de um identificador de pacote, não é algo que um segundo agente consiga reproduzir casualmente sem acesso ao certificado de assinatura dessa conta. Se as duas cópias mostrarem Team Identifiers diferentes, não está a olhar para duas compilações da mesma aplicação; está a olhar para dois assinantes diferentes, um dos quais não é quem a transferência alegava ser. Siga isso com spctl --assess -vv na cópia suspeita — uma origem de notarização em falta ou incompatível na cópia que alega ser idêntica a um original notarizado é a confirmação, não apenas uma pista.
Ler o quadro completo, e os verdadeiros sinais de alerta
- Nenhuma cadeia
Authority, ou uma cadeia que não termina na Apple Root CA — a aplicação não tem nenhuma identidade de programador responsável por trás. codesign --verifyfalha, especialmente com uma mensagem a identificar um ficheiro aninhado específico — algo dentro do pacote mudou depois de assinado.spctl --assessdevolverejected, ou o Team Identifier emcodesign -dvvvnão corresponde ao programador que esperava para esse produto.- Um sinalizador de quarentena claramente removido de um ficheiro que não transferiu você mesmo, ou que chegou por um canal invulgar (um script, um anexo de e-mail com o nome alterado para parecer outra coisa).
- Entitlements totalmente abertos — acesso total ao disco, validação de bibliotecas desativada, acesso à rede sem restrições — numa aplicação cujo propósito declarado não precisa obviamente deles.
Nenhuma destas verificações olha para o que a aplicação faz de facto assim que está a correr e ligada à rede — essa é uma pergunta diferente, respondida vigiando o seu tráfego, e não a sua assinatura. Uma assinatura limpa e um bilhete de notarização válido são um patamar real e significativo: dizem que a Apple viu este conjunto exato de bytes e não encontrou problemas de assinatura de código no momento da verificação. São o início de confiar numa aplicação, não o fim.
O papel do FireAI e da HisnLabs
A clean signature and a stapled ticket say an app hasn’t been tampered with since Apple checked it — they say nothing about what it connects to afterward, which is the question FireAI’s per-app rules and on-device review are built to keep answering, signature by signature, connection by connection.
O FireAI é o produto da HisnLabs: uma firewall com IA que corre diretamente no seu Mac. Mostra, em linguagem clara, cada ligação que as suas aplicações fazem e deixa-o decidir o que sai do seu Mac — a IA funciona localmente, pelo que o seu tráfego nunca é enviado para nós nem para mais ninguém. A equipa de investigação em segurança da HisnLabs é quem mantém essas decisões fiáveis: cataloga que domínios são simples telemetria e quais são um serviço real, acompanha o país e a rede por detrás de uma ligação e treina o modelo local (a funcionalidade Autopilot) com padrões de tráfego reais, sem que nada disso saia do seu Mac.
Pode ler as decisões técnicas por detrás dele, ou experimentar o FireAI durante 17 dias, em FireAI, da HisnLabs.
