Summary
The wpasec_kquery function unconditionally transmits BSSID and SSID fingerprints of scanned Wi-Fi networks to the third-party service wpa-sec.stanev.org on every nearby-device scan request. This exfiltration is silent, undisclosed to users, and has no opt-out mechanism, rate limiting, or request timeout.
Evidence
app-env.py lines 84–118:
def wpasec_kquery(bssid, ssid):
url = f"https://wpa-sec.stanev.org/?api&wpas_get={bssid}"
headers = {"Cookie": f"key={WPASEC_KEY}"}
try:
response = requests.get(url, headers=headers, timeout=None) # no timeout
...
Called unconditionally from the nearby-scan handler for every BSSID in the response. No user consent prompt, no privacy notice, no configuration toggle to disable the lookup. WPASEC_KEY is pulled from environment variables but the transmission itself is mandatory.
The function transmits:
- Full BSSID (hardware MAC address of access points).
- SSID (network name — may contain personal/organisational identifiers).
- The application's
WPASEC_KEY, included in every outbound request.
Why this matters
Users of WireTapper (and the owners of the access points being scanned) have no knowledge that their network fingerprints are being sent to an external Bulgarian cracking/lookup service. In enterprise or law-enforcement deployments this constitutes unauthorised data disclosure to a third party and may violate GDPR Article 5 (data minimisation) and Article 13 (transparency obligations). The timeout=None also means a slow or unresponsive wpa-sec.stanev.org will hang the entire scan request indefinitely.
Attack or failure scenario
- Security analyst runs a Wi-Fi sweep of a sensitive location (e.g., a government building, a private home under investigation).
- WireTapper silently POSTs every BSSID + SSID to
wpa-sec.stanev.org without the analyst's knowledge.
- The third-party operator now has a timestamped record of which access points were scanned, correlating scan activity to operational targets.
- If
wpa-sec.stanev.org is unavailable, every scan request blocks indefinitely (no timeout), hanging the UI.
Root cause
A debug/research feature was shipped to production without a feature flag, user disclosure, or timeout guard. The integration treats an external cracking lookup as a mandatory pipeline step rather than an optional enrichment.
Recommended fix
- Gate
wpasec_kquery behind an explicit opt-in configuration flag (ENABLE_WPASEC_LOOKUP=false by default).
- Add a hard
timeout=10 to the requests.get call.
- Display a clear disclosure in the UI when the lookup is enabled ("Network fingerprints are submitted to wpa-sec.stanev.org for PMKID lookup").
- Add a privacy notice to the README documenting the data-sharing behaviour.
- Consider whether the feature is necessary at all given its privacy implications.
Acceptance criteria
Suggested labels
security, privacy, bug
Priority
P1
Severity
High — silent exfiltration of operational intelligence to an undisclosed third party; constitutes a privacy violation and potential operational security breach.
Confidence
Confirmed — wpasec_kquery in app-env.py:84 with timeout=None, called unconditionally from scan handler.
Summary
The
wpasec_kqueryfunction unconditionally transmits BSSID and SSID fingerprints of scanned Wi-Fi networks to the third-party servicewpa-sec.stanev.orgon every nearby-device scan request. This exfiltration is silent, undisclosed to users, and has no opt-out mechanism, rate limiting, or request timeout.Evidence
app-env.pylines 84–118:Called unconditionally from the nearby-scan handler for every BSSID in the response. No user consent prompt, no privacy notice, no configuration toggle to disable the lookup.
WPASEC_KEYis pulled from environment variables but the transmission itself is mandatory.The function transmits:
WPASEC_KEY, included in every outbound request.Why this matters
Users of WireTapper (and the owners of the access points being scanned) have no knowledge that their network fingerprints are being sent to an external Bulgarian cracking/lookup service. In enterprise or law-enforcement deployments this constitutes unauthorised data disclosure to a third party and may violate GDPR Article 5 (data minimisation) and Article 13 (transparency obligations). The
timeout=Nonealso means a slow or unresponsivewpa-sec.stanev.orgwill hang the entire scan request indefinitely.Attack or failure scenario
wpa-sec.stanev.orgwithout the analyst's knowledge.wpa-sec.stanev.orgis unavailable, every scan request blocks indefinitely (no timeout), hanging the UI.Root cause
A debug/research feature was shipped to production without a feature flag, user disclosure, or timeout guard. The integration treats an external cracking lookup as a mandatory pipeline step rather than an optional enrichment.
Recommended fix
wpasec_kquerybehind an explicit opt-in configuration flag (ENABLE_WPASEC_LOOKUP=falseby default).timeout=10to therequests.getcall.Acceptance criteria
wpasec_kqueryis not called unlessENABLE_WPASEC_LOOKUP=trueis explicitly set.requests.getcall has a finite timeout (≤ 10 s)..env.examplesetsENABLE_WPASEC_LOOKUP=false.Suggested labels
security, privacy, bug
Priority
P1
Severity
High — silent exfiltration of operational intelligence to an undisclosed third party; constitutes a privacy violation and potential operational security breach.
Confidence
Confirmed —
wpasec_kqueryin app-env.py:84 withtimeout=None, called unconditionally from scan handler.