T09 · Insecure Skill Coding Practices
- Location
validate-wecom-config.js:143- Finding
Plaintext Disclosure of WeCom Authentication and Encryption Secrets
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill fits its bidding-collection purpose, but it exposes WeCom secrets in logs, sends business data automatically, and includes unsafe scheduling/install patterns that require review before use.
Review and fix the WeCom secret logging before installing. Use least-privilege WeCom credentials, restrict webhook destinations to approved WeCom endpoints, add a dry-run or approval step before records or notifications are sent, and choose one scheduler model instead of installing the supplied crontab alongside the in-process scheduler.
validate-wecom-config.js:143Plaintext Disclosure of WeCom Authentication and Encryption Secrets
test-wechat.js:77Partial Disclosure of a Live WeCom Access Token
wechat-api.js:22Unrestricted Webhook Destination Permits External Disclosure of Collected Records
package-lock.json:4546Unused Puppeteer Dependency Introduces Unnecessary Install-Time Code Execution
crontab.txt:4OS Cron Entry Repeatedly Launches Long-Lived Internal Scheduler Processes
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
### 问题2:API调用失败
**可能原因:**
1. Access Token过期
2. 参数格式错误
3. 权限不足
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
### 问题2:API调用失败
**可能原因:**
1. Access Token过期
2. 参数格式错误
3. 权限不足
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
### 问题2:API调用失败
**可能原因:**
1. Access Token过期
2. 参数格式错误
3. 权限不足
At this location, the documentation instructs users to retrieve an access token using the application's CorpID and CorpSecret as part of troubleshooting. While obtaining a token is normal, in this context it is immediately paired with printing the token, creating a practical credential exposure path and normalizing unsafe handling of secrets.
解决方案:
// 测试获取Access Token
const wechatAPI = new WeChatWorkAPI(config);
const token = await wechatAPI.getAccessToken(config.wechatWork.corpId, config.wechatWork.corpSecret);
console.log('Access Token:', token);
This line logs the access token directly to the console, exposing a valid credential that can be reused by anyone with access to logs or terminal output. Because access tokens are bearer tokens, disclosure can enable unauthorized API calls until the token expires, and such output may be retained in CI/CD or support logs beyond the token lifetime as evidence of poor secret handling.
// 测试获取Access Token const wechatAPI = new WeChatWorkAPI(config); const token = await wechatAPI.getAccessToken(config.wechatWork.corpId, config.wechatWork.corpSecret); console.log('Access Token:', token);
### 问题3:智能表格记录失败
axios is a runtime dependency of this collector skill, so known SSRF, proxy bypass, redirect, or prototype-pollution-related flaws can directly affect network-facing behavior. In a scraping/collector context that fetches remote content, this increases risk because attacker-influenced URLs, redirects, or proxy environment handling may allow internal network access, credential leakage, or response tampering.
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.
form-data is a runtime dependency of axios and the cited CRLF injection issue can become dangerous if attacker-controlled field names or filenames are used when building multipart requests. In a data-collection agent, this could enable request smuggling or header/body manipulation toward downstream services if multipart uploads are implemented.
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.
The code retrieves an enterprise WeChat access token using configured credentials as part of a test flow. In context this is expected functionality, but handling live credentials and tokens in a test script increases exposure risk, especially if the script is run in shared environments or with verbose logging.
console.log('\n⚠️ 智能表格ID未配置,跳过表格测试');
}
// 测试4: 获取Access Token(如果配置了CorpID和Secret)
if (wechatConfig.corpId && wechatConfig.corpSecret) {
console.log('\n🔑 测试4: 获取Access Token...');
const token = await wechatAPI.getAccessToken(wechatConfig.corpId, wechatConfig.corpSecret);
The script logs the first 20 characters of the access token to stdout after successful retrieval. Even partial credential disclosure can aid token identification, correlation across logs, or accidental leakage through CI logs, terminals, or centralized log platforms.
// 测试4: 获取Access Token(如果配置了CorpID和Secret)
if (wechatConfig.corpId && wechatConfig.corpSecret) {
console.log('\n🔑 测试4: 获取Access Token...');
const token = await wechatAPI.getAccessToken(wechatConfig.corpId, wechatConfig.corpSecret);
console.log(`✅ Access Token获取成功: ${token.substring(0, 20)}...`);
} else {
These lines directly print highly sensitive configuration values including the callback token and EncodingAESKey. Exposure of these values can enable unauthorized parties to forge or interfere with WeCom message validation and compromises secrecy well beyond simple misconfiguration troubleshooting.
The README explicitly describes automatically recording collected bidding information into WeCom smart tables, but it does not warn users that data will be transmitted to an external enterprise service or that automated writes will occur. In an agent skill context, this can lead to unintended exfiltration of collected data, accidental disclosure of procurement-related information, or unauthorized modification of shared business records if users deploy it without understanding the integration.
The skill explicitly describes automatic collection and population of externally sourced procurement data into a WeChat Work smart table on a daily schedule, but provides no warning, approval gate, or validation controls around outbound transmission and record modification. This creates a real risk of silently sending scraped data to an external business system and overwriting or polluting records with inaccurate, manipulated, or sensitive information.
The troubleshooting example explicitly prints an access token to the console, which can expose a live bearer credential through terminal history, CI logs, shared screenshots, or centralized logging systems. Even in documentation, this pattern encourages unsafe operator behavior and can lead to unauthorized API use if the token is captured.
The code path for recording bidding information does more than the surrounding comment suggests: postToWeChatWork sends a proactive Markdown message to WeChat Work and may also write to a smart table. This creates a transparency and data-minimization issue because collected procurement details are automatically broadcast to an external collaboration platform, which can surprise operators and leak business-sensitive information more broadly than intended.
The workflow automatically transmits collected bidding data to WeChat Work during scheduled and immediate execution without any approval gate, preview, or explicit warning. In this skill context, the data concerns procurement opportunities and internal sales assignment, so unintended transmission can expose commercially sensitive information, cause compliance issues, or notify the wrong audience at scale.
The script is described as a configuration validator, but it reads a local config file and later prints secret values such as the WeCom token and EncodingAESKey to stdout. This creates an information-disclosure risk because terminal output may be captured in logs, CI pipelines, shell history, or shared support screenshots.
All user-facing descriptions and console messages in the file are hard-coded in Chinese, which imposes a specific language on users without opt-in or explanation. Under the language/locale policy, this is a natural-language locale constraint that should either be optional or clearly justified as region-specific.
The method is documented as decrypting callback messages, but it only logs and returns the encrypted input unchanged. This can cause downstream code to treat undeciphered data as trusted callback content, breaking security assumptions and potentially leading to incorrect processing, audit gaps, or accidental exposure of sensitive encrypted payloads in logs.
The code logs callback message contents directly with console.log, even though callback payloads may contain sensitive business data or identifiers. In an agent/integration context, logs are often centralized and broadly accessible, so this increases the risk of unintended disclosure without any sanitization or warning.