← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-9152 · CWE-306 · Disclosed 2026-05-21

A missing authentication vulnerability exists in the Altium 365 SearchService

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a building directory left unlocked, not the vault door itself

CVE-2026-9152 is an unauthenticated exposure in a legacy Altium 365 SearchService SOAP endpoint. Per Altium's advisory, it affected all Altium 365 cloud workspaces, including commercial and government cloud regions, while on-prem Altium Enterprise Server was not affected. An attacker who knows or can guess a target workspace identifier can query indexed content and can also inject, modify, or delete search index entries without presenting a token, session, or identity.

The raw technical shape screams severe because it is unauthenticated, network-reachable, and cross-tenant. But reality matters: the impact is constrained to the search index layer, not the underlying vault data or platform control plane. That keeps this out of CRITICAL for defenders prioritizing real-world risk, even though the exposed surface is ugly and the confidentiality exposure is still meaningful.

"Internet-reachable and cross-tenant, but the blast radius stops at the search index rather than the source-of-truth vault"
02 · The Attack Path

3 steps from start to impact.

STEP 01

Identify a target workspace

The attacker first needs a valid Altium 365 workspace identifier or workspace URL. In practice this can come from public collaboration links, supplier emails, screenshots, documentation, browser history, or normal business relationship leakage. Tooling is trivial here: a browser, search engine dorks, or passive OSINT is enough.
Conditions required:
  • Attacker has internet reachability to Altium 365 cloud endpoints
  • Attacker can obtain or infer a target workspace identifier
Where this breaks in practice:
  • Workspace identifiers are not always public
  • Enterprises with tightly controlled external sharing reduce passive discovery
Detection/coverage: Attack-surface scanners usually do not flag this prerequisite; this is mostly an OSINT problem, not a vuln-scan problem.
STEP 02

Call the legacy SOAP endpoint without a token

Using curl, Burp Suite, SoapUI, or a custom Python SOAP client, the attacker sends requests directly to the legacy SearchService endpoint. The bug is that the service accepts search index operations without bearer tokens, cookies, or session validation, so the attacker reaches cross-tenant indexed data with no login step.
Conditions required:
  • A reachable vulnerable SearchService endpoint exists
  • The service has not yet been remediated at Altium's side
Where this breaks in practice:
  • Undocumented legacy SOAP paths are harder to discover than first-class REST/GraphQL APIs
  • Reverse proxies, WAFs, or service retirement can break naive exploit attempts
Detection/coverage: External scanners may miss this unless they test undocumented SOAP paths. WAF, CDN, and SaaS access logs are the best place to catch unusual unauthenticated SOAP traffic.
STEP 03

Read or poison the search index

Once connected, the attacker can enumerate indexed content such as component data, folder and project names, and user metadata, then optionally write or delete index entries. Weaponized tools would be simple request replayers in Burp or a Python script; there is no evidence a complex exploit chain is required.
Conditions required:
  • The endpoint exposes read and/or write search index operations
  • The target workspace has sensitive metadata in the index
Where this breaks in practice:
  • Impact stops at the search layer rather than modifying source-of-truth vault objects
  • Some indexed content may be low sensitivity in mature environments
Detection/coverage: Application-layer telemetry can spot bursts of SOAP requests, cross-workspace enumeration patterns, or sudden search-quality anomalies. Traditional EDR on endpoints will not see much because the attack stays in the SaaS plane.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo confirmed active exploitation found in public sources reviewed as of 2026-06-06; not listed in CISA KEV.
Public PoC availabilityNo public GitHub, Exploit-DB, or Metasploit PoC was identified in the reviewed sources as of 2026-06-06.
EPSSPrompt-supplied EPSS is 0.00079 (~0.079%), which is extremely low and argues against broad opportunistic exploitation right now.
KEV statusAbsent from the CISA KEV catalog as checked on 2026-06-06.
Assessed CVSS interpretationMy working vector is CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:L: internet-reachable, no auth, no user action, cross-tenant confidentiality impact, but integrity/availability damage is mostly limited to the search index.
Affected scopePer Altium: all Altium 365 cloud workspaces in commercial and government cloud were affected; Altium Enterprise Server on-prem was not affected.
Fixed stateAltium says the issue was remediated at the service level and no customer action is required; there is no customer-installable fixed version.
Exposure realityThis was a SaaS-wide internet surface rather than a niche internal admin port. Reachability was broad, but exploitability still depended on finding the legacy SOAP path and a target workspace identifier.
Scanning / exposure dataI found no reliable public Shodan/Censys/FOFA fingerprint for this specific SearchService endpoint in the reviewed sources. That means exposure quantification is poor, but the vendor advisory already confirms the affected population was cloud-wide.
Disclosure / reporter / baseline discrepancyDisclosure date is 2026-05-21 and Altium credits Joris Aerts. Note: your prompt says there is no vendor/authority score, but Altium's advisory page currently displays CVSS 10.0; I still mark this as assessed per your instruction because the goal here is a first-principles real-world severity call.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to HIGH (8.4/10)

