Back to skill

Security audit

Jira BUG Analysis Assistant[Jira-BUG分析助手]

Security checks for vulnerabilities and agentic risk

Overview

This Jira reporting skill appears legitimate, but it needs review because it handles Jira credentials and creates portable raw-data exports without enough safeguards.

Review before installing. Use a short-lived, read-only Jira PAT scoped to the specific project; avoid username/password auth; do not use --no-verify or curl -k unless you fully accept interception risk; treat generated HTML and XLS files as sensitive internal exports; and install dependencies in an isolated environment with pinned versions if possible.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/get_jiraData.py:121
Finding
TLS Certificate Verification Can Be Disabled for Authenticated Jira Requests<![CDATA[ ## Vulnerability Details **File Location**: `scripts/get_jiraData.py:81, 121-130, 155-159`; related instructions in `SKILL.md:32, 52-63, 72, 81` **Vulnerability Type**: Improper certificate validation **Risk Level**: High ### Complete Code Snippet ```python parser.add_argument( "--no-verify", action="store_true", help="Disable SSL certificate verification" ) ``` ```python def build_session(args): """Create and configure an HTTP session.""" session = requests.Session() if args.token: session.headers["Authorization"] = f"Bearer {args.token}" else: session.auth = (args.username, args.password) session.headers["Content-Type"] = "application/json" session.verify = not args.no_verify if args.no_verify: urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) return session ``` ```python try: resp = session.post(url, json=payload, timeout=30) except requests.exceptions.SSLError as e: log(f"ERROR: SSL certificate verification failed: {e}") log("Hint: Use --no-verify for self-signed certificates.") sys.exit(1) ``` The documentation also recommends an equivalent unsafe option: ```bash curl -u <USER>:<PASS> -k <SERVER>/rest/api/2/project/<PROJECT_KEY> | python3 -c "import sys,json;[print(t['name']) for t in json.load(sys.stdin).get('issueTypes',[])]" ``` ### Technical Analysis When `--no-verify` is supplied, `requests` no longer authenticates the Jira server's TLS certificate. The documented `curl -k` command has the same effect. Disabling warning messages further reduces the likelihood that the user will notice the connection is unauthenticated. The session sends either a bearer token or Basic Authentication credentials over this connection. TLS encryption without certificate validation does not establish the identity of the remote server, so an active network attacker can present an arbitrary certificate and impersonate Jira. Supporting private certificate a ...[truncated 1672 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--no-verify` and the documented `curl -k` workflow. 2. Add a `--ca-bundle PATH` option and pass the supplied private CA bundle to `session.verify`. 3. Require HTTPS for authenticated requests and reject `http://` Jira URLs. 4. Preserve certificate warnings rather than suppressing them. 5. If an emergency bypass must remain, require an explicit interactive confirmation, display a prominent credential-exposure warning, and prevent unattended use. 6. Recommend a least-privileged, read-only Jira service account whose access is restricted to the requested project. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/get_jiraData.py:71
Finding
Jira Credentials Are Accepted Through Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/get_jiraData.py:71-76`; related usage instructions in `SKILL.md:52-66` **Vulnerability Type**: Sensitive information exposure through command-line arguments **Risk Level**: Medium ### Complete Code Snippet ```python parser.add_argument( "--server", required=True, help="Jira base URL, e.g. https://jira.company.com" ) parser.add_argument("--token", help="Personal Access Token (Bearer auth)") parser.add_argument("--username", help="Basic Auth username") parser.add_argument("--password", help="Basic Auth password") parser.add_argument("--project", required=True, help="Jira project key, e.g. PROJ") ``` The documented execution pattern places the secret directly in the command: ```bash python ${SKILL_DIR}/scripts/get_jiraData.py \ --server <JIRA_SERVER_URL> \ --token <PAT> \ --project <PROJECT_KEY> \ [--issue-type Bug] \ [--start-date YYYY-MM-DD] \ [--end-date YYYY-MM-DD] \ [--severity-field customfield_NNNNN] \ [--no-verify] ``` For Basic Authentication, the instructions state that the token should be replaced with: ```bash --username <USER> --password <PASS> ``` ### Technical Analysis Command-line arguments are an unsafe channel for reusable secrets. Depending on the operating system and execution environment, arguments may be visible in process inspection interfaces, monitoring agents, shell history, terminal logs, job metadata, agent transcripts, crash reports, or command audit records. The code does not log the parsed secret itself, but that does not prevent exposure by the shell, process supervisor, or surrounding automation before Python processes the arguments. The risk is particularly significant for a Skill operated by an AI agent because generated commands and execution transcripts may be retained. ### Attack Path 1. A user follows the documented invocation and supplies a PAT or password as a command-line argument. 2. The shell records the command in histor ...[truncated 856 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--token` and `--password` as the recommended credential input mechanisms. 2. Read secrets from a protected environment variable, standard input, an operating-system credential store, or an interactive `getpass.getpass()` prompt. 3. If environment variables are supported, document their exposure limitations and ensure they are not printed or included in generated reports. 4. Allow non-interactive automation to read a secret from a permission-restricted file descriptor or file. 5. Redact credential-bearing arguments from agent transcripts, process logs, and error output. 6. Recommend short-lived, revocable PATs with read-only access limited to the required Jira projects. 7. Retain command-line credential flags only for backward compatibility if necessary, while displaying a deprecation and exposure warning. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Unpinned Python Dependency Is Installed Without Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1`; installation instructions in `SKILL.md:37-47` **Vulnerability Type**: Unpinned third-party dependency **Risk Level**: Medium ### Complete Code Snippet ```text requests ``` The Skill directs users to resolve and install that unrestricted dependency: ```bash pip install -r ${SKILL_DIR}/requirements.txt ``` The fallback command performs the same unrestricted installation: ```bash source ${SKILL_DIR}/.venv/bin/activate && pip install -r ${SKILL_DIR}/requirements.txt ``` ### Technical Analysis The dependency has no exact version constraint and no package hash. Each installation can therefore resolve a different version of `requests` and its transitive dependencies. The result depends on the configured package index and the packages available at execution time rather than on a reviewed, reproducible dependency set. The package name is legitimate and no evidence of intentional typosquatting or dependency confusion was found. Nevertheless, unrestricted resolution increases supply-chain exposure. A compromised package release, compromised package index, maliciously configured index, or unexpectedly incompatible future release could introduce code not covered by this audit. Python package installation and subsequent import can execute package-controlled code with the privileges of the user running the Skill. ### Attack Path 1. The user runs the documented `pip install -r` command. 2. `pip` queries its configured index and selects the latest versions satisfying the unrestricted requirement. 3. A compromised index, malicious mirror, unsafe index configuration, or compromised future release supplies attacker-controlled package content. 4. Package-controlled code executes during installation or when the dependency is imported. 5. The attacker obtains code execution with the operating-system privileges of the user running the Skill. ### Impact Assessment A successful supply-chain compromi ...[truncated 370 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `requests` and all transitive dependencies to reviewed versions. 2. Generate a lock file with cryptographic hashes and install with hash verification, such as `pip install --require-hashes`. 3. Use an approved, authenticated package index or internal mirror. 4. Review and update pinned versions through a controlled dependency-update process. 5. Install into an isolated virtual environment rather than the user's global Python environment. 6. Add automated vulnerability and license scanning for the resolved dependency set. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/get_jiraData.py:104
Finding
Untrusted Project and Issue-Type Values Are Interpolated into JQL<![CDATA[ ## Vulnerability Details **File Location**: `scripts/get_jiraData.py:104-110` **Vulnerability Type**: JQL injection **Risk Level**: Medium ### Complete Code Snippet ```python def build_jql(project, issue_type="Bug", start_date=None, end_date=None): """Build a Jira Query Language query string.""" jql = f'issuetype = {issue_type} AND project = {project}' if start_date: jql += f' AND created >= "{start_date}"' if end_date: jql += f' AND created <= "{end_date}"' jql += " ORDER BY created DESC" return jql ``` These values originate from command-line arguments: ```python parser.add_argument("--project", required=True, help="Jira project key, e.g. PROJ") parser.add_argument( "--issue-type", default="Bug", help="Issue type name to query (default: Bug). Use '故障' for Chinese Jira instances." ) ``` ### Technical Analysis The `project` and `issue_type` values are inserted directly into a JQL expression without validation, quoting, or escaping. An attacker who can influence Skill arguments can provide JQL operators, clauses, or delimiters that alter the intended query. Date values are format-validated before use, but equivalent validation is not applied to the project key or issue-type name. The vulnerable query is sent to Jira using the invoking user's credentials. Jira authorization still limits which issues can be returned, but the injection can broaden retrieval beyond the project or issue type requested by the user. ### Attack Path 1. An attacker controls or influences the `--project` or `--issue-type` value passed to the Skill. 2. The attacker supplies a value containing additional JQL syntax that changes the query's logical structure. 3. `build_jql()` concatenates the value into the query without validation or escaping. 4. The script submits the altered query to `/rest/api/2/search`. 5. Jira returns any matching issues that the authenticated account is authorized to view. 6. The script exports the ...[truncated 808 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate project keys with a strict allowlist pattern appropriate for the Jira deployment, such as `^[A-Z][A-Z0-9_]*$`. 2. Resolve the supplied project through Jira's project API and use the canonical project identifier in the query. 3. Quote issue-type values and escape embedded JQL metacharacters according to Jira's JQL rules. 4. Prefer validated Jira IDs over free-form display names where the API supports them. 5. Reject input containing JQL operators or unexpected delimiters rather than attempting permissive sanitization. 6. Add tests covering spaces, quotes, parentheses, Boolean operators, and malformed project keys. 7. Use a read-only Jira account whose permissions are restricted to the project being analyzed, providing defense in depth against query broadening. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
代码与描述部分重合:它确实连接 Jira Server/DC、查询 Bug、并计算趋势/分布/解决时间/老化等统计维度。但声明强调的是一个端到端技能:拉取数据后进行全面 AI 分析并生成交互式 HTML 报表。给出的实际代码仅实现了数据获取、字段提取和聚合统计的后端数据准备步骤,没有任何 AI 推理、报告撰写、HTML/SVG 生成、交互式前端输出等逻辑。因此这是功能范围上的明显不一致。未声明的危险或无关资源访问未见明显存在;主要问题是声明的核心后续能力没有在代码中体现。

Credential Access

High
Category
Privilege Escalation
Content
**必填参数:**
- **Jira Server URL**: 例如 `https://jira.company.com`
- **认证方式**(二选一):
  - Personal Access Token (PAT)(推荐)
  - 用户名 + 密码
- **Project Key**: Jira 项目标识,例如 `PROJ`
Confidence
93% confidence
Finding
The skill explicitly asks for PATs or username/password credentials as conversational inputs. Collecting credentials in-band through the agent is dangerous because secrets may be exposed in chat history, logs, prompts, or downstream tool invocations, and password-based auth is especially risky.

External Script Fetching

High
Category
Supply Chain
Content
**Issue Type 自动检测**:如果脚本返回 0 条数据,可能是 Issue Type 名称不匹配。此时应通过 REST API 查询项目实际的 Issue Type 列表:
```bash
curl -u <USER>:<PASS> -k <SERVER>/rest/api/2/project/<PROJECT_KEY> | python3 -c "import sys,json;[print(t['name']) for t in json.load(sys.stdin).get('issueTypes',[])]"
```
如果发现实际名称为中文(如 `故障`、`缺陷`),用 `--issue-type` 参数指定后重新执行。
Confidence
94% confidence
Finding
The skill instructs a credentialed curl request to a user-supplied server and pipes the response into Python for processing. This is dangerous because it combines external network access, secret use, SSL bypass capability, and command composition around untrusted parameters, increasing the risk of SSRF, secret exposure, and unsafe handling of remote content.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
**Issue Type 自动检测**:如果脚本返回 0 条数据,可能是 Issue Type 名称不匹配。此时应通过 REST API 查询项目实际的 Issue Type 列表:
```bash
curl -u <USER>:<PASS> -k <SERVER>/rest/api/2/project/<PROJECT_KEY> | python3 -c "import sys,json;[print(t['name']) for t in json.load(sys.stdin).get('issueTypes',[])]"
```
如果发现实际名称为中文(如 `故障`、`缺陷`),用 `--issue-type` 参数指定后重新执行。
Confidence
97% confidence
Finding
The use of `curl -u <USER>:<PASS> -k <SERVER>` encourages insecure tool parameters: credentials on the command line and disabled certificate verification. In context, this makes credential theft and man-in-the-middle interception substantially more likely, especially on shared systems where process arguments may be observable.

Missing User Warnings

High
Confidence
98% confidence
Finding
The skill requires embedding the complete raw Jira JSON into the generated HTML and does not warn the user that the report will contain all retrieved issue data. That can expose internal bug descriptions, assignees, labels, versions, and other metadata to anyone who opens, shares, or stores the report, turning a visualization artifact into a bulk data disclosure vehicle.

Ssd 3

High
Confidence
97% confidence
Finding
The instruction to generate a downloadable Excel file containing all raw issue records creates an explicit bulk-export mechanism for sensitive Jira data. This greatly lowers the barrier to exfiltration because a single click produces a portable spreadsheet with detailed issue metadata that can be redistributed outside Jira's access controls.

Credential Access

High
Category
Privilege Escalation
Content
description="Fetch bug data from Jira Server/DC and output structured JSON."
    )
    parser.add_argument("--server", required=True, help="Jira base URL, e.g. https://jira.company.com")
    parser.add_argument("--token", help="Personal Access Token (Bearer auth)")
    parser.add_argument("--username", help="Basic Auth username")
    parser.add_argument("--password", help="Basic Auth password")
    parser.add_argument("--project", required=True, help="Jira project key, e.g. PROJ")
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill performs network-capable actions against Jira and instructs credentialed access, but it declares no explicit tool scope or allowed-tools boundary. That increases the chance of unintended tool use or overbroad execution in an agent runtime, especially because the skill also includes follow-on shell commands and API calls.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The description says to use the skill when the user wants to 'analyze Jira bugs, generate bug reports, or view bug metrics,' but it does not define clear boundaries or exclusion conditions. Phrases like '生成 Bug 报表' and especially '查看 Bug 指标' are broad enough to overlap with many general analytics or reporting requests, increasing the chance of unintended invocation.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill instructs collection of Jira credentials and issue data without any explicit warning about handling secrets or potentially sensitive project content. This is dangerous because users may provide PATs, usernames, passwords, and internal defect data directly to the agent without being told about exposure, retention, or safer alternatives.

Ssd 3

Medium
Confidence
95% confidence
Finding
Embedding the full Jira output into client-side HTML materially increases the blast radius of any sensitive data retrieved from Jira. Because the page is self-contained and portable, it is easy to email, upload, or open on unmanaged devices, causing broad disclosure of internal project and personnel data.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script accepts any server URL and does not enforce HTTPS or warn when plain HTTP is used. If a user supplies an insecure URL, Jira credentials, query contents, and returned issue data can be exposed to interception or tampering in transit.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The --no-verify option disables TLS certificate validation and only suppresses warnings, which enables man-in-the-middle attacks against both credentials and Jira data. This is especially risky for an enterprise Jira analysis skill because it routinely handles potentially sensitive bug details and authentication secrets.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The script outputs the full per-issue dataset, including summaries, assignees, reporters, labels, and other ticket metadata, not just aggregated statistics. In a skill whose stated purpose is analysis/report generation, this materially increases data exposure and makes it easier for downstream components or users to exfiltrate sensitive operational or personal information from Jira.

Natural-Language Policy Violations

Low
Confidence
77% confidence
Finding
The instructions explicitly anticipate Chinese issue type names such as '故障' and '缺陷' and direct behavior around them, but do not offer a general language or locale choice for users. While not severe, this reflects a language-specific assumption in natural-language guidance without explicit opt-in or broader locale framing.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests
Confidence
95% confidence
Finding
The dependency manifest specifies `requests` without a version pin, which makes builds non-reproducible and can silently introduce vulnerable or incompatible releases over time. In a skill that pulls Jira bug data from a server and may handle authenticated requests, dependency drift increases supply-chain risk and makes it impossible to verify whether known vulnerable versions are in use.

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
90% confidence
Finding
`requests` has multiple published advisories, and because no version is pinned, the actual installed version cannot be verified as patched. This skill's purpose—retrieving Jira Server/DC bug data—likely involves authenticated HTTP requests to internal systems, so using an affected `requests` release could expose credentials, session data, or permit other request-handling weaknesses depending on the deployed version.

Static analysis

No suspicious patterns detected.