- Location
- modules/coze_generate_image.py:34
- Finding
- Image Workflow Credential and User Metadata Persisted in Plaintext Logs<![CDATA[
## Vulnerability Details
**File Location**: `skill.py:454-459`, `modules/coze_generate_image.py:27`, `modules/coze_generate_image.py:34-39`, and `modules/coze_generate_image.py:528-540`
**Vulnerability Type**: Plaintext logging of credentials and user identifiers
**Risk Level**: High
### Vulnerable Code
The parent process embeds the image workflow key in a serialized subprocess argument:
```python
payload = {
"prompt": prompt_en,
"image_urls": image_urls,
"key": os.environ.get("MIHE_KEY", "").strip() or file_env.get("MIHE_KEY", "").strip() or os.environ.get("COZE_IMAGE_WORKFLOW_KEY", "").strip() or file_env.get("COZE_IMAGE_WORKFLOW_KEY", "").strip(),
"link_only": True,
"label": label,
}
```
The image module defines a persistent log in the Skill directory and writes arbitrary payloads without redaction:
```python
RUN_LOG_PATH = str(Path(__file__).resolve().parent / "runtime.log")
def append_runtime_log(payload: dict):
try:
from datetime import datetime
line = {"ts": datetime.now().isoformat(timespec="seconds"), **payload}
with open(RUN_LOG_PATH, "a", encoding="utf-8") as f:
f.write(json.dumps(line, ensure_ascii=False) + "\n")
except Exception:
pass
```
After image generation, it logs the original subprocess argument and communication metadata:
```python
append_runtime_log({
"user_input": user_input,
"prompt": parsed.get("prompt"),
"label": parsed.get("label", ""),
"receive_id": receive_id,
"receive_id_type": receive_id_type,
"receive_target_source": receive_target_source,
"chat_id": parsed.get("chat_id", ""),
"chat_type": parsed.get("chat_type", ""),
"link_only": link_only,
"image_url": image_url,
})
```
### Technical Analysis
`skill.py` serializes `MIHE_KEY` or `COZE_IMAGE_WORKFLOW_KEY` into the JSON command-line argument passed to the image module. In the normal parent-driven image-generation flow, the image module receives that e
...[truncated 1930 chars]
- Remediation
- <![CDATA[
## Remediation Suggestions
- Never include API keys or workflow keys in `user_input`, logs, error messages, or command-line arguments.
- Pass the workflow key through a narrowly scoped environment variable or another protected inter-process channel.
- Log only an invocation identifier, status, duration, and non-sensitive label when operational logging is necessary.
- Explicitly redact fields named `key`, `token`, `secret`, `authorization`, and similar variants before serialization.
- Avoid logging raw prompts, recipient IDs, chat IDs, reference URLs, and generated URLs unless the user explicitly enables diagnostic logging.
- Create any required log with mode `0600`, verify ownership, and place it outside distributable or synchronized source directories.
- Add bounded rotation and a documented short retention period.
- Remove existing `runtime.log` files securely and rotate any credential that may already have been recorded.
]]>