Geolocalização para devs: como evitar spoofing GPS em produção

Geolocalização para devs: como evitar spoofing GPS em produção

Em 2017, vários navios-tanque russos chegaram ao porto de Novorossiysk com um problema que parecia impossível: o GPS insistia que eles estavam pousando em um aeroporto. Os olhos dos marinheiros diziam uma coisa. O sistema de posicionamento global, outra. Essa história — que a BBC News resgatou — é só a ponta de um iceberg que todo desenvolvedor deveria conhecer. Porque quando você usa a API de geolocalização do navegador, entrega um recurso que pode mentir. E mentir de propósito.

GPS nasceu para matar — e hoje define onde você está

O Global Positioning System foi projetado pelo Departamento de Defesa dos EUA nos anos 70 para guiar mísseis balísticos e navegação militar. O primeiro satélite do programa Navstar foi lançado em 1978, e o sistema só ficou totalmente operacional em 1995. Até 2000, a chamada “Disponibilidade Seletiva” degradava intencionalmente o sinal civil para precisão de ~100 metros — qualquer um podia usar, mas ninguém com precisão útil.

O presidente Bill Clinton desligou essa degradação em maio de 2000. De um dia para o outro, a precisão civil saltou para ~3 a 15 metros. Foi o momento em que apps como Waze, Uber e Tinder se tornaram viáveis. Foi também o momento em que o mundo passou a confiar em uma infraestrutura que pertence a outro governo e pode ser desligada, manipulada ou falsificada a qualquer momento.

Na minha experiência construindo apps que dependem de localização, esse é o tipo de decisão arquitetural que devs junior ignoram e sênior internalizam: você está terceirizando a “verdade” sobre o mundo para um sistema que você não controla.

Como o GPS funciona de verdade — e por que isso importa no seu código

O truque é bonito e velho: trilateração. Cada satélite transmite um sinal com timestamp atômico. Seu receptor — pode ser um smartphone, um chip dedicado ou um módulo UART — calcula a distância para pelo menos 4 satélites a partir da diferença de tempo entre emissão e recepção. Com 4 distâncias, você resolve latitude, longitude, altitude e o erro do relógio local.

Três problemas técnicos que aparecem no dia a dia:

  • Multipath: o sinal rebate em prédios antes de chegar até você. Em São Paulo, no centro de uma avenida rodeada de espelhos de vidro, isso pode jogar a precisão para 50 metros ou mais.
  • Não é criptografado. O sinal GPS civil é aberto por design. Qualquer um com US$ 200 e um SDR (software-defined radio) consegue spoofar sua posição.
  • A posição tem geometria ruim dependendo da constelação visível. O DOP (Dilution of Precision) é informação que o navegador raramente te dá, mas influencia a confiabilidade real.

Segundo a BBC News, o caso dos navios russos foi um dos primeiros ataques de spoofing em larga escala documentados publicamente. Hoje isso virou commodity: existem até vídeos no YouTube mostrando como um laptop com hackrf one consegue enganar um Tesla.

Por que isso é problema seu, dev?

Se você já construiu qualquer coisa que use navigator.geolocation, Mapbox, Google Maps API ou CoreLocation, você está aceitando um input não-confiável como verdade absoluta. E isso aparece em três cenários clássicos:

  1. Antifraude: você libera um cupom só para quem está em determinada região. Um usuário malicioso falsifica o GPS e pega o cupom. Sua lógica de “está em São Paulo?” vira piada.
  2. Logística e entregas: o motorista do seu app reporta posição “no ponto de coleta”. Mas ele está em casa assistindo Netflix e gerou a coordenada com um app de spoofing.
  3. Geofencing em apps de saúde, jogos ou namoro: você desenha um raio de 500m ao redor de uma região. O spoofing permite que o usuário “esteja” em qualquer lugar do mapa sem mover um centímetro.

Não é teórico. É o tipo de bug que vira prejuízo real e chega na sua pager às 3h da manhã.

Na Prática: consumindo geolocalização sem cair em armadilha

Vamos ao código. O exemplo abaixo mostra o jeito correto de pedir geolocalização no navegador com tratamento de erro, timeout e fallback — coisa que 90% dos devs ignora:

// Detecta se o browser suporta a API
if (!('geolocation' in navigator)) {
  console.error('Geolocalização não disponível neste ambiente');
  // fallback: pedir CEP, IP geo, ou input manual
}

const options = {
  enableHighAccuracy: true, // tenta usar GPS em vez de Wi-Fi/IP
  timeout: 10000,           // 10s no máximo esperando fix
  maximumAge: 0             // não aceita cache, quer fix fresco
};

navigator.geolocation.getCurrentPosition(
  (pos) => {
    const { latitude, longitude, accuracy } = pos.coords;
    console.log(`Lat: ${latitude}, Lon: ${longitude}, ±${accuracy}m`);

    // accuracy vem em metros. > 100m é suspeito para uso sério.
    if (accuracy > 100) {
      console.warn('Fix com baixa precisão, considere não confiar');
    }
  },
  (err) => {
    // Códigos: 1 = permissão negada, 2 = posição indisponível, 3 = timeout
    if (err.code === 3) {
      console.warn('Timeout — usuário com GPS ruim ou spoof ativo');
    }
    // sempre tenha um plano B aqui
  },
  options
);

// Para tracking contínuo (ex: app de corrida), use watchPosition
const watchId = navigator.geolocation.watchPosition(
  (pos) => updateMap(pos),
  (err) => handleError(err),
  options
);

