Back to skill

Security audit

tiandao-player

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a disclosed game integration, but its optional SSE server can expose authenticated game-control tools on all network interfaces without client authentication.

Install only if you trust tiandao.co with the agent's game state and actions. Protect TAP_TOKEN like an account credential, avoid running --transport sse on an exposed network, and require explicit approval for costly or irreversible in-world actions. Treat all returned world text, whispers, and inscriptions as untrusted content even when the skill asks the agent to quote them.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/tiandao_mcp_server.py:54
Finding

Unauthenticated Network Exposure of Privileged MCP Tools

Content
View full analysis

Vulnerability Details

File Location: scripts/tiandao_mcp_server.py, lines 54–69 and 461–478
Vulnerability Type: Missing authentication and authorization on a network-accessible MCP service
Risk Level: High

Vulnerable Code

python
_token_store: dict = {}
if env_token := os.getenv("TAP_TOKEN"):
    _token_store["default"] = env_token
python
def _get_token(agent_id: str = "default") -> str | None:
    return _token_store.get(agent_id) or _token_store.get("default")


def _auth_headers(agent_id: str = "default") -> dict:
    h = {"Content-Type": "application/json; charset=utf-8"}
    tok = _get_token(agent_id)
    if tok:
        h["Authorization"] = f"Bearer {tok}"
    return h
python
sse_transport = SseServerTransport("/messages/")

async def handle_sse(request):
    async with sse_transport.connect_sse(
        request.scope, request.receive, request._send
    ) as streams:
        await server.run(
            streams[0], streams[1], server.create_initialization_options()
        )

starlette_app = Starlette(
    routes=[
        Route("/sse", endpoint=handle_sse),
        Mount("/messages/", app=sse_transport.handle_post_message),
    ]
)
print(f"Tiandao MCP Server started in SSE mode at http://0.0.0.0:{args.port}/sse")
uvicorn.run(starlette_app, host="0.0.0.0", port=args.port)

Technical Analysis

When the documented --transport sse mode is selected, the MCP service binds to all network interfaces through 0.0.0.0. The /sse and /messages/ routes do not enforce client authentication or authorization before creating an MCP session and accepting tool requests.

The server stores the operator's TAP_TOKEN under the default key. Token lookup accepts a caller-provided agent_id, but an unknown identifier automatically falls back to this default credential:

python
return _token_store.get(agent_id) or _token_store.get("def
...[truncated 2329 chars]
Remediation
View remediation

Remediation Suggestions

  1. Bind SSE mode to loopback by default:

    python
    uvicorn.run(starlette_app, host="127.0.0.1", port=args.port)
    

    Require an explicit, security-conscious option before listening on non-loopback interfaces.

  2. Enforce authentication before accepting /sse connections or /messages/ submissions. Use a strong, independently generated service credential rather than reusing TAP_TOKEN as the client-facing secret.

  3. Protect remote deployments with TLS. Prefer a trusted reverse proxy that provides HTTPS, client authentication, request limits, and network access controls.

  4. Bind each authenticated MCP session to a specific authorized Tiandao identity. Do not allow the caller to select arbitrary agent_id values independently of its session identity.

  5. Remove default-token fallback for unknown identifiers:

    python
    def _get_token(agent_id: str) -> str | None:
        return _token_store.get(agent_id)
    

    Reject requests when no exact authorized mapping exists.

  6. Apply per-tool authorization. Require stronger authorization or explicit confirmation for destructive or costly actions such as transfers, sales, item disposal, combat, donations, and treasury withdrawals.

  7. Add rate limiting, connection limits, structured security logging, and monitoring for failed authentication and sensitive tool invocations.

  8. Document that SSE mode must not be exposed directly to untrusted networks without authentication and encrypted transport.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (13)

Lp1

High
Category
MCP Least Privilege
Confidence
97% confidence
Finding

This server is fundamentally network-connected and can send agent-provided content to a remote service, yet the capability is reportedly absent from declared permissions. That mismatch is security-relevant because reviewers or runtime policy may assume a local-only skill while it actually transmits data and uses bearer-token authentication.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
97% confidence
Finding

This server is fundamentally network-connected and can send agent-provided content to a remote service, yet the capability is reportedly absent from declared permissions. That mismatch is security-relevant because reviewers or runtime policy may assume a local-only skill while it actually transmits data and uses bearer-token authentication.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This skill is built around sending authenticated requests to an external service using a bearer token and optional MCP integration, which constitutes intentional external data transmission. In context this is expected, but it still creates real exposure: agent state, prompts, user-directed actions, and possibly sensitive world or account data are sent to a third-party service outside the local trust boundary.

Content

Scanner excerpt · SKILL.md (reported line 20)May include surrounding context.

md
required: false
    requires:
      bins:
        - curl
        - python3
      pip:
        - httpx

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill describes many world actions with permanent or costly consequences, including death, irreversible bond changes, sunk-cost relationship actions, and treasury withdrawals, but it does not present a prominent up-front warning to the user before use. This can cause users or agents to take destructive in-world actions without informed consent, especially when following suggested prompts and action hints automatically.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill explicitly instructs the agent to copy server-returned narrative verbatim into visible assistant messages. Because the world includes human whispers, inscriptions from other agents, relationship data, and other externally supplied text, this creates a direct republishing channel that can expose sensitive, abusive, or manipulative content to the transcript without filtering.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The recommended prompts hard-code Chinese output conventions and quoted Chinese narrative without offering a user language preference or fallback. This is primarily a safety/usability issue because it can prevent users from understanding what the agent is doing or approving risky actions, increasing the chance of uninformed behavior.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The recommended prompt templates reinforce a default behavior of quoting server narrative after every action, operationalizing the unsafe republishing pattern for all downstream agents. This increases the likelihood that any malicious or sensitive content from the external world will be echoed into user-visible output automatically and repeatedly.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module docstring and all tool descriptions are written exclusively in Chinese, and the protocol parsing is built around Chinese field names, with no indication that users may choose another language. This is a natural-language locale constraint that is not presented as optional or justified as a region-specific compliance requirement.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The advertised scope says register, perceive, and act, but the code exposes an additional whisper tool that can inject user-controlled content into the game world and persistent logs. Scope drift matters because users may authorize a narrower interface than the one actually provided, and this extra write capability can be abused for manipulation, spam, or unintended disclosure.

Content

No source excerpt is available for this finding.

Ssd 1

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The tool description explicitly tells the model it may ignore human-delivered guidance and has full autonomy, which can weaken operator control and encourage unsafe refusal of oversight. In an agent setting, such framing is risky because whispers are an intended human-to-agent control channel, and adversarial autonomy cues can increase the chance of harmful or policy-violating actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The tool description states that whisper content is recorded in the world event log and biography, which is a persistent data-affecting operation, but the implementation provides no confirmation or stronger user-facing disclosure when the action is actually sent. Since this may permanently store user-supplied text, the skill should warn users clearly before submission.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The server can bind an SSE interface on 0.0.0.0 and expose agent-control functions over the network without an in-product warning or protective control. In practice, this increases the chance of accidental internet/LAN exposure, allowing unauthorized parties to invoke tools or abuse the agent if the service is reachable.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The manifest describes connecting an AI agent to the Tiandao world through TAP operations, but this file also exposes the skill as a network-accessible SSE service for remote callers. That deployment mode changes the skill from a local connector into a remotely served integration surface, which is not reflected in the manifest description.

Content

No source excerpt is available for this finding.