Back to skill

Security audit

Agent Colony Join (Agent 聚落接入)

Security checks for vulnerabilities and agentic risk

Overview

This skill broadly matches its community-agent purpose, but it handles account tokens and signing identity material in ways that could expose or confuse users.

Review before installing. Do not use a real platform JWT with this skill until the service uses HTTPS, the token flow is safer than localStorage copying, and the bundled identity private key is removed so each installation generates its own private identity. Treat any posts as public community content and only run the daemon if you intentionally want a long-running agent identity connected to that service.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/identity/identity.json:2
Finding

Bundled Ed25519 Private Key Enables Agent Identity Impersonation

Content
View full analysis

Vulnerability Details

File Location: scripts/identity/identity.json:2-5
Vulnerability Type: Hardcoded cryptographic private key
Risk Level: Medium

Vulnerable Code

json
{
  "name": "本机OpenClaw",
  "pubkey": "302a300506032b6570032100a607131a7e3f8b0eda8acb291dffa1d5bdaefcabf6136f93a4408193d0a7ec12",
  "privkey": "302e020100300506032b657004220420726920ac095c693d58c4d42918b7ca80f263585b165ef394e615af3961de3196",
  "created": "2026-09-17T11:38:39.809Z"
}

The exposed key is loaded by scripts/identity.js:14-17:

javascript
if (fs.existsSync(ID_FILE)) {
  const saved = JSON.parse(fs.readFileSync(ID_FILE, 'utf8'));
  const priv = crypto.createPrivateKey({
    key: Buffer.from(saved.privkey, 'hex'),
    format: 'der',
    type: 'pkcs8'
  });
  return {
    name: saved.name,
    priv,
    privHex: saved.privkey,
    pubHex: saved.pubkey,
    agentId: saved.agentId
  };
}

It is then used to authenticate messages in scripts/post.js:13-19:

javascript
const id = loadOrCreateIdentity('本机OpenClaw');
const agentId = id.pubHex.toLowerCase();
const data = JSON.stringify({
  room,
  kind: reply ? 'comment' : 'post',
  body: text,
  reply_to: reply ? Number(reply) : null,
  ts: Date.now()
});
const r = await fetch(BASE + '/messages', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    agent_id: agentId,
    data,
    signature: sign(id.priv, data)
  }),
});

Technical Analysis

The package distributes a complete Ed25519 private key in plaintext. The identity loader prefers an existing identity.json over generating a new key, so installations containing this file reuse the same package-distributed identity.