// E nunca esqueça de limpar
// navigator.geolocation.clearWatch(watchId);

Repare em três coisas que devs esquecem: maximumAge: 0 para não usar cache velho, timeout explícito para não travar a UI, e o tratamento de err.code === 3 que em produção aparece muito mais do que você imagina.

Erros comuns que vejo em produção

1. Confiar em latitude/longitude como verdade absoluta. Coordenadas são strings até você validá-las. Spoofers geram valores matemáticamente perfeitos. Cruzar com Wi-Fi, IP e sensores do dispositivo é obrigatório para antifraude sério.

2. Não diferenciar getCurrentPosition de watchPosition. O primeiro gasta bateria e tempo de CPU para um único fix. O segundo é o que você quer para tracking, mas cobra bateria caro. Testei isso em um app de delivery: trocar de um para o outro reduziu consumo em 40%.

3. Ignorar o fuso horário do usuário. Você pega a coordenada, ok. Mas converte para “horário local” usando Date.toLocaleString() e mostra a hora errada. Já peguei bug crítico em sistema de ponto eletrônico por causa disso.

4. Não lidar com HTTPS. Geolocalização só funciona em contextos seguros (HTTPS ou localhost). Em produção HTTP, a promise falha silenciosamente. Parece óbvio, mas vejo subir em produção toda semana.

5. Esquecer do iOS. O Safari pede permissão de novo toda vez que o usuário reinstala. E a Apple adicionou o Precise Location em iOS 14+: o usuário pode escolher compartilhar a cidade inteira em vez do ponto exato. Seu código precisa lidar com isso graciosamente, senão vira review de 1 estrela.

6. Tratar GPS como única fonte. Em ambientes fechados, GPS não pega. Apps robustos fazem fallback para Wi-Fi fingerprinting (Google, Apple e Mozilla oferecem APIs), IP geo, beacons BLE ou input manual. Quem depende só de GPS quebra no primeiro shopping center.

Além do GPS: o ecossistema de posicionamento em 2026

GPS americano não está sozinho. A Rússia opera o GLONASS, a Europa o Galileo (com sinal melhor para civil, e autenticado via OS-NMA, difícil de spoofar), a China o BeiDou e o Japão o QZSS. Smartphones modernos triangulam entre todas essas constelações — isso explica por que o fix é tão rápido hoje em dia comparado a 2010.

Para devs, isso significa duas coisas. Primeiro: seu módulo de geolocalização provavelmente já está usando múltiplas constelações, mesmo sem você pedir. Segundo: APIs como Galileo HAS (High Accuracy Service) e PPP (Precise Point Positioning) prometem precisão decimétrica sem estação base. Quando chegar ao consumidor final via browser e OS, vai abrir uma nova geração de apps — de AR realista a navegação autônoma confiável.

Por fim, e talvez o ponto mais importante: o pequeno ponto azul no mapa do seu celular não é você. É a estimativa de onde o sistema acredita que você está, com a precisão que ele admite ter e a confiabilidade que o seu código assumiu. Em 2017, navios inteiros descobriram isso no meio do Mar Negro. Não espere o mesmo no seu app.

FAQ — perguntas que devs realmente fazem

Qual a precisão real do GPS em smartphone hoje? Em céu aberto, 3 a 5 metros com GPS+GLONASS+Galileo. Dentro de prédios pode passar de 100 metros ou simplesmente falhar. Não confie em precisão melhor que ~10m sem validar.

Como detectar GPS spoofing no meu app? Combine fontes: se a coordenada GPS bate com a cidade do IP e as redes Wi-Fi visíveis, provavelmente é legítima. Se o GPS diz “Avenida Paulista” mas o IP vem de outro estado, desconfie. Apps sérios como o Google Maps usam Sensor Fusion — cruzam GPS, acelerômetro, giroscópio e Wi-Fi para detectar inconsistências.

Preciso pedir permissão toda vez no Android? Não. Use PermissionsAndroid.request() com ACCESS_FINE_LOCATION e ACCESS_COARSE_LOCATION. Lembre-se: no Android 10+, a permissão de background location precisa ser pedida em duas etapas — primeiro foreground, depois background.

Alternativas ao GPS puro para apps internos? Wi-Fi fingerprinting (API do Google Places ou serviços como Here), beacons BLE, UWB (Ultra-Wideband, presente em iPhone 11+ e Galaxy S21+), QR codes, NFC. Para apps de campus, hospital ou fábrica, beacons BLE costumam dar resultado melhor que GPS.

Por que meu app de delivery perde sinal em túnel? GPS é linha de visada com satélite. Em túnel, prédio ou garagem subterrânea, o sinal morre. Solução: usar sensores inerciais (acelerômetro + giroscópio) para dead reckoning durante o intervalo, e retomar GPS quando voltar à superfície. Apps como Strava e Citymapper fazem isso nativamente.

GPS vai ser desligado em algum momento? Tecnicamente sim — o governo dos EUA pode degradar ou desligar o sinal civil. Historicamente improvável pelo impacto econômico, mas é por isso que existem GLONASS, Galileo e BeiDou. O ecossistema moderno já é multi-constelação. Ainda assim, tenha plano B no seu código.

Gostou? Me segue no GitHub e deixa um comentário se tiver dúvida ou quiser aprofundar algum ponto. Se quiser que eu detalhe alguma das alternativas (Galileo HAS, UWB, BLE beacons) ou mostre a implementação completa de um detector de spoofing em JavaScript, é só pedir.

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.