Back to skill

Security audit

ckarena

Security checks for vulnerabilities and agentic risk

Overview

This remote game skill is purpose-aligned overall, but it sends player and game data over unencrypted hard-coded/default servers, so it should be reviewed before use.

Install only if you are comfortable with a remote game service receiving your player name/ID, descriptions, votes, game state, and logs. Prefer not to use this on sensitive networks or with sensitive identifiers until the skill uses HTTPS/WSS consistently and honors one documented endpoint configuration.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
src/api.ts:49
Finding

Plaintext HTTP and WebSocket Connections Expose Game Traffic to Interception and Manipulation

Content
View full analysis
(method: string, path: string, body?: unknown): Promise { const url = `${API_BASE}${path}`; const options: RequestInit = { method, headers: { 'Content-Type': 'application/json' }, }; if (body) options.body = JSON.stringify(body); const res = await fetch(url, options); if (!res.ok) { const text = await res.text(); throw new Error(text || `HTTP ${res.status}`); } return res.json() as Promise; } ``` `src/arena-api.ts:3,28-58`: ```ts const API_BASE = process.env.CKARENA_API || 'http://43.134.60.58:8000'; export async function joinArena(playerId: string): Promise<{success: boolean; message: string; game_id?: string; status: string}> { const res = await fetch(`${API_BASE}/api/arena/join?player_id=${playerId}`, { method: 'POST', }); if (!res.ok) throw new Error(await res.text()); return res.json() as Promise<{success: boolean; message: string; game_id?: string; status: string}>; } export async function leaveArena(playerId: string): Promise { const res = await fetch(`${API_BASE}/api/arena/leave?player_id=${playerId}`, { method: 'POST', }); if (!res.ok) throw new Error(await res.text()); } export async function getArenaStatus(): Promise { const res = await fetch(`${API_BASE}/api/arena/status`); if (!res.ok) throw new Error(await res.text()); return res.json() as Promise; } export async function getMyGame(playerId: string): Promise<{in_game: boolean; game_id?: string; game?: any}> { ...[truncated 4495 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
package-lock.json:15
Finding

Dependency Lockfile Downloads Build Tooling from a Plaintext Third-Party Mirror

Content
View full analysis
=14.17" } }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "http://mirrors.tencentyun.com/npm/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59c6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" } ``` ### Technical Analysis The lockfile resolves all third-party development dependencies from `http://mirrors.tencentyun.com`, which does not provide TLS protection. This exposes package retrieval to interception, redirection, traffic observation, and denial of service. The lockfile includes SHA-512 integrity values. Under normal npm behavior, these values provide an important mitigation: an attacker who modifies only a downloaded archive should cause installation to fail rather than transparently install the altered package. Therefore, plaintext transport alone does not establish a direct arbitrary-code-execution path when the integrity metadata remains trusted and verification is enforced. However, ...[truncated 2536 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (11)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation instructs users to authenticate, poll for game state, and download logs from a third-party remote server, but it does not clearly warn that player identifiers, gameplay content, and potentially other user-provided data will be transmitted off-host. The risk is increased because all listed endpoints use insecure HTTP/WS rather than HTTPS/WSS, exposing data to interception or tampering in transit in addition to the missing privacy disclosure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest presents the skill description and command labels in Chinese, but does not indicate that the skill is China/Chinese-specific or give users a language option. This can violate language/locale policy expectations when a skill implicitly forces one language without opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The client defaults to an HTTP base URL using a raw IP address, so player and game data is transmitted without transport encryption. This exposes identifiers, room activity, votes, and gameplay state to interception or modification by any network attacker on the path, and the use of a hardcoded remote endpoint makes the risk more concrete than a purely theoretical missing-warning issue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The functions send playerId to a remote API via network requests in joinArena and leaveArena, which is user/system data transmission. In this file there is no confirmation prompt, logging, comment, or docstring disclosing that player identifiers are sent to an external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The CLI sends player_id and queue actions to a remote service over plain HTTP, which exposes identifiers and gameplay actions to interception or modification by any network attacker on the path. Because the player_id is included directly in the request URL, it is also more likely to be logged by proxies, terminals, and server infrastructure, increasing privacy and impersonation risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The status handler performs a network call and then displays other waiting players' names, ratings, and wait times, but the CLI help and code comments do not warn users that invoking this feature retrieves and exposes other participants' information from the server. For code files, network operations involving user or system data should include some user disclosure when not otherwise clearly documented.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file's console messages and command guidance are consistently hard-coded in Chinese, including status, prompts, and end-user instructions. Because the skill does not offer language selection or indicate that it is intentionally limited to a Chinese-speaking context, this is a natural-language locale policy violation under the stated rules.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The WebSocket URL embeds the client identifier directly and uses an unencrypted ws:// connection to a hard-coded IP address. This exposes the identifier in cleartext to network observers and intermediaries, and because the identifier appears to act as a connection selector, it may enable user tracking, impersonation attempts, or unauthorized subscription if server-side authentication is weak.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 15)May include surrounding context.

json
"author": "",
  "license": "MIT",
  "devDependencies": {
    "typescript": "^5.3.0",
    "@types/node": "^20.0.0"
  },
  "dependencies": {}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 16)May include surrounding context.

json
"license": "MIT",
  "devDependencies": {
    "typescript": "^5.3.0",
    "@types/node": "^20.0.0"
  },
  "dependencies": {}
}

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The inline comments state the player ID is read from environment variables or a config file and that it 'should actually' come from state.js, yet the implementation only returns process.env.CKARENA_PLAYER_ID or 'guest'. This is a direct documentation-to-code divergence about where identity state is sourced from.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/api.ts:3

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/arena-api.ts:3

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/cli-arena.ts:129