geedge.lantern.io
evaluation confidence: medium public

A Deny policy using an SNI "Negate" condition fails to block after a page is refreshed multiple times, a duplicate of a prior known bug (TSG-18234) — indicating a reliability gap for negated-SNI-condition policies under repeated/retried connections.

duplicate with TSG-18234 【Policies-Security】Condition为SNI Negate的Deny策略,访问网址多次刷新后,页面未阻断

Defense implications

censorsgeneric
techniquessni-blocking
productstsg
capabilitydpi-signature

extracted_by: claude-sonnet-5 · added 2026-08-26 · id: 2026-ompub1179-sni-negate-bug

Related findings

detection

A confirmed bypass — TSG failed to extract SNI from TLS ClientHello when the SNI extension appeared later than expected in the extension list, letting those flows through unblocked (and incidentally TLS 1.3 flows generally, since clients fell back to 1.3 after 1.2 was blocked); fixed on-site via a patch to the "ssl.so" detection plugin.

detection

Engineers built and deployed IP-list and SNI-wildcard signatures to block Cloudflare WARP (the 1.1.1.1 app), including wildcard SNI blocking of *.cloudflare.com. A CTO-level engineer (name redacted) personally flagged the SNI-based rule as likely to cause false positives against unrelated Cloudflare-fronted traffic, given Cloudflare's role as a major CDN.

detection

Geedge fingerprinted several V2Ray-based VPN apps by their fixed API/bootstrap domains rather than protocol characteristics — blocking "V2 Pro" via pro.mucacherry.org, "V2 VPN" via v2.mucacherry.org, and "V2Net VPN" via api.v2net.live plus 5 rotating free-node domains (free1-5.v2n3t2.online / v2n3t.online) the app uses to fetch node lists.

detection

TSG's SSL/IPD logging schema records a hit_pos field on every SSL-blocking log entry (NTC_SSL_LOG, IPD_SSL_IP_LOG) whose value is explicitly one of SNI, SAN, or CN -- confirming TSG's TLS-blocking decision can be attributed to, and therefore driven by, the certificate's SAN or CN fields, not only the ClientHello SNI extension.

evaluation

chongming/traffic_replay is a Flask/tcpreplay-based QA harness that replays curated pcaps against a TSG instance to exercise its decoders, including SSL fixtures specifically named ssl_ech_false.pcap, ssl_no_sni.pcap and ssl_tls13.pcap alongside esni.pcap, openvpn.pcap, and major-platform captures (facebook/google/twitter/ youtube). A companion update_tsg_ca.py/tsg_ca.txt installs a TSG-issued CA cert on the test client, confirming the QA environment exercises TLS interception as part of routine detection testing.

detection

relationship-gtpc-user derives a single per-subscriber correlation key as Hashkey = md5(IMEI + IMSI + phone_number + vsys_id) from mobile-core GTP-C signaling, and a separate per-tunnel key gtp_uuid = md5(uplink_teid + "|" + downlink_teid). On every update it writes not just the primary user<->TEID row (tsg_galaxy:relation_user_teid) but up to four additional secondary-index rows into tsg_galaxy:gtpc_knowledge_base, one per identifier (IMEI, IMSI, phone number, APN) with a type-digit prefix ("0"/"1"/"2"/"3") and — for phone number and APN — the value's characters reversed before use as the row key, a range-scan-friendly key design that lets any of the four identifiers be used to look up the associated tunnel/session independently.