The decisive factor is that exploitation is unauthenticated and internet-reachable across a multitenant SaaS platform, which makes the entry condition dangerously easy. It lands at HIGH instead of CRITICAL because the blast radius is materially capped: the attacker compromises the search index plane, not the underlying vault data store or platform execution layer.

HIGH Affected scope and core vulnerability behavior from Altium advisory
MEDIUM Practical exploit friction and public exposure observability

Why this verdict

  • Unauthenticated remote access pushes this up: no credentials, no prior foothold, no user interaction, and network reachability from the internet are strong severity amplifiers.
  • Cross-tenant SaaS exposure pushes this up again: the bug crosses workspace boundaries in a shared cloud platform, so the reachable population before remediation was broad rather than niche.
  • Search-index-only impact pulls it down: Altium explicitly says the operations affect the search index, not the underlying vault data. That is the biggest downward pressure on severity.
  • Workspace-ID knowledge adds friction: an attacker still needs a target workspace identifier, which implies some discovery work and keeps this from being the easiest spray-and-pray internet bug.
  • Threat intel is cold: no KEV listing, no public PoC found, and the prompt-supplied EPSS of 0.00079 all argue against widespread weaponization today.

Why not higher?

This is not a platform takeover, auth bypass to the primary data plane, or remote code execution. The attacker can expose sensitive indexed metadata and corrupt search results, but the advisory is clear that the underlying vault objects are not directly changed through this flaw. That limitation is too important to ignore.

Why not lower?

You do not get to call an unauthenticated, internet-facing, cross-tenant SaaS flaw 'medium' just because the write path stops at the search layer. Confidentiality loss still matters here, especially for project names, component data, folder names, and user metadata that can reveal active programs, suppliers, or regulated work.

05 · Compensating Control

What to do — in priority order.

  1. Confirm vendor-side remediation — Treat this as a vendor-risk verification task. Obtain written confirmation from Altium that your commercial or GovCloud workspaces were covered by the service-side fix and retain the evidence within 30 days for a HIGH finding.
  2. Reduce public workspace identifier leakage — Review externally shared project links, supplier onboarding docs, screenshots, and public knowledge-base material that could expose workspace identifiers. Even after remediation, reducing tenant discovery surface is worthwhile and should be completed within 30 days.
  3. Watch SaaS logs for anomalous search activity — If you have access to Altium audit telemetry, proxy logs, or CASB/SSE visibility, look for unauthenticated or unusual SOAP-like requests and sudden spikes in search failures or index anomalies. Put the monitoring rule in place within 30 days.
  4. Escalate regulated-workspace review — If you use Altium 365 GovCloud or store export-controlled design metadata, validate whether any indexed project names or part metadata were sensitive enough to trigger internal incident review. Do that within 30 days because the confidentiality angle is the main business risk.
What doesn't work
  • MFA does not help against a path that never asks for authentication in the first place.
  • EDR on engineer laptops does not meaningfully detect or block abuse that stays inside the SaaS provider's service plane.
  • Patch your endpoints is irrelevant here because there is no customer-side software fix for Altium 365 cloud tenants.
  • Perimeter WAF on your corporate edge does not protect a third-party SaaS endpoint you do not front.
06 · Verification

Crowdsourced verification payload.

Run this from an auditor workstation with internet access to your Altium 365 workspace, not from the target host—this is a SaaS check. Invoke it as python3 altium365_searchservice_check.py https://yourworkspace.365.altium.com; no admin rights are needed. It is a heuristic validator because Altium does not publicly document the legacy SearchService path in the reviewed sources.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# altium365_searchservice_check.py
# Heuristic check for CVE-2026-9152-style unauthenticated SearchService exposure
# Exit codes:
#   0 = PATCHED
#   1 = VULNERABLE
#   2 = UNKNOWN

import sys
import urllib.request
import urllib.error
import urllib.parse
import ssl
import re

CANDIDATE_PATHS = [
    "/SearchService.svc?wsdl",
    "/SearchService.svc?singleWsdl",
    "/SearchService.svc",
    "/search/SearchService.svc?wsdl",
    "/search/SearchService.svc?singleWsdl",
    "/search/SearchService.svc",
    "/services/SearchService.svc?wsdl",
    "/services/SearchService.svc",
]

SOAP_PROBE = b'''<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body />
</soap:Envelope>'''

AUTH_PATTERNS = [
    re.compile(r'login', re.I),
    re.compile(r'sign\s*in', re.I),
    re.compile(r'authorization', re.I),
    re.compile(r'bearer', re.I),
]

SERVICE_PATTERNS = [
    re.compile(r'<wsdl:definitions', re.I),
    re.compile(r'<definitions', re.I),
    re.compile(r'SearchService', re.I),
    re.compile(r'soap:Envelope', re.I),
    re.compile(r'tempuri\.org', re.I),
    re.compile(r'http://schemas\.xmlsoap\.org/wsdl/', re.I),
]


