T09 · Insecure Skill Coding Practices
- Location
waste_cron.py:87- Finding
Unescaped Configuration Values Permit Output-Protocol Injection
- Content
View full analysis
Vulnerability Details
File Location:
waste_cron.py, lines 87–122 and 143–147
Vulnerability Type: Output-protocol injection through unvalidated configuration values
Risk Level: MediumVulnerable Code
python # Build message template = reminder_config.get("template", "Reminder: {container_name}") container_emoji = container_info.get("emoji", "🗑️") container_name = container_info.get("name", container) message = template.replace("{container_emoji}", container_emoji) message = message.replace("{container_name}", container_name) message = message.replace("{date}", date) # Get recipient info target_key = reminder_config.get("target", "group_whatsapp") # Target name now includes channel (e.g., group_whatsapp, me_telegram) # Extract channel from target name if not specified in reminder_config target_info = get_target_info(targets, target_key) recipient_id = target_info.get("id") # Use channel from target info, or try to extract from target name channel = target_info.get("channel") if not channel: # Extract channel from target key (e.g., group_whatsapp -> whatsapp) if "_" in target_key: channel = target_key.split("_")[-1] else: channel = "whatsapp" if recipient_id: reminders_to_send.append({ "recipient": recipient_id, "channel": channel, "message": message, "container": container, "date": date, "time_slot": time_slot })python # Output for automation print(f"SEND_TO:{r['recipient']}") print(f"CHANNEL:{r['channel']}") print(r["message"]) print("---")Technical Analysis
The script uses a line-oriented protocol in which
SEND_TO:,CHANNEL:, and---have structural meaning. Recipient identifiers, channel names, container metadata, and message templates are read from editable JSON configuration and emitted into this protocol without schema validation, ...[truncated 2661 chars]- Remediation
View remediation
Remediation Suggestions
-
Replace the ad hoc line-oriented output with strict JSON serialization. Emit one JSON object per reminder or a single JSON array, and require the consumer to parse it as data rather than executable routing text.
python output = { "recipient": r["recipient"], "channel": r["channel"], "message": r["message"], "container": r["container"], "date": r["date"], "time_slot": r["time_slot"], } print(json.dumps(output, ensure_ascii=False)) -
Enforce a configuration schema before processing:
- Allow only explicitly supported channels such as
whatsapp,telegram,discord, andemail. - Require recipient identifiers to match channel-specific formats.
- Reject newline, carriage-return, null, and other control characters in routing fields.
- Require templates and container metadata to be strings with reasonable length limits.
- Allow only explicitly supported channels such as
-
If the existing text protocol must be retained, encode every untrusted field using an unambiguous mechanism such as JSON string encoding or Base64. Do not rely only on replacing known marker strings.
-
Harden the downstream consumer so it accepts only a formally parsed record schema, rejects duplicate or unknown fields, validates recipients against an authorized allowlist, and never interprets protocol-like text inside the message field.
-
Restrict permissions on
config.jsonand its containing directory so that only the intended service account can modify routing configuration. -
Add tests covering templates and routing values containing
\n,\r,SEND_TO:,CHANNEL:, and---to verify that they cannot create additional records or modify record boundaries.
-
