#364·osiris

[Regression] Tor exit-node check still uses substring matching — #159 was closed Completed without any code change

Author: jsawyerdevCreated Sep 13, 2026Updated Sep 15, 2026
LabelsTriage

Severity: Medium (false threat attribution; confirmed regression) Confidence: Confirmed by direct inspection of the current, unmodified route. Audited commit: bd4057567de8ee18d49a8b2744c9746bcd67f3e0 (master, 2026-09-13 audit).

This is the second report of the identical defect. #159 reported that /api/osint/threats determines Tor exit-node status via torList.includes(query) against the raw bulk-exit-list text — substring matching instead of exact line/IP membership — and gave a concrete false-positive example. #159 was closed COMPLETED on 2026-05-21. On the audited commit, four months later, the exact same line is unchanged.

Evidence

typescript
if (torRes.ok) {
  const torList = await torRes.text();
  results.tor_exit_node = torList.includes(query);
}

torList is the newline-delimited bulk exit list as one string; .includes(query) matches query as a substring anywhere in that blob, including across an IP that merely contains the queried IP's digits as a sub-sequence of a different, longer-looking address on an adjacent line boundary, or (as #159 demonstrated) a shorter IP that is textually contained in a longer one.

Reproduction from the original report (still applicable, unchanged code)

Against a fixture list "11.1.1.10\n8.8.8.8\n", querying 1.1.1.1 returns tor_exit_node: true even though 1.1.1.1 is not present as its own line — it is only present as a substring of 11.1.1.10.

Why this matters

  • This route explicitly presents itself as threat intelligence (// Threat Intelligence — AlienVault OTX public pulse feed + Tor exit nodes). A false-positive Tor attribution on a real, non-Tor IP is a direct, actionable false accusation an analyst could act on.

Smallest correction and acceptance criteria

  • Split torList on newlines and check exact membership (.split('\n').map(l => l.trim()).includes(query)), not substring containment.
  • Acceptance: the exact fixture from #159 (list "11.1.1.10\n8.8.8.8\n", query "1.1.1.1") must return false; a genuinely listed exit-node IP must still return true.

Prior-issue check: this is a confirmed, unresolved regression of #159 (closed as Completed, 2026-05-21) — not a new independent finding.