You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Feature request] Reject spoofed GPS positions and protect the RTC from spoofed GPS time #3733
GPS spoofing is common in parts of Europe (Ukraine, the Baltics) and the Middle East. MeshCore currently trusts any NMEA fix:
the position goes straight into telemetry/adverts, and
the GPS time is written to the RTC every 30 minutes (MicroNMEALocationProvider).
Real case on a solar repeater in Ukraine (ProMicro + PCF8563 RTC + serial GNSS):
shortly after boot the module reported a "fix" at -12.04, -77.06 (Lima, Peru) with 0 satellites in view a few seconds later;
the RTC was set to 10 March 2028 by a spoofed GPS time. Because time / clock sync only allow the clock to move forward, there was no CLI way to recover, and the node's adverts carried 2028 timestamps.
Proposal (opt-in, e.g. GPS_GUARD)
Position plausibility — accept a fix for node_lat/lon and telemetry only if:
satellites ≥ 4 and HDOP ≤ 4.0;
inside an optional build-time bounding box (region);
within an optional geofence around the configured node position (set lat/lon), e.g. 1 km for a fixed repeater;
no "impossible jump" from the last trusted fix (e.g. > 250 km/h);
N consecutive consistent fixes (e.g. 5 within 100 m).
Until then, no GPS position is reported.
Time guard — write GPS time to the RTC only if:
a trusted fix is current;
the time is not earlier than the firmware build date and not absurdly far ahead;
once the clock is valid, the correction stays within real clock drift (first sync ≤ 10 min, later ones ≤ 5 s + 100 ppm of elapsed time) — so a spoofer cannot walk the clock away in small steps.
Operator tools
an alert (status + telemetry channel) when a trusted fix keeps disagreeing with the clock by the same offset for an hour or more;
a way to set the clock backwards on purpose (time force <epoch>) and to accept the alerted GPS time.
The GNSS module reported a valid fix with 12 satellites — it would pass any satellite/HDOP check — but the position was outside the configured region (bounding box for Ukraine), so it was rejected. As a result:
no GPS position appeared in telemetry/adverts,
the GPS time was not written to the RTC (time sync requires a trusted fix),
the RTC stayed correct (checked against NTP-synced PC time).
Earlier the same evening this node received a genuine fix inside the region (6 sats) and accepted it together with a +1 s time correction, so the guard does not block normal operation.
This shows that satellite count / HDOP alone are not enough against spoofing — a spoofer produces a "perfect" fix. The region/geofence check is what caught it.
Activity
AlexandrTyshchenko commentedon Oct 29, 2026
Another real-world data point from the same node, running the guard from the linked implementation (2026-10-29, ~22:35 UTC):
The GNSS module reported a valid fix with 12 satellites — it would pass any satellite/HDOP check — but the position was outside the configured region (bounding box for Ukraine), so it was rejected. As a result:
Earlier the same evening this node received a genuine fix inside the region (6 sats) and accepted it together with a +1 s time correction, so the guard does not block normal operation.
This shows that satellite count / HDOP alone are not enough against spoofing — a spoofer produces a "perfect" fix. The region/geofence check is what caught it.
GPS guard: keep ',' and ':' out of sensor setting values