AirTag stalking: como o Find My da Apple falha na arquitetura

AirTag stalking: como o Find My da Apple falha na arquitetura

Essa ação judicial contra a Apple expõe algo que poucos devs realmente entendem: sistemas anti-stalking baseados em detecção passiva são tragédias de UX esperando para acontecer. A mulher do Oregon sustenta que o iPhone nunca a alertou sobre um AirTag escondido no carro. Segundo o Sapo.pt, ela pede 75 mil dólares por negligência. Mas antes de julgar a Apple, vamos olhar o código invisível por trás desse tipo de proteção — porque quando você entender como o sistema foi projetado, vai perceber que o problema não é só “a Apple falhou”. É arquitetônico.

Como o AirTag realmente detecta stalking (e onde falha)

O Find My usa um protocolo de criptografia assimétrica rotativo. Cada AirTag gera uma chave privada SK_i durante a fabricação, e emite periodicamente um identificador BLE_ID_i derivado dessa chave. Quando um iPhone na vizinhança capta esse sinal, ele envia um relatório anônimo aos servidores da Apple contendo a localização atual, o horário e o BLE_ID_i criptografado.

O ponto crucial: o iPhone da vítima só recebe um alerta de “AirTag desconhecido” quando detecta que o mesmo BLE_ID está viajando com ela por um período prolongado. Segundo a própria Apple, esse intervalo pode chegar a horas. Não é em tempo real. E depende de três pré-condições que a mulher pode nunca ter atendido:

  • Bluetooth ativado.
  • Serviços de localização com precisão alta.
  • Notificações de rastreamento habilitadas em Ajustes > Privacidade > Localização > Notificações de rastreamento.
  • Modo de voo desligado.

Se um desses três estiver desativado — e honestamente, quantos devs mantêm tudo isso sempre ligado após algumas atualizações que “resetaram preferências”? — o sistema inteiro fica cego. Isso não é marketing: é a documentação oficial.

O que a Apple fez certo e onde tropeçou

Vou ser direto: a arquitetura do Find My é brilhante do ponto de vista de privacidade do dono do AirTag. O AirTag nem sabe onde está — ele emite beacon, e a rede constrói a localização. O agressor não precisa tocar na conta da vítima, e a vítima não vê dados do dono. Isso é criptografia ponta a ponta aplicada com elegância.

Mas o sistema falha miseravelmente na acessibilidade do alerta. Há três armadilhas reais que devs que constroem features de segurança precisam estudar:

  1. Notificação passiva vs. alerta ativo: a Apple usa notificação push, que compete com 50 outras no centro de notificações. Alertas críticos de segurança não deveriam ser apenas push — deveriam ter banners persistentes, haptics diferenciados, e exigir confirmação.
  2. Falta de auditoria proativa: o iPhone só verifica periodicamente. Não há um daemon checando continuamente. Bateria, performance, vida útil da bateria — tudo conspira contra o monitoramento constante.
  3. Configuração não-default: a notificação de rastreamento vem ativada por padrão, mas qualquer ajuste manual ou reset pode desativar. Sistemas críticos de segurança deveriam ser à prova de configuração.

Na Prática: detectando trackers desconhecidos via BLE

Quando construí um protótipo de auditoria para um cliente preocupado com BYOD corporativo, escrevi essencialmente isto em Swift para varrer periféricos BLE em background:

import CoreBluetooth
import CoreLocation

class StalkDetector: NSObject, CBCentralManagerDelegate {
    private var manager: CBCentralManager!
    private var seenTrackers: [String: (firstSeen: Date, lastSeen: Date)] = [:]
    private let STALK_THRESHOLD: TimeInterval = 30 * 60 // 30 minutos
    
    override init() {
        super.init()
        manager = CBCentralManager(delegate: self, queue: .global(qos: .userInitiated))
    }
    
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        guard central.state == .poweredOn else { return }
        // Filtra serviços BLE comuns de trackers conhecidos
        // AirTag usa identificador Apple Continuity (0x4C)
        let continuity: [CBUUID] = [CBUUID(string: "7DFC9000-7D1C-4951-868A-CC8F37EC07EB")]
        manager.scanForPeripherals(withServices: continuity,
                                   options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
    }
    
    func centralManager(_ central: CBCentralManager,
                        didDiscover peripheral: CBPeripheral,
                        advertisementData: [String : Any],
                        rssi RSSI: NSNumber) {
        let key = peripheral.identifier.uuidString
        let now = Date()
        
        if var seen = seenTrackers[key] {
            seen = (seen.firstSeen, now)
            seenTrackers[key] = seen
            
            // Heurística simples: tracker viajando muito tempo = suspeito
            if now.timeIntervalSince(seen.firstSeen) > STALK_THRESHOLD {
                triggerAlert(reason: "Tracker presente há mais de 30min")
            }
        } else {
            seenTrackers[key] = (now, now)
        }
    }
    
