Back to skill

Security audit

Jira Skills

Security checks for vulnerabilities and agentic risk

Overview

This Jira skill is purpose-aligned, but it can change live Jira issues using stored credentials and automatic invocation without a built-in confirmation gate.

Review before installing. Use a Jira account with only the needed project permissions, prefer environment variables or a protected config file, and require the agent to show the exact issue key, operation, and target value before any create/comment/assign/transition command. Treat implicit invocation as risky for write actions.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
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: Medium

Complete 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

  1. 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.

  2. 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")
    
  3. Add a --dry-run mode that prints the exact Jira URL, issue key, operation, and proposed values without sending the request.

  4. 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.
  5. For transitions, continue validating the available transition list, but display the matched transition ID and name before approval.

  6. Add automated tests proving that create-issue, comment, transition, and assign cannot issue network write requests without the confirmation flag.

Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (14)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 67)May include surrounding context.

md
## 注意事项

- Cloud 用「邮箱 + API Token」配 `JIRA_AUTH=basic`。
- Server/DC 的 Personal Access Token 用 `JIRA_AUTH=bearer`(用户名可省略)。
- `assign --user` 在 Server 用 `name`,Cloud 上可能需要 accountId。
- 建单、评论、流转、指派都是写操作(🟡 级),执行前跟用户确认单据号与目标值。

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/USAGE.md (reported line 27)May include surrounding context.

md
3. 认证方式为 **basic**:用户名填你的登录邮箱,密码填该 token。

### Jira Server / Data Center(自建)
1. 头像 → **Personal Access Tokens** → **Create token**。
2. 认证方式为 **bearer**:只需 token,无需用户名。

---

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/jira_cli.py (reported line 9)May include surrounding context.

python
JIRA_URL    e.g. https://your-domain.atlassian.net  (or self-hosted base URL)
    JIRA_USER   account email (Cloud) or username (Server/DC)
    JIRA_TOKEN  API token (Cloud) or personal access token (Server/DC)
    JIRA_AUTH   "basic" (default, Cloud: email+token) or "bearer" (Server/DC PAT)

Alternatively put the same keys (lowercased, without the JIRA_ prefix) in

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 9)May include surrounding context.

md
## English

Manage Jira issues from the command line through the Jira REST API. The included
Python CLI can read issues, run JQL searches, create issues, add comments, assign
owners, and transition issues through a workflow.

### Compatibility

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill declares and encourages use of network access and environment-sourced credentials, but it does not declare any explicit tool scope such as allowed-tools or permissions. That omission weakens reviewability and least-privilege controls, making it easier for an agent to invoke networked behavior without clear policy boundaries.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill enables implicit invocation without any visible activation constraints, narrowing rules, or user-confirmation guardrails. Because this skill can perform Jira issue and workflow operations, automatic triggering could cause unintended searches, comments, assignments, or state transitions based on loosely matched user intent or prompt injection from surrounding context.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/USAGE.md (reported line 23)May include surrounding context.

md
### Jira Cloud(xxx.atlassian.net)
1. 登录 Jira,访问 https://id.atlassian.com/manage-profile/security/api-tokens
2. 点击 **Create API token**,复制生成的 token。
3. 认证方式为 **basic**:用户名填你的登录邮箱,密码填该 token。

### Jira Server / Data Center(自建)

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/USAGE.md (reported line 23)May include surrounding context.

md
### Jira Cloud(xxx.atlassian.net)
1. 登录 Jira,访问 https://id.atlassian.com/manage-profile/security/api-tokens
2. 点击 **Create API token**,复制生成的 token。
3. 认证方式为 **basic**:用户名填你的登录邮箱,密码填该 token。

### Jira Server / Data Center(自建)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/USAGE.md (reported line 56)May include surrounding context.

}

text

> 安全建议:`chmod 600 ~/.devops-skills/jira.json`,切勿把 token 提交到仓库。

---

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill advertises very broad natural-language triggers and says the assistant will automatically call the skill for generic Jira-related requests. That increases the chance of unintended activation for ambiguous prompts, causing actions such as issue creation, comments, assignment, or workflow transitions without sufficiently explicit user confirmation.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/jira_cli.py (reported line 80)May include surrounding context.

python
def request(cfg, method, path, **kwargs):
    headers = {"Accept": "application/json", "Content-Type": "application/json"}
    auth = None
    if cfg["auth"] == "bearer":
        headers["Authorization"] = f"Bearer {cfg['token']}"
    else:

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The markdown lists commands that create issues, add comments, transition workflow state, and assign owners, all of which modify live Jira records. While the README includes permission notes, it does not explicitly warn users that these commands will change production/project data and may trigger notifications or workflow side effects.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The file is written entirely in Chinese and the activation examples are only provided in Chinese, with no indication that other languages are supported or that Chinese is a region-specific requirement. This can be interpreted as a fixed language expectation without user opt-in.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency specifier requests>=2.25,<3 allows installation of many different versions, including releases with known security advisories, and provides no assurance that a patched version will be used. In a Jira-management skill that makes outbound HTTP requests and may handle credentials, session data, and issue content, an unsafe or outdated requests version can increase the risk of credential leakage, TLS/verification flaws, or other client-side request handling issues.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.