Sep 9, 2026·7 min read·2 visits
Unauthenticated remote code execution in winml-cli before 0.4.0 via CORS wildcard and lack of loopback verification.
A critical vulnerability (CVE-2026-84452) in the Windows ML CLI (winml-cli) HTTP server component allows unauthenticated remote code execution via permissive CORS and lack of request validation.
The Windows ML CLI (winml-cli) HTTP server component before version 0.4.0 contains an unauthenticated local remote code execution vulnerability, tracked as CVE-2026-84452. The tool, designed to manage and execute machine learning models locally on Windows, exposes an HTTP API to facilitate local tooling integrations and user dashboards. By default, this HTTP server binds to the loopback interface (127.0.0.1 or localhost).
The fundamental security flaw stems from a permissive Cross-Origin Resource Sharing (CORS) policy configured with a wildcard (*) alongside a complete lack of authentication on administrative endpoints. Because the local server does not validate the origin of incoming HTTP requests, external websites can cross the browser-security boundary to execute commands on the loopback interface. This vulnerability belongs to the classes CWE-942 (Permissive Cross-domain Policy with Untrusted Domains) and CWE-306 (Missing Authentication for Critical Function).
If a developer with a running winml-cli instance visits a malicious or compromised web page, the attacker's site can issue silent HTTP POST requests to the local server. By passing specific parameters to vulnerable endpoints such as /v1/cli/build, the attacker can trigger arbitrary model downloads that execute custom Python scripts. This chain results in unauthorized remote code execution on the developer's workstation with the privileges of the active user.
The primary technical root cause resides in the configuration of the FastAPI web application within winml-cli. To facilitate ease of use, the development server registered FastAPI's standard CORSMiddleware with allow_origins=["*"]. This configuration instructs web browsers that any external origin is authorized to read responses and interact with the local HTTP server.
While the web application framework runs locally on loopback, web browsers do not restrict public internet websites from initiating cross-origin requests to private IP spaces or loopback interfaces. Typically, the browser's Same-Origin Policy (SOP) blocks external origins from reading responses unless explicit CORS headers are returned. Because the wildcard policy tells the browser to accept all origins, the security boundary between local services and the public web is eliminated.
Furthermore, the local API translates JSON request parameters directly into CLI utility arguments. Specifically, when invoking Hugging Face transformers routines, the API exposes the trust_remote_code flag. If an API request sets "trust_remote_code": true, the local server passes this parameter directly to AutoConfig.from_pretrained or AutoModel.from_pretrained without validation. The Hugging Face library then downloads and executes any custom code embedded within the specified model repository.
Prior to version 0.4.0, the HTTP server was initialized with a wide-open CORS policy. The application lacked filters on incoming hostnames or client origins, rendering it vulnerable to cross-origin exploitation and DNS rebinding attacks. The vulnerable initialization routine structured CORS as follows:
# VULNERABLE: Permissive CORS configuration in winml-cli
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=False,
allow_methods=["*"],
allow_headers=["*"],
)To address this vulnerability, the developers removed the permissive wildcard middleware and implemented a multi-layered security architecture. They introduced a custom validation middleware named SameOriginMiddleware to block cross-origin traffic and verify that the request host header resolves exclusively to localhost or a loopback IP address:
# PATCHED: Same-origin validation and loopback hostname verification
def _is_same_origin(scope: Scope) -> bool:
# Normalizes host and origin parameters to ensure matching boundaries
origin = _get_origin_header(scope)
if not origin:
return True
return _normalize_host(origin) == _normalize_host(_get_host_header(scope))
def _is_allowed_http_host(hostname: str | None) -> bool:
normalized = _normalize_host(hostname)
if normalized is None:
return False
if normalized == "localhost":
return True
try:
# Ensure the host is a numeric loopback IP
ipaddress.ip_address(normalized)
except ValueError:
return False
return TrueAdditionally, the patch implements strict argument validation inside _args_to_flags() to block the transmission of the trust_remote_code parameter via HTTP endpoints. To guarantee complete protection even if the HTTP validation is bypassed, the server executes downstream routines within a thread-local context that disables code execution. The _disable_remote_code_execution context manager sets a ContextVar to false, which is verified before executing any third-party Hugging Face modeling files:
# PATCHED: Context-bound execution prevention
@contextmanager
def _disable_remote_code_execution() -> Iterator[None]:
token = _REMOTE_CODE_EXECUTION_ALLOWED.set(False)
try:
yield
finally:
_REMOTE_CODE_EXECUTION_ALLOWED.reset(token)Exploitation of CVE-2026-84452 requires two conditions: a running local winml-cli instance on the victim's machine and user interaction to visit a malicious website. The attack operates entirely through the victim's web browser, which serves as a proxy to send requests to localhost or 127.0.0.1 on default port 8000 or 8080. The attacker does not need direct network visibility or access to the victim's machine.
First, the attacker creates a malicious model repository on the Hugging Face Hub containing a customized config file. The repository includes a Python file such as configuration_malicious.py containing arbitrary command execution instructions. When Hugging Face's transformers library parses this configuration with trust_remote_code=True, it imports and executes the module, triggering the payload.
Second, the attacker hosts a page with a JavaScript payload that sends asynchronous background POST requests targeting standard local ports. When the victim loads the page, the script executes automatically, delivering a JSON payload containing the attacker's model identifier and "trust_remote_code": true to the local /v1/cli/build endpoint. The local server processes the request, downloads the malicious configuration, and executes the payload on the host system.
The security consequences of CVE-2026-84452 are severe, resulting in complete compromise of the local workstation's integrity, confidentiality, and availability. Because the winml-cli HTTP server runs within the security context of the local developer or system administrator, any code executed through the Hugging Face engine inherits those identical system privileges. If the user runs the CLI server with administrative privileges, the attacker gains full control over the operating system.
The CVSS v4.0 base score is rated at 8.6, reflecting the high impact on confidentiality, integrity, and availability. Although the attack requires user interaction to visit a malicious website, the exploit complexity is low, and no specialized privileges are needed to execute the request. This low barrier to entry, combined with the automated execution flow of browser-initiated cross-origin requests, makes the vulnerability a critical risk for machine learning engineers.
Furthermore, because developers frequently handle proprietary code, private access keys, and training data on their workstations, this exploit path poses a significant risk of intellectual property theft. Attackers can leverage the execution context to exfiltrate environment variables, system credentials, and AWS or Hugging Face access tokens. The vulnerability has not been documented in active ransomware or wild-threat campaigns, but proof-of-concept indicators suggest it is highly reliable.
Remediation of CVE-2026-84452 requires updating the winml-cli package to version 0.4.0 or later. This release includes the security mitigations that eliminate permissive CORS policies, restrict DNS rebinding vectors, and block untrusted remote code execution through context wrappers. Users can upgrade their installation using standard package managers or by syncing their git clone with the main repository.
# Upgrade winml-cli package
pip install --upgrade winml-cli>=0.4.0If an immediate upgrade is not feasible, several defensive workarounds can be applied to mitigate the exposure. Developers should terminate the local server processes immediately after use rather than leaving them active in background terminals. Host firewalls can also be configured to block external or interface-level routing to ports 8000 and 8080 to prevent unauthorized cross-origin requests from adjacent devices on the local network.
At the browser level, administrators can configure policies to restrict cross-origin requests to private networks. For instance, enabling Google Chrome's Private Network Access (PNA) security feature prevents public web origins from making requests to the local loopback space without prior preflight approval. Developers should also verify that their web browsers do not bypass local routing rules or expose loopback ports to untrusted external domains.
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
winml-cli microsoft | < 0.4.0 | 0.4.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-942, CWE-306 |
| Attack Vector | Network (via Browser Cross-Origin Request) |
| CVSS v4.0 Score | 8.6 |
| EPSS Score | 0.00945 (58.83rd percentile) |
| Impact | Remote Code Execution |
| Exploit Status | Proof of Concept |
| KEV Status | Not Listed |
The product allows a cross-domain policy to be configured to allow access from untrusted domains.
A high-severity namespace injection vulnerability in both the MongoDB Client Library for PHP (mongodb/mongodb) and the native PHP C Extension (ext-mongodb) allows unauthenticated remote attackers to bypass logical database separation and execute database commands inside unauthorized storage compartments via dot (".") and null byte ("\0") injection.
An incomplete fix vulnerability (CVE-2026-15603) in the morgan HTTP request logger middleware for Node.js allows unauthenticated remote attackers to forge log entries. The flaw arises because the escaping mechanism does not neutralize Unicode line separator characters, enabling attackers to inject payloads that trick downstream log processors into splitting single log records into multiple logical entries.
A high-severity denial of service vulnerability in the Node.js middleware 'multer' allows unauthenticated remote attackers to exhaust CPU resources and freeze applications. By submitting small, specially crafted 'multipart/form-data' requests containing large array indices alongside conflicting parameter keys, attackers force synchronous execution loops over up to 4.2 billion elements within the underlying 'append-field' library.
CVE-2026-77063 details a security flaw in multer, the standard multipart/form-data handler for Node.js, where asynchronous file filters introduce a race condition. This condition causes the library to miss file size limitation events, resulting in the silent acceptance of truncated files.
A resource consumption vulnerability exists in the multer library version 2.2.0 when utilizing the disk storage engine. When a remote client aborts or truncates an in-progress file upload, multer removes the partial file from the disk but fails to properly close the active write stream. This behavior leaves the underlying file descriptor open in the operating system, allowing a remote attacker to systematically exhaust the server's file descriptor limits and trigger a Denial of Service.
CVE-2026-77078 is a critical denial of service vulnerability in the multer Node.js package, allowing unauthenticated remote attackers to crash the runtime process using a single crafted multipart/form-data HTTP payload.