Skip to content

wpasec_kquery silently exfiltrates BSSID/SSID fingerprints to wpa-sec.stanev.org on every scan with no user disclosure or timeout #19

@tg12

Description

@tg12

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

  1. Security analyst runs a Wi-Fi sweep of a sensitive location (e.g., a government building, a private home under investigation).
  2. WireTapper silently POSTs every BSSID + SSID to wpa-sec.stanev.org without the analyst's knowledge.
  3. The third-party operator now has a timestamped record of which access points were scanned, correlating scan activity to operational targets.
  4. 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

  1. Gate wpasec_kquery behind an explicit opt-in configuration flag (ENABLE_WPASEC_LOOKUP=false by default).
  2. Add a hard timeout=10 to the requests.get call.
  3. Display a clear disclosure in the UI when the lookup is enabled ("Network fingerprints are submitted to wpa-sec.stanev.org for PMKID lookup").
  4. Add a privacy notice to the README documenting the data-sharing behaviour.
  5. Consider whether the feature is necessary at all given its privacy implications.

Acceptance criteria

  • wpasec_kquery is not called unless ENABLE_WPASEC_LOOKUP=true is explicitly set.
  • The requests.get call has a finite timeout (≤ 10 s).
  • UI displays a disclosure banner when the feature is active.
  • Default .env.example sets ENABLE_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_kquery in app-env.py:84 with timeout=None, called unconditionally from scan handler.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions