T09 · Insecure Skill Coding Practices
- Location
scripts/enterprise_executed.py:271- Finding
API Credential Exposure Through Command-Line Arguments and Insecure Plaintext Storage
- Content
View full analysis
Vulnerability Details
File Location:
scripts/enterprise_executed.py:69-83, 271-273, 329, 356-358;SKILL.md:27-33
Vulnerability Type: API credential disclosure
Risk Level: MediumThe skill supports passing the Juhe API key directly as a command-line argument and recommends this method in its documentation. Command-line arguments may be exposed through shell history, process inspection, execution telemetry, and command logging.
The skill also supports loading the credential from a plaintext
.envfile but neither creates that file with restrictive permissions nor verifies its ownership or permissions before reading it.Relevant credential-loading code:
python def load_api_key(cli_key: str = None) -> str: if cli_key: return cli_key env_key = os.environ.get("JUHE_ENTERPRISE_EXECUTED_KEY", "").strip() if env_key: return env_key env_file = Path(__file__).parent / ".env" if env_file.exists(): for line in env_file.read_text(encoding="utf-8").splitlines(): line = line.strip() if line.startswith("JUHE_ENTERPRISE_EXECUTED_KEY="): val = line.split("=", 1)[1].strip().strip('"').strip("'") if val: return val return ""Relevant command-line parsing code:
python if args[i] == "--key" and i + 1 < len(args): cli_key = args[i + 1] i += 2The script explicitly advertises the unsafe command-line option:
python print(" --key KEY API Key(可选,可用环境变量配置)")python print(" 1. 环境变量:export JUHE_ENTERPRISE_EXECUTED_KEY=your_api_key") print(" 2. .env 文件:在脚本目录创建 .env,写入 JUHE_ENTERPRISE_EXECUTED_KEY=your_api_key") print(" 3. 命令行参数:python enterprise_executed.py --key your_api_key --name 企业名称")The Skill documentation similarly recommends both plaintext storage and command-line entry: ...[truncated 2456 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove support for supplying the API key through
--key, and remove all command-line examples that embed credentials. - Prefer a dedicated secret manager or a narrowly scoped environment variable injected by the execution platform.
- If interactive credential entry is required, use
getpass.getpass()so the key is not echoed or placed in process arguments. - If
.envsupport remains necessary:- Document creation with restrictive permissions, such as
install -m 600 /dev/null scripts/.env. - Require permission mode
0600or stricter before loading the file. - Verify that the file is owned by the effective user.
- Reject symbolic links and unexpected non-regular files.
- Add
scripts/.envand equivalent secret files to.gitignore. - Warn users never to commit, archive, or share the file.
- Document creation with restrictive permissions, such as
- Rotate any key previously supplied on a command line or stored in a file with uncertain permissions.
- Use a least-privileged API credential with appropriate quota and service restrictions, where the provider supports them.
- Remove support for supplying the API key through