    private func triggerAlert(reason: String) {
        UNUserNotificationCenter.current().requestAuthorization { granted in
            DispatchQueue.main.async {
                let content = UNMutableNotificationContent()
                content.title = "⚠️ Possível stalkerware"
                content.body = reason
                content.sound = .defaultCritical
                
                let req = UNNotificationRequest(
                    identifier: UUID().uuidString,
                    content: content,
                    trigger: UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
                )
                UNUserNotificationCenter.current().add(req)
            }
        }
    }
}

Os erros mais comuns que devs cometem ao copiar isso: usar AllowDuplicatesKey: true pode drenar bateria; confiar só em UUID descarta spoofing; e você precisa pedir permissão de localização Always, não When in Use. Se implementar features anti-stalking em produção, trate isso com o mesmo rigor que trata autenticação.

Comparativo: o que concorrentes fazem melhor (e pior)

Solução Detecção automática Alerta proativo Custo Risco residual
Apple AirTag Sim (iOS/Android) Push demorado ~30 USD Alto se notificações desativadas
Tile Fraca Não ~25 USD Muito alto
Samsung SmartTag Só em Galaxy Push ~30 USD Médio (depende do ecossistema)
AirGuard (Android) Excelente Banner persistente Grátis Baixo
StalkerwareDetector.nl Local-only Não contínuo Grátis Variável

Repare: AirGuard (open-source) implementa banner persistente, que era exatamente o que faltava no caso da Jane Doe. A Apple poderia ter feito isso em 2022 e tem a prerrogativa técnica para tal. Não fez. Por quê? Hipótese minha: notificações críticas que interrompem o usuário têm impacto direto em métricas de engajamento. UX corporativo geralmente vence UX de segurança.

Erros comuns ao implementar proteção anti-stalking

Cuidados que vejo devs ignorarem toda semana:

  • Confiar só em push notifications. Push é relegado. Use Critical Alerts (requer entitlement da Apple) ou banners intrusivos.
  • Threshold temporal muito longo. 30 minutos parece razoável para dev, mas para a vítima pode ser tarde. Reduza para 10 quando possível.
  • Não diferenciar AirPods perdidos de AirTag. A Apple confunde seus próprios devices legítimos com ameaças. Feature flag mal desenhada.
  • Esquecer usuários Android. AirTag hoje detecta em Android via app Tracker Detect, mas como opt-in. Por padrão, ninguém está protegido.
  • Não logar eventos para auditoria. Se a vítima processar, ela vai precisar de logs forenses. Construa pensando em chain of custody.

Implicações para quem desenvolve apps de segurança

Esse caso tem três lições que todo dev senior deveria internalizar. Primeira: sistemas de segurança que dependem de configuração do usuário são, na prática, sistemas de segurança quebrados. Design defensivo significa assumir que o usuário não tocou em nada. Segunda: notificações precisam ter peso visual equivalente à criticidade. Notificação anti-stalking não pode coexistir pacificamente com “Sua pizza saiu para entrega”. Terceira: criptografia forte sem UX forte é teatro de privacidade.

Se você está construindo algo nessa área — IoT, smart home, wearables, seguros — pare agora e faça uma auditoria: “Se um atacante colocar meu dispositivo na mochila de alguém, aquela pessoa recebe um alerta inequívoco, persistente e impossível de ignorar?” Se a resposta é não, você tem um risco legal esperando para abrir.

FAQ

O iPhone tem mesmo um alerta nativo de AirTag?
Sim, desde o iOS 14.5 o sistema notifica quando detecta um AirTag viajando com você por tempo prolongado. Mas depende de Bluetooth, localização e notificações de rastreamento ativas.

Por que o alerta pode não aparecer?
Três causas comuns: Bluetooth desligado, Serviços de localização desativados, modo de voo ativo, ou notificações de rastreamento desabilitadas manualmente em Ajustes &emgt; Privacidade.

Existe alternativa open-source ao Find My da Apple?
Sim. AirGuard (Android, open-source) implementa detecção contínua com banners persistentes. OwnTracks e FindMyThings também fazem parte do ecossistema.

Como diferenciar AirTag de AirPods perdidos?
A Apple usa heurística baseada em comportamento: AirPods mudam de dono rapidamente (múltiplos pareamentos), enquanto AirTag suspeito tem padrão monotônico. Mas dev que for implementar isso: não confie só em MAC address, use RSSI e histograma temporal.

AirTag emite som?
Sim. Após 8 a 24 horas separado do dono, ele emite um beep curto. Mas o som é de 60 dB e pode ser abafado com fita, espuma ou posicionado em locais com ruído ambiente.

Gostou? Me segue no GitHub e deixa um comentário se quiser que eu aprofunde a implementação do detector BLE ou a parte de criptografia do Find My.

Y

Yuri Sousa

Front-End Developer / Designer

Desenvolvedor apaixonado por criar experiências digitais acessíveis e visualmente perfeitas. Escrevo sobre desenvolvimento web, design e tecnologia.