The community protocol treats possession of this private key as proof of control over the corresponding agent identity. Because every person with access to the package can recover the key, the identity is not private or host-specific. The restrictive mode applied when creating ...[truncated 1192 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove scripts/identity/identity.json from source control and all distributed packages.
  2. Revoke or invalidate the exposed community identity because the private key must be considered compromised.
  3. Generate a new Ed25519 key locally on each installation's first use.
  4. Add scripts/identity/ or the specific identity file to version-control ignore and package-exclusion rules.
  5. Store generated keys in a user-specific application data directory rather than inside the installed Skill directory.
  6. Preserve restrictive owner-only permissions and verify them after file creation where the operating system supports such checks.
  7. Add release checks that reject artifacts containing private-key fields or PKCS#8 private-key material.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/join.js:12
Finding

Platform JWT Is Transmitted over Plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: scripts/join.js:12-16, 20-29, 43-45
Vulnerability Type: Cleartext transmission of an authentication credential
Risk Level: Medium

Vulnerable Code

javascript
const BASE = process.env.AC_BASE || 'http://38.190.226.234/community/api';
const args = process.argv.slice(2);
const get = (k, d) => {
  const i = args.indexOf('--' + k);
  return i >= 0 ? args[i + 1] : d;
};

const JWT = get('jwt', '');

The generic API helper uses this plaintext base URL:

javascript
const api = async (method, p, body, headers = {}) => {
  const ctrl = new AbortController();
  const t = setTimeout(() => ctrl.abort(), 10000);
  try {
    const r = await fetch(BASE + p, {
      method,
      headers: { 'Content-Type': 'application/json', ...headers },
      body: body ? JSON.stringify(body) : undefined,
      signal: ctrl.signal,
    });
    const d = await r.json().catch(() => ({}));
    return { status: r.status, d };
  } finally {
    clearTimeout(t);
  }
};

During registration, the platform JWT is inserted into the authorization header:

javascript
if (!known) {
  if (!JWT) {
    console.error('首次加入需要 --jwt <平台JWT>(登录 http://38.190.226.234 获取)');
    process.exit(1);
  }
  r = await api(
    'POST',
    '/register',
    {
      name: NAME,
      pubkey: id.pubHex,
      capabilities: {
        protocols: ['narrow-task', 'chat'],
        desc: 'OpenClaw 智能体,可发言讨论与承接窄任务'
      }
    },
    { Authorization: `Bearer ${JWT}` }
  );
}

Technical Analysis

On first-time registration, the user-provided platform JWT is sent as a bearer credential to an http:// endpoint. Plain HTTP provides neither transport confidentiality nor authenticated server identity.

An attacker positioned on the network path can read the authorization header. Such an attacker may also modify plaintext responses or redirect the user's traffic at the network layer. The ten-second request timeout does not mitigate interception.

The vul ...[truncated 1297 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the default endpoint with an HTTPS URL backed by a valid certificate.
  2. Reject http: base URLs whenever an authorization header or other secret would be sent.
  3. Validate AC_BASE before requests and fail closed if its scheme is not https:.
  4. Do not provide an insecure fallback for authenticated registration.
  5. Rotate or revoke JWTs that may already have been transmitted through the plaintext endpoint.
  6. Consider accepting the JWT through a protected environment variable or secure prompt to reduce local command-line exposure, while recognizing that this does not replace HTTPS.
  7. Document the expected destination and credential scope so users can verify where their token will be sent.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (12)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The instructions tell the user to extract a platform JWT from browser localStorage and even provide a test account credential, but do not include any warning about credential sensitivity, account compromise risk, or safe handling. This is especially risky because the JWT enables authenticated registration actions and may expose a user to account takeover, token leakage, or unauthorized use if copied into logs, prompts, terminals, or shared environments.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/join.js --jwt "<平台JWT>" --name "本机OpenClaw" --daemon

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/feed.js [--room general] [--limit 20]

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill advertises broad trigger phrases like joining a community, posting, and checking what the community is discussing, which can match ordinary user requests and cause the skill to be invoked in situations where the user did not intend external network actions or account-linked operations. In this skill, unintended invocation is more dangerous because the actions include registration, persistent daemon behavior, posting content, and use of authentication material.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The natural-language description and subsequent console output strings are written in Chinese, with no indication that language selection is optional or that the skill is intentionally limited to a Chinese-speaking context. This can violate language/locale policy when a skill implicitly forces one language without user opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code makes outbound network requests with fetch() to a remote API endpoint, but the script provides no confirmation prompt, warning message, or explanatory comment/docstring about contacting that external service. Users running the script may not realize it transmits their requested room/query context and connects to a hard-coded remote host.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The comment states that the private key never leaves the local machine, but the function returns the private key both as a KeyObject and as a raw hex string (privHex). Exporting raw private key material greatly increases the chance that other modules log, transmit, or persist it elsewhere, defeating the stated security boundary and making key exfiltration much easier if any consuming code is compromised.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script automatically creates or loads a persistent agent identity and immediately uses it for remote registration and challenge signing, but gives no warning that cryptographic key material may be stored on disk. This can surprise users into creating a long-lived credential tied to the host, increasing the risk of credential theft, unauthorized reuse, or accidental enrollment of the machine into an external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script transmits user-supplied post content, a derived agent identity, and a cryptographic signature to a hard-coded remote endpoint over plain HTTP. Because there is no explicit warning, confirmation, or secure transport, users may unknowingly disclose sensitive content and identifiers, and the traffic can be intercepted or modified in transit by a network attacker.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The identity name is specified entirely in Chinese ("本机OpenClaw") with no indication of user choice or locale opt-in. Under the stated policy, forcing a specific language without offering a language or locale choice can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The natural-language instructions and user-facing behavior are entirely in Chinese, with no indication that language is selectable or that the skill is region-specific. This can violate language/locale policy when a skill imposes a specific language without offering user choice or documenting a justified locale constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

All natural-language strings shown to the user, including the usage text and success/error messages, are written only in Chinese. The file does not offer a language choice or explain that the skill is intentionally limited to a Chinese-speaking or region-specific context.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.