#987·obscura

Passive detection (proxydetect.live) produces contradictory results across host OSes in identical Obscura stealth mode

Author: anthonyalayoCreated Sep 14, 2026Updated Sep 14, 2026
Labelsbug

Before you start

  • I searched existing issues and this is not a duplicate.
  • I tested against the latest release or main.
  • This is not a security vulnerability (those go through SECURITY.md, not a public issue).

obscura version or commit

v0.2.2

OS and architecture

Ubuntu 26.04.1 LTS x86_64 host macOS host
Binary / build obscura --stealth fetch obscura --stealth fetch
Network Same home network, no proxy, same public IP same
ip_ttl to proxydetect.live 54 54

How are you using obscura?

CLI (fetch / serve / scrape / mcp)

Affected area

Detection

Build variant

Render-enabled with stealth (official stealth archive or --features render,stealth)

Stealth mode

On (--stealth)

Summary

Running the same Obscura build with identical --stealth fetch arguments on two machines on the same home network (no proxy, no NAT differences, same public IP) produces contradictory passive-detection results from proxydetect.live:

Test Linux host macOS host
AI random-forest classifier PROXY (74 % confidence) NONPROXY (10 % confidence)
TCP/IP SYN fingerprint GREEN (undetected) RED (detected)

Reproduction

bash
# Identical on both hosts:
obscura --stealth fetch "https://proxydetect.live/ai.html"     --dump text
obscura --stealth fetch "https://proxydetect.live/tcpip.html"  --dump text

Expected Behavior

Passive TCP/IP and AI classifiers should not produce contradictory host-dependent results for the same binary under the same flags. If the kernel SYN options cannot be controlled by Obscura, this should be documented as a known limitation. If they can be controlled (userspace TCP/IP, SO_SNAPPED + custom handshake, or equivalent), that would close the gap.

Actual Behavior

AI random-forest classifier

Host Verdict Confidence Elapsed
Linux PROXY 74.0 % 28 ms
macOS NONPROXY 10.0 % 27 ms

Linux raw JSON

json
{
  "is_proxy": true,
  "info": { "status": "ok", "label": "PROXY", "score": 0.74, "totalElapsed": 28 }
}

macOS raw JSON

json
{
  "is_proxy": false,
  "info": { "status": "ok", "label": "NONPROXY", "score": 0.10, "totalElapsed": 27 }
}

Results TCP/IP SYN fingerprint

Host Detected OS User-Agent OS Mismatch flagged? Page verdict
Linux Chromium OS Windows Yes GREEN
macOS iOS Windows Yes RED

OS classification scores:

Host Linux Apple Windows
Linux host 29.6 5.5 3.6
macOS host 10.6 28.4 2.3

Linux SYN packet (full JSON)

json
{
  "cap_len": 74,
  "dst_ip": "5.161.181.126",
  "dst_port": 22379,
  "header_len": 74,
  "ip_checksum": 38656,
  "ip_df": 1,
  "ip_hdr_length": 5,
  "ip_id": 36303,
  "ip_mf": 0,
  "ip_nxt": null,
  "ip_off": 16384,
  "ip_plen": null,
  "ip_protocol": 6,
  "ip_rf": 0,
  "ip_tos": 0,
  "ip_total_length": 60,
  "ip_ttl": 54,
  "ip_version": 4,
  "src_ip": "X.X.X.X",
  "src_port": 54031,
  "tcp_ack": 0,
  "tcp_checksum": 65021,
  "tcp_flags": 2,
  "tcp_header_length": 20,
  "tcp_mss": 1460,
  "tcp_off": 10,
  "tcp_options": "M1460,S,T,N,W10,",
  "tcp_options_ordered": "MSTNW",
  "tcp_seq": 2098441757,
  "tcp_timestamp": 2862690004,
  "tcp_timestamp_echo_reply": 0,
  "tcp_urp": 0,
  "tcp_window_scaling": 10,
  "tcp_window_size": 64240
}

macOS SYN packet (full JSON)

json
{
  "cap_len": 78,
  "dst_ip": "5.161.181.126",
  "dst_port": 22379,
  "header_len": 78,
  "ip_checksum": 9420,
  "ip_df": 1,
  "ip_hdr_length": 5,
  "ip_id": 0,
  "ip_mf": 0,
  "ip_nxt": null,
  "ip_off": 16384,
  "ip_plen": null,
  "ip_protocol": 6,
  "ip_rf": 0,
  "ip_tos": 0,
  "ip_total_length": 64,
  "ip_ttl": 54,
  "ip_version": 4,
  "src_ip": "X.X.X.X",
  "src_port": 9030,
  "tcp_ack": 0,
  "tcp_checksum": 59763,
  "tcp_flags": 2,
  "tcp_header_length": 20,
  "tcp_mss": 1460,
  "tcp_off": 11,
  "tcp_options": "M1460,N,W6,N,N,T,S,E,E,",
  "tcp_options_ordered": "MNWNNTSEE",
  "tcp_seq": 761757651,
  "tcp_timestamp": 1194245761,
  "tcp_timestamp_echo_reply": 0,
  "tcp_urp": 0,
  "tcp_window_scaling": 6,
  "tcp_window_size": 65535
}

Rendering details

No response

Does headless Chrome behave the same?

I did not check