T09 · Insecure Skill Coding Practices
- Location
scripts/capabilities/configure/cmd.py:37- Finding
Raw AccessKeys Are Exposed Through Process Arguments and Plaintext Configuration Storage
- Content
View full analysis
Vulnerability Details
File Location:
scripts/capabilities/configure/cmd.py:37-43,scripts/capabilities/get_shop_data/cmd.py:18-27,scripts/capabilities/configure/service.py:68-80, andSKILL.md:930-935
Vulnerability Type: Credential exposure through command-line arguments and plaintext storage
Risk Level: MediumVulnerable Code
scripts/capabilities/configure/cmd.py:37-43:python ak = sys.argv[1].strip() is_valid, error_msg = validate_ak(ak) if not is_valid: print_output(False, f"❌ {error_msg}", {"configured": False}) return write_ok = configure_via_gateway(ak) or configure_via_file(ak)scripts/capabilities/get_shop_data/cmd.py:18-27:python parser = argparse.ArgumentParser(description="获取单个店铺的全量经营数据(商家身份由传入的 AK 自动识别,无需提供 user_id)") parser.add_argument("--ak", "-a", required=True, help="目标店铺的原始 AK(从 get_bindlist 获取)") parser.add_argument("--date_type", "-d", default="RECENT_7", choices=["RECENT_7", "RECENT_30"], help="日期类型: RECENT_7(近7天,默认) / RECENT_30(近30天)") args = parser.parse_args() try: result = get_shop_data(args.ak, args.date_type)scripts/capabilities/configure/service.py:68-80:python config.setdefault("skills", {}) config["skills"].setdefault("entries", {}) config["skills"]["entries"].setdefault(SKILL_NAME, {}) skill_entry = config["skills"]["entries"][SKILL_NAME] skill_entry["apiKey"] = api_key if "env" in skill_entry and isinstance(skill_entry["env"], dict): skill_entry["env"].pop("ALI_1688_AK", None) if not skill_entry["env"]: del skill_entry["env"] CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True) with open(CONFIG_PATH, "w", encoding="utf-8") as f: json.dump(config, f, ensure_ascii=False, indent=2)Technical Analysis
The configuration command reads the raw AccessKey directly from
sys.argv, while the sho ...[truncated 2231 chars]- Remediation
View remediation
Remediation Suggestions
-
Remove raw AccessKeys from command-line arguments.
- Read secrets from protected standard input with terminal echo disabled.
- Prefer an OpenClaw secret-provider API, operating-system keychain, or inherited protected file descriptor.
- Replace cross-shop raw keys with short-lived, opaque server-side shop identifiers where the gateway supports them.
-
Remove plaintext fallback storage where possible.
- Store credentials in a dedicated secret manager rather than the general OpenClaw JSON configuration.
- If file storage is unavoidable, create the file atomically with mode
0600, verify that it is owned by the current user, and reject symbolic links and unexpected file types. - Correct overly broad permissions on existing files before writing.
-
Prevent secondary disclosure.
- Never include raw AccessKeys in logs, exceptions, command usage examples, telemetry, or Agent-visible output.
- Redact process invocation details in execution telemetry.
- Document credential rotation procedures and advise rotation after suspected transcript or host exposure.
-
Use scoped and short-lived credentials where supported.
- Limit each credential to the minimum read-only endpoints needed.
- Avoid distributing complete shop signing secrets to the Agent execution layer.
-
