T09 · Insecure Skill Coding Practices
- Location
scripts/linear.sh:12- Finding
Untrusted CLI arguments are embedded directly into GraphQL, JSON, and jq programs
- Content
View full analysis
" >&2 exit 1 fi gql "{ projects(filter: { name: { containsIgnoreCase: \\\"$project_name\\\" } }, first: 1) { nodes { issues(first: 30, filter: { state: { type: { nin: [\\\"completed\\\", \\\"canceled\\\"] } } }) { nodes { identifier title state { name } priority priorityLabel assignee { name } } } } } }" | format_issues ``` ```bash issue_id="${1:-}" if [[ -z "$issue_id" ]]; then echo "Usage: linear.sh issue " >&2 exit 1 fi team_key="${issue_id%%-*}" issue_num="${issue_id##*-}" gql "{ issues(filter: { number: { eq: $issue_num }, team: { key: { eq: \\\"$team_key\\\" } } }) { nodes { identifier title description state { name } priority priorityLabel assignee { name } project { name } team { name } createdAt dueDate } } }" ``` Mutation inputs only escape double quotes: ```bash # Escape quotes in title and description title="${title//\"/\\\"}" description="${description//\"/\\\"}" result=$(gql "mutation { issueCreate(input: { teamId: \\\"$team_id\\\", title: \\\"$title\\\", description: \\\"$description\\\" }) { success issue { identifier title url } } }") ``` The comment command also embeds input into GraphQL and jq source: ```bash body="${body//\"/\\\"}" # First get the issue UUID from the identifier issue_uuid=$(gql "{ issueVcsBranchSearch(branchName: \\\"$issue_id\\\") { id } }" | jq -r '.data.issueVcsBranchSearch.id // empty') if [[ -z "$issue_uuid" ]]; then ...[truncated 3423 chars]- Remediation
View remediation
