T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/pushplus.py:160
- Finding
- Verbose Logging Exposes PushPlus Credentials and Sensitive Message Data## Vulnerability Details **File Location**: `scripts/pushplus.py:160-162` and `scripts/pushplus.py:265-267` **Vulnerability Type**: Sensitive information exposure through unredacted diagnostic logging **Risk Level**: Medium ### Vulnerable Code Single-channel message sending: ```python if verbose: print(f"Request URL: {API_BASE_URL}") print(f"Request data: {data.decode('utf-8')}") ``` Batch message sending: ```python if verbose: print(f"Request URL: {API_BATCH_URL}") print(f"Request data: {data.decode('utf-8')}") ``` ### Technical Analysis Both message-sending functions serialize the complete request payload before transmitting it to PushPlus. The payload includes the PushPlus `token` and message `content`. Depending on the selected options, it may also include recipient identifiers, group identifiers, webhook configuration codes, preprocessing codes, and callback URLs. When verbose mode is enabled, the code decodes and prints the complete serialized payload without redaction. Standard output is frequently captured by CI/CD systems, process supervisors, agent transcripts, terminal recording systems, and centralized log collectors. Consequently, a temporary diagnostic option can cause credentials and private notification content to persist outside their intended security boundary. Transmitting these values to the fixed HTTPS PushPlus endpoints is necessary for the declared notification functionality. Printing them locally is not necessary and exceeds the minimum data exposure required to perform that function. ### Attack Path 1. A user, administrator, troubleshooting workflow, or automated agent invokes the script with `--verbose`, or calls `send_message()` or `send_batch_message()` with `verbose=True`. 2. The script constructs a JSON payload containing the PushPlus token, message content, and optional routing or recipient data. 3. The complete payload is printed to standard output without ...[truncated 1268 chars]
- Remediation
- ## Remediation Suggestions 1. Never print the complete serialized request payload. Construct a separate sanitized diagnostic representation. 2. Replace sensitive values with fixed placeholders. At minimum, redact: - `token` - `content` - `to` - `option` - `callbackUrl` - `pre` 3. Log only operational metadata needed for troubleshooting, such as endpoint name, channel, template, payload byte length, and whether optional fields were supplied. 4. If limited content diagnostics are essential, require a separate explicit opt-in and truncate the value. Do not enable that behavior in shared, CI, or agent environments. 5. Document that credentials passed through command-line arguments can also be exposed through shell history or process listings; recommend environment variables or a protected credential provider. 6. Add automated tests verifying that known token and message-content values never appear in verbose output. Example hardening pattern: ```python if verbose: safe_payload = { "token": "[REDACTED]", "content": f"[REDACTED: {len(normalized_content)} characters]", "template": normalized_template, "channel": normalized_channel, "hasTopic": bool(topic), "hasRecipient": bool(to), "hasCallbackUrl": bool(callback_url), } print(f"Request URL: {API_BASE_URL}") print(f"Request metadata: {json.dumps(safe_payload, ensure_ascii=False)}") ```
