T09 · Insecure Skill Coding Practices
- Location
scripts/jira_cli.py:147- Finding
Jira write operations do not technically enforce user confirmation
- Content
View full analysis
Vulnerability Details
File Location:
scripts/jira_cli.py, lines 147–246
Vulnerability Type: Missing authorization confirmation for persistent remote mutations
Risk Level: MediumComplete Code Snippet
python def cmd_comment(cfg, args): data = request(cfg, "POST", f"/rest/api/2/issue/{args.key}/comment", data=json.dumps({"body": args.body})) out({"issue": args.key, "comment_id": data.get("id")}) def cmd_transitions(cfg, args): data = request(cfg, "GET", f"/rest/api/2/issue/{args.key}/transitions") out({"transitions": [{"id": t["id"], "to": t["name"]} for t in data.get("transitions", [])]}) def cmd_transition(cfg, args): data = request(cfg, "GET", f"/rest/api/2/issue/{args.key}/transitions") match = next((t for t in data.get("transitions", []) if t["name"].lower() == args.to.lower()), None) if not match: names = ", ".join(t["name"] for t in data.get("transitions", [])) die(f'no transition "{args.to}". Available: {names}') request(cfg, "POST", f"/rest/api/2/issue/{args.key}/transitions", data=json.dumps({"transition": {"id": match["id"]}})) out({"issue": args.key, "transitioned_to": match["name"]}) def cmd_assign(cfg, args): request(cfg, "PUT", f"/rest/api/2/issue/{args.key}/assignee", data=json.dumps({"name": args.user})) out({"issue": args.key, "assignee": args.user}) def build_parser(): p = argparse.ArgumentParser(description="Jira REST API CLI") sub = p.add_subparsers(dest="command", required=True) s = sub.add_parser("get-issue", help="show one issue") s.add_argument("key") s.set_defaults(func=cmd_get_issue) s = sub.add_parser("search", help="search issues by JQL") s.add_argument("jql") s.add_argument("--limit", type=int, default=20) s.set_defaults(func=cmd_search) s = sub.add_parser("create-issue", help="create an issue") s.add_argument( ...[truncated 4130 chars]- Remediation
View remediation
Remediation Suggestions
-
Require an explicit confirmation flag for every mutating command:
python s.add_argument("--confirm", action="store_true", required=True)Prefer validating it in a shared write-operation gate rather than duplicating checks across handlers.
-
Reject write requests unless confirmation is present:
python def require_confirmation(args): if not getattr(args, "confirm", False): die("Write operation requires explicit --confirm approval") -
Add a
--dry-runmode that prints the exact Jira URL, issue key, operation, and proposed values without sending the request. -
Structure the agent workflow as two distinct phases:
- First, inspect and display the precise proposed mutation.
- After explicit user approval, rerun the command with
--confirm.
-
For transitions, continue validating the available transition list, but display the matched transition ID and name before approval.
-
Add automated tests proving that
create-issue,comment,transition, andassigncannot issue network write requests without the confirmation flag.
-
