T09 · Insecure Skill Coding Practices
- Location
discord-threads.py:105- Finding
Discord Bot Token Exposed Through the Config Command
- Content
View full analysis
Vulnerability Details
File Location:
discord-threads.py, lines 105–137
Vulnerability Type: Sensitive credential disclosure through standard output
Risk Level: HighVulnerable Code
python def load_openclaw_discord_config(): """从 openclaw.json 提取 Discord 配置""" import os config_path = os.path.expanduser("~/.openclaw/openclaw.json") with open(config_path) as f: config = json.load(f) discord = config.get("channels", {}).get("discord", {}) accounts = discord.get("accounts", {}) default_account = accounts.get("default", {}) token = default_account.get("token", "") # 从 bindings 提取 agent -> channel 映射 channel_map = {} for binding in config.get("bindings", []): agent_id = binding.get("agentId") match = binding.get("match", {}) peer = match.get("peer", {}) if peer.get("kind") == "channel" and agent_id: channel_map[agent_id] = peer["id"] guild_id = "" for gid in default_account.get("guilds", {}): guild_id = gid break return { "token": token, "guild_id": guild_id, "channel_map": channel_map, } if __name__ == "__main__": parser = argparse.ArgumentParser(description="Discord Thread 批量操作") sub = parser.add_subparsers(dest="command") # create: 从 JSON stdin 批量创建 p_create = sub.add_parser("create", help="批量创建项目 Thread") p_create.add_argument("project_name", help="项目名") p_create.add_argument("--input", help="JSON 文件路径 (或 stdin)") # status: 查询 Thread 最新消息 p_status = sub.add_parser("status", help="查询项目 Thread 状态") p_status.add_argument("--input", help="JSON 文件路径 (或 stdin)") # config: 输出当前 Discord 配置 p_config = sub.add_parser("config", help="输出 OpenClaw Discord 配置") args = parser.parse_args() if args.command == "config": cfg = load_openclaw_discor ...[truncated 2042 chars]- Remediation
View remediation
Remediation Suggestions
-
Remove the token from the object returned by any command intended for display.
-
Make the
configcommand return only non-secret information, for example:python print(json.dumps({ "token_configured": bool(cfg["token"]), "guild_id": cfg["guild_id"], "channel_map": cfg["channel_map"], }, indent=2, ensure_ascii=False)) -
Keep credential retrieval private to the functions that perform authenticated Discord API operations.
-
Separate public configuration metadata from secret authentication state using distinct data structures.
-
Redact authorization credentials from all logs, exceptions, diagnostics, and debugging output.
-
Restrict
~/.openclaw/openclaw.jsonto the owning user, such as with file mode0600. -
Rotate the Discord bot token if the vulnerable
configcommand has previously been invoked in a logged environment. -
Add an automated test asserting that command output never contains the configured token.
-
