T09 · Insecure Skill Coding Practices
- Location
create-account.js:481- Finding
Shell Command Injection Through User-Controlled Account Parameters
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches an admin account-creation tool, but it needs Review because it uses privileged credentials insecurely and can modify or delete accounts without enough safeguards.
Install only in a tightly controlled admin workspace. Treat the example VPN/subscription values as compromised, rotate any matching credentials, require validated TLS, avoid running the bundled delete/test scripts against production, and review the create/delete/logging code before allowing an agent to invoke it with untrusted account parameters.
create-account.js:481Shell Command Injection Through User-Controlled Account Parameters
create-account.js:116TLS Certificate Validation Can Be Disabled for Credential-Bearing Connections
README.md:49Live-Looking VPN and Subscription Credentials Are Embedded in Documentation
log-creation.js:96Full Subscription URLs and Personal Data Are Stored in Plaintext Logs
log-creation.js:153Unsanitized Username Is Incorporated into Log File Paths
The script sends an Authorization bearer token derived from the environment or a local .env file in outbound HTTPS requests while explicitly disabling TLS certificate verification. This creates a realistic man-in-the-middle risk where the API token and response data could be intercepted or modified, especially since the destination is a raw IP address rather than a hostname with normal certificate validation expectations.
try:
if method == 'GET':
resp = requests.get(url, headers=HEADERS, verify=False)
elif method == 'PUT':
resp = requests.put(url, json=data, headers=HEADERS, verify=False)
elif method == 'PATCH':
This PUT request transmits a bearer token and performs authenticated state-changing operations while TLS verification is disabled. An attacker positioned on the network could intercept the token or tamper with the request, potentially causing unauthorized account modifications on the remote service.
if method == 'GET':
resp = requests.get(url, headers=HEADERS, verify=False)
elif method == 'PUT':
resp = requests.put(url, json=data, headers=HEADERS, verify=False)
elif method == 'PATCH':
resp = requests.patch(url, json=data, headers=HEADERS, verify=False)
elif method == 'POST':
The PATCH request leaks sensitive authentication material to the network stack under insecure transport settings because certificate verification is disabled. Since this endpoint updates user data, interception or tampering could directly lead to unauthorized changes and token compromise.
elif method == 'PUT':
resp = requests.put(url, json=data, headers=HEADERS, verify=False)
elif method == 'PATCH':
resp = requests.patch(url, json=data, headers=HEADERS, verify=False)
elif method == 'POST':
resp = requests.post(url, json=data, headers=HEADERS, verify=False)
The POST request sends the bearer token and modification payload to a remote endpoint with TLS verification turned off. This makes credential exposure and request/response manipulation plausible, particularly because the script automates administrative-style user and squad updates.
elif method == 'PATCH':
resp = requests.patch(url, json=data, headers=HEADERS, verify=False)
elif method == 'POST':
resp = requests.post(url, json=data, headers=HEADERS, verify=False)
print(f"状态码:{resp.status_code}")
try:
The skill documents a destructive API operation that accepts a user-controlled UUID and presents it without any guardrails, confirmation workflow, authorization scoping guidance, or safety constraints. In an agent/tooling context, this can enable parameter abuse or accidental account deletion if untrusted input is passed into the DELETE call, especially since the same document also points to a live bearer token location.
DELETE /api/users/{uuid}
响应: 200 OK
The documented curl command includes the '-k' option, which disables TLS certificate validation while sending an authorization bearer token to a remote admin API. In this skill context, that makes the workflow more dangerous because the tool manages privileged account operations; using insecure TLS settings can expose tokens and administrative changes to man-in-the-middle attacks.
或者运行更新命令(如果后续 API 支持):
curl -k -X PATCH "https://8.212.8.43/api/users/{uuid}" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"trafficResetInterval": "WEEKLY"}'
The script directly accesses a bearer token from a fixed local .env path and then uses it for privileged API operations. In an agent-skill setting, secret consumption from user workspace files is sensitive because it can silently leverage existing credentials to change remote system state, especially when combined with disabled TLS verification.
import os
# 读取配置
ENV_FILE = os.path.expanduser('~/.openclaw/workspace/.env')
with open(ENV_FILE) as f:
for line in f:
if line.startswith('REMNAWAVE_API_TOKEN='):
Passing --force-recreate allows the script to delete an existing user account without an interactive confirmation or strong warning. In an administrative account-management context, destructive actions on production identities can cause service disruption, data loss, and unintended revocation of user access.
On a create failure indicating a duplicate username, the script may automatically search for and delete an existing account, then retry creation, without prior operator approval. This is dangerous because an error path can silently trigger destructive actions against legitimate accounts, increasing the blast radius of API inconsistencies or lookup errors.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
/**
* Remnawave API Token 加载器
*
* 从 .env 文件读取 REMNAWAVE_API_TOKEN
*
* 用法:
* const { getRemnawaveToken } = require('./lib/env-loader');
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
/**
* Remnawave API Token 加载器
*
* 从 .env 文件读取 REMNAWAVE_API_TOKEN
*
* 用法:
* const { getRemnawaveToken } = require('./lib/env-loader');
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
/**
* Remnawave API Token 加载器
*
* 从 .env 文件读取 REMNAWAVE_API_TOKEN
*
* 用法:
* const { getRemnawaveToken } = require('./lib/env-loader');
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
/**
* Remnawave API Token 加载器
*
* 从 .env 文件读取 REMNAWAVE_API_TOKEN
*
* 用法:
* const { getRemnawaveToken } = require('./lib/env-loader');
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
/**
* Remnawave API Token 加载器
*
* 从 .env 文件读取 REMNAWAVE_API_TOKEN
*
* 用法:
* const { getRemnawaveToken } = require('./lib/env-loader');
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
/**
* Remnawave API Token 加载器
*
* 从 .env 文件读取 REMNAWAVE_API_TOKEN
*
* 用法:
* const { getRemnawaveToken } = require('./lib/env-loader');
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
/**
* Remnawave API Token 加载器
*
* 从 .env 文件读取 REMNAWAVE_API_TOKEN
*
* 用法:
* const { getRemnawaveToken } = require('./lib/env-loader');
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
/**
* Remnawave API Token 加载器
*
* 从 .env 文件读取 REMNAWAVE_API_TOKEN
*
* 用法:
* const { getRemnawaveToken } = require('./lib/env-loader');
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
/**
* Remnawave API Token 加载器
*
* 从 .env 文件读取 REMNAWAVE_API_TOKEN
*
* 用法:
* const { getRemnawaveToken } = require('./lib/env-loader');
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
/**
* Remnawave API Token 加载器
*
* 从 .env 文件读取 REMNAWAVE_API_TOKEN
*
* 用法:
* const { getRemnawaveToken } = require('./lib/env-loader');
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
/**
* Remnawave API Token 加载器
*
* 从 .env 文件读取 REMNAWAVE_API_TOKEN
*
* 用法:
* const { getRemnawaveToken } = require('./lib/env-loader');
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
const path = require('path');
// .env 文件路径(workspace 根目录)
const ENV_FILE = path.join(__dirname, '../../../.env');
/**
* 从 .env 文件读取 Remnawave API Token
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
const path = require('path');
// .env 文件路径(workspace 根目录)
const ENV_FILE = path.join(__dirname, '../../../.env');
/**
* 从 .env 文件读取 Remnawave API Token
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
const path = require('path');
// .env 文件路径(workspace 根目录)
const ENV_FILE = path.join(__dirname, '../../../.env');
/**
* 从 .env 文件读取 Remnawave API Token
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
const path = require('path');
// .env 文件路径(workspace 根目录)
const ENV_FILE = path.join(__dirname, '../../../.env');
/**
* 从 .env 文件读取 Remnawave API Token
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
const path = require('path');
// .env 文件路径(workspace 根目录)
const ENV_FILE = path.join(__dirname, '../../../.env');
/**
* 从 .env 文件读取 Remnawave API Token
Detected: suspicious.exposed_secret_literal, suspicious.insecure_tls_verification