T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/jira-pat.sh:13
- Finding
- Jira Personal Access Token Can Be Sent to an Untrusted or Insecure Destination## Vulnerability Details **File Location**: `scripts/jira-pat.sh:13-17, 21-24, 37-41, 76-84, 89-99` **Vulnerability Type**: Unrestricted credential destination and insecure transport **Risk Level**: Medium ### Vulnerable Code ```bash check_env() { if [[ -z "${JIRA_PAT:-}" ]]; then echo "Error: JIRA_PAT environment variable not set" >&2 exit 1 fi if [[ -z "${JIRA_URL:-}" ]]; then echo "Error: JIRA_URL environment variable not set" >&2 exit 1 fi } jira_get() { check_env local issue_key="$1" curl -s -H "Authorization: Bearer $JIRA_PAT" \ "$JIRA_URL/rest/api/2/issue/$issue_key" | jq } jira_search() { check_env local jql="$1" curl -s -H "Authorization: Bearer $JIRA_PAT" \ "$JIRA_URL/rest/api/2/search?jql=$jql" | \ jq '.issues[] | "\(.key): \(.fields.summary) [\(.fields.status.name)]"' -r } curl -s -X POST \ -H "Authorization: Bearer $JIRA_PAT" \ -H "Content-Type: application/json" \ -d "$payload" \ "$JIRA_URL/rest/api/2/issue/$issue_key/transitions" curl -s -X POST \ -H "Authorization: Bearer $JIRA_PAT" \ -H "Content-Type: application/json" \ -d "$(jq -n --arg body "$body" '{body: $body}')" \ "$JIRA_URL/rest/api/2/issue/$issue_key/comment" | jq ``` The same unsafe pattern also appears in the documented commands in `SKILL.md:20-30, 36-51, 68-69, 75-86, 92-97, 103-114, 120-133`. ### Technical Analysis The helper validates only that `JIRA_URL` is nonempty. It does not require HTTPS, verify that the host is an approved Jira instance, or reject a URL containing an unexpected scheme, host, port, credentials, query, or fragment. Every operation places the privileged `JIRA_PAT` value in an HTTP `Authorization` header and sends it to the origin selected through `JIRA_URL`. Network access and Bearer authentication are necessary for the declared Jira-management functionality, but allowing the credential destination to remain unrestricted exceeds minimum safe privilege. If `JIRA_URL` is accidentally or m ...[truncated 1789 chars]
- Remediation
- ## Remediation Suggestions 1. Parse and validate `JIRA_URL` before making any request: - Require the `https` scheme. - Reject embedded credentials, fragments, and malformed URLs. - Reject unexpected ports unless explicitly approved. - Normalize the URL and remove trailing slashes. 2. Restrict the destination hostname through an administrator-controlled allowlist or immutable configuration. Do not rely solely on an environment variable that untrusted processes or wrappers may influence. 3. Ensure the validated origin exactly matches the origin receiving the Authorization header. Do not concatenate credentials into arbitrary user-provided URLs. 4. Preserve TLS certificate verification and do not introduce `curl -k` or `--insecure`. 5. Configure `curl` to fail safely and expose HTTP errors without printing credentials, for example by using `--fail-with-body --silent --show-error`. 6. Document that `JIRA_URL` is security-sensitive configuration and must come from a trusted source. 7. Use a short-lived, revocable PAT with only the Jira permissions required for the intended read or write operations. 8. Apply equivalent validation guidance to every command example in `SKILL.md`. A validation routine should fail closed before any network request, for example: ```bash validate_jira_url() { case "$JIRA_URL" in https://issues.example.com|https://issues.example.com/) JIRA_URL="${JIRA_URL%/}" ;; *) echo "Error: JIRA_URL must be the approved HTTPS Jira origin" >&2 exit 1 ;; esac } ``` For deployments requiring multiple Jira instances, use a securely maintained allowlist rather than accepting every HTTPS hostname.
