T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/write.sh:35
- Finding
- Bearer Token Disclosed in Error Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/write.sh:35-47` **Vulnerability Type**: Sensitive credential exposure through diagnostic output **Risk Level**: Medium ### Vulnerable Code ```bash if [ "$SHARE_ID" = "$DOC_ID" ]; then # Check if this is a folder share by trying to list files FILES_CHECK=$(curl -sf "${RELAY_CP_URL}/v1/documents/${SHARE_ID}/files?share_id=${SHARE_ID}" \ -H "Authorization: Bearer $TOKEN" 2>/dev/null || echo "") if [ -n "$FILES_CHECK" ]; then FILE_COUNT=$(echo "$FILES_CHECK" | jq '.files | length' 2>/dev/null || echo "0") if [ "$FILE_COUNT" -gt "0" ] || echo "$FILES_CHECK" | jq -e '.files' >/dev/null 2>&1; then echo "Error: this looks like a folder share (has file metadata)." >&2 echo "write.sh does NOT work for folder shares — files won't appear in Obsidian." >&2 echo "" >&2 echo "Use upsert-file.sh instead:" >&2 echo " scripts/upsert-file.sh \"$TOKEN\" \"$SHARE_ID\" \"filename.md\" \"content\"" >&2 exit 1 ``` ### Technical Analysis When `write.sh` determines that the supplied identifier appears to represent a folder share, it constructs a usage example containing the complete value of `$TOKEN` and writes it to standard error. Standard error is not a secure secret channel. It may be retained in AI agent transcripts, CI/CD logs, centralized logging systems, terminal recordings, support bundles, or command-execution audit trails. The exposed value is a bearer credential, so possession of it is sufficient to authenticate as the corresponding Relay user until the token expires or is revoked. ### Attack Path 1. A user or agent invokes `write.sh` with identical folder share and document identifiers. 2. The script successfully queries the folder’s file metadata. 3. The folder-share detection branch is entered. 4. The script prints a command containing the complete bearer token to standard error. 5. A local user, log reader, monitoring service, or other party with ...[truncated 816 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Never place authentication credentials in diagnostics, usage examples, or error messages. Replace the token-bearing output with an invocation that relies on the existing environment variable: ```bash echo "Use upsert-file.sh instead:" >&2 echo " scripts/upsert-file.sh \"$SHARE_ID\" \"filename.md\" \"content\"" >&2 ``` Additional hardening measures: 1. Search all script output paths to ensure that `$TOKEN`, `$RELAY_PASSWORD`, and complete API responses containing credentials are never printed. 2. Add automated tests that invoke error branches using a sentinel token and fail if the sentinel appears in stdout or stderr. 3. Treat existing logs as potentially compromised and remove any retained output containing tokens. 4. Revoke exposed tokens where supported, or wait for expiration before considering affected sessions secure. ]]>