def normalize_base(url: str) -> str:
    if not url.startswith("http://") and not url.startswith("https://"):
        url = "https://" + url
    parsed = urllib.parse.urlparse(url)
    if not parsed.scheme or not parsed.netloc:
        raise ValueError("Invalid workspace URL")
    return f"{parsed.scheme}://{parsed.netloc}"


def fetch(url: str, method: str = "GET", data: bytes = None, headers: dict = None, timeout: int = 10):
    req = urllib.request.Request(url, data=data, method=method)
    for k, v in (headers or {}).items():
        req.add_header(k, v)
    ctx = ssl.create_default_context()
    try:
        with urllib.request.urlopen(req, timeout=timeout, context=ctx) as resp:
            body = resp.read(4096).decode("utf-8", errors="replace")
            return resp.getcode(), dict(resp.headers), body, None
    except urllib.error.HTTPError as e:
        try:
            body = e.read(4096).decode("utf-8", errors="replace")
        except Exception:
            body = ""
        return e.code, dict(e.headers), body, None
    except Exception as e:
        return None, {}, "", str(e)


def looks_like_auth_gate(code: int, headers: dict, body: str) -> bool:
    if code in (401, 403):
        return True
    loc = headers.get("Location", "")
    if code in (301, 302, 303, 307, 308) and any(p.search(loc) for p in AUTH_PATTERNS):
        return True
    if any(p.search(body) for p in AUTH_PATTERNS):
        return True
    return False


def looks_like_exposed_service(code: int, body: str) -> bool:
    if code != 200:
        return False
    return any(p.search(body) for p in SERVICE_PATTERNS)


def main():
    if len(sys.argv) != 2:
        print("UNKNOWN - usage: python3 altium365_searchservice_check.py https://yourworkspace.365.altium.com")
        sys.exit(2)

    try:
        base = normalize_base(sys.argv[1])
    except Exception as e:
        print(f"UNKNOWN - invalid input: {e}")
        sys.exit(2)

    saw_network_error = False
    saw_auth_or_notfound = False
    findings = []

    for path in CANDIDATE_PATHS:
        url = base + path
        code, headers, body, err = fetch(url, method="GET", headers={"User-Agent": "noisgate-check/1.0"})
        if err:
            saw_network_error = True
            findings.append(f"GET {url} -> network error: {err}")
            continue

        findings.append(f"GET {url} -> HTTP {code}")

        if looks_like_exposed_service(code, body) and not looks_like_auth_gate(code, headers, body):
            print("VULNERABLE - unauthenticated service metadata exposed")
            for f in findings:
                print(f)
            sys.exit(1)

        if code in (401, 403, 404) or looks_like_auth_gate(code, headers, body):
            saw_auth_or_notfound = True
            continue

        if code == 200:
            # Try a blank SOAP POST; vulnerable services often respond with SOAP faults without auth
            pcode, pheaders, pbody, perr = fetch(
                url.split("?")[0],
                method="POST",
                data=SOAP_PROBE,
                headers={
                    "User-Agent": "noisgate-check/1.0",
                    "Content-Type": "text/xml; charset=utf-8",
                    "SOAPAction": '""'
                }
            )
            if perr:
                saw_network_error = True
                findings.append(f"POST {url.split('?')[0]} -> network error: {perr}")
                continue
            findings.append(f"POST {url.split('?')[0]} -> HTTP {pcode}")
            if looks_like_exposed_service(pcode, pbody) and not looks_like_auth_gate(pcode, pheaders, pbody):
                print("VULNERABLE - unauthenticated SOAP interaction appears possible")
                for f in findings:
                    print(f)
                sys.exit(1)
            if pcode in (401, 403, 404) or looks_like_auth_gate(pcode, pheaders, pbody):
                saw_auth_or_notfound = True

    if saw_auth_or_notfound and not saw_network_error:
        print("PATCHED - tested candidate paths require auth, redirect to login, or are absent")
        for f in findings:
            print(f)
        sys.exit(0)

    print("UNKNOWN - no positive exposure found, but endpoint path could not be confidently determined")
    for f in findings:
        print(f)
    sys.exit(2)


if __name__ == "__main__":
    main()
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, treat this as a HIGH-severity vendor-risk item, not a host patch ticket. Under the noisgate mitigation SLA, confirm within 30 days that Altium's service-side remediation covered every commercial or GovCloud workspace you use and capture that evidence; under the noisgate remediation SLA, there is no customer patch to deploy, so close the finding with documented vendor confirmation and any residual monitoring well before 180 days.

Sources

  1. Altium security advisory
  2. Positive Technologies dbugs summary
  3. Altium 365 API documentation
  4. Altium external systems integration docs
  5. NVD search result containing CVE-2026-9152
  6. NVD vulnerability API docs
  7. CISA Known Exploited Vulnerabilities catalog
  8. FIRST EPSS overview
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.