T09 · Insecure Skill Coding Practices
- Location
scripts/google_search.py:92- Finding
API Key Accepted Through a Command-Line Argument
- Content
View full analysis
Vulnerability Details
File Location:
scripts/google_search.py:92andSKILL.md:52-53
Vulnerability Type: Sensitive credential exposure through process arguments and shell history
Risk Level: MediumThe Skill explicitly supports supplying a paid API key through the
--azt_api_keycommand-line argument.Relevant documentation:
bash # Paid version (pass directly as an argument) python3 scripts/google_search.py --q "OpenAI news" --azt_api_key your_key_hereRelevant implementation:
python parser.add_argument("--azt_api_key", default=None, help="API Key (may also be set through the AZT_API_KEY environment variable; optional for the free version)")The argument is subsequently selected and transmitted to the configured third-party search endpoint:
python def get_api_key(arg_key: str | None) -> str | None: """Prefer the key passed as an argument; otherwise read AZT_API_KEY.""" return arg_key or os.environ.get("AZT_API_KEY", "").strip() or None def google_search(q: str, azt_api_key: str | None = None) -> dict: payload: dict = {"q": q} if azt_api_key: payload["api_key"] = azt_api_key try: response = requests.post( API_URL, json=payload, timeout=150, headers={"Content-Type": "application/json"}, )Technical Analysis
Secrets supplied as command-line arguments may be retained in shell history and can be exposed in process listings or operating-system process metadata while the program is running. On systems where process arguments are visible to other users, containers, monitoring agents, diagnostic collectors, or CI logging systems, an observer may recover the API key without compromising the HTTPS connection.
The key is intentionally sent in the JSON body to
https://coze-js-api.devtool.uk/google/search/web. Sending an authentication credential to the service that validates it is consistent with the declared search functional ...[truncated 1820 chars]- Remediation
View remediation
Remediation Suggestions
-
Remove the
--azt_api_keyargument and its documented usage. Read the credential only from a protected secret source such asAZT_API_KEY, a secret manager, or an inherited file descriptor. -
If interactive entry is required, use
getpass.getpass()so the key is not echoed or placed in shell history:python from getpass import getpass api_key = os.environ.get("AZT_API_KEY", "").strip() or getpass("API key: ").strip() -
For automation, configure the execution platform's secret-injection mechanism and ensure secret masking is enabled in logs.
-
Avoid printing the key, request payload, or request headers in normal output, error handling, or future debug logging.
-
Update
SKILL.mdto show only safe credential-loading examples and warn users not to place credentials in command-line arguments. -
Make the implementation and documentation agree on credential precedence. Prefer an approved secret source rather than allowing an exposed command-line value to override it.
-
Document that both the search query and API key are transmitted to
coze-js-api.devtool.uk, allowing users to make an informed trust decision before invoking the Skill. -
Rotate any API key that has previously been supplied through the documented command-line form or exposed in shell or CI logs.
-
