Back to skill

Security audit

Atlassian Jira by altf1be

Security checks for vulnerabilities and agentic risk

Overview

This Jira skill is mostly coherent, but it can send Jira API credentials and issue data to an unvalidated or plaintext host if configured that way.

Review before installing. Use only a trusted Jira Cloud host such as yourtenant.atlassian.net, do not set JIRA_HOST to an http:// URL or an untrusted domain, and prefer a least-privilege Jira API token that you can rotate. Be aware the skill can create, modify, transition, and delete Jira content, and can upload files you pass with the attachment command.

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

Error
Location
scripts/jira.mjs:77
Finding

Unrestricted Jira Host Allows Credential and Data Transmission over Plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: scripts/jira.mjs, lines 27 and 77–102; the same unsafe destination is used for attachment uploads at lines 477–485
Vulnerability Type: Insufficient validation of a sensitive network destination and transport
Risk Level: High

Vulnerable Code:

js
const host     = process.env.JIRA_HOST;
const email    = process.env.JIRA_EMAIL;
const apiToken = process.env.JIRA_API_TOKEN;

function authHeader() {
  const token = Buffer.from(`${CFG.email}:${CFG.apiToken}`).toString('base64');
  return `Basic ${token}`;
}

function baseUrl() {
  const host = CFG.host.replace(/\/+$/, '');
  const prefix = host.startsWith('http') ? host : `https://${host}`;
  return `${prefix}/rest/api/3`;
}

async function jiraFetch(path, options = {}, retries = 3) {
  const url = path.startsWith('http') ? path : `${baseUrl()}${path}`;
  const headers = {
    'Authorization': authHeader(),
    'Accept': 'application/json',
    ...options.headers,
  };

  if (!(options.body instanceof FormData)) {
    headers['Content-Type'] = headers['Content-Type'] || 'application/json';
  }

  for (let attempt = 1; attempt <= retries; attempt++) {
    const resp = await fetch(url, { ...options, headers });
    // ...
  }
}

The attachment upload uses the same unchecked base URL and credential:

js
const url = `${baseUrl()}/issue/${options.key}/attachments`;
const resp = await fetch(url, {
  method: 'POST',
  headers: {
    'Authorization': authHeader(),
    'X-Atlassian-Token': 'no-check',
  },
  body: form,
});

Technical Analysis

JIRA_HOST is taken directly from the environment without parsing or validating its protocol, hostname, port, path, query, or fragment. If it starts with the characters http, baseUrl() accepts it unchanged. This includes plaintext http:// URLs and arbitrary non-Atlassian servers.

...[truncated 2949 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse JIRA_HOST with new URL() rather than using string-prefix checks.
  2. Require url.protocol === "https:"; reject plaintext HTTP under all circumstances.
  3. For the declared Jira Cloud use case, restrict the destination to the expected tenant hostname or an explicit allowlist, such as a validated subdomain of atlassian.net.
  4. Reject embedded usernames or passwords, unexpected ports, paths, query strings, and fragments in JIRA_HOST.
  5. Construct API URLs from validated URL components rather than string concatenation.
  6. Remove support for absolute URLs in jiraFetch(), or separately validate absolute destinations and never attach authorization credentials to a different origin.
  7. Set redirect: "error" or manually process redirects while ensuring the Authorization header is never forwarded across origins.
  8. Apply the same centralized validated HTTP client to attachment uploads instead of using a separate direct fetch() call.
  9. Fail closed with a clear configuration error when host validation fails.
  10. Document that users should create a least-privilege Jira API token and rotate it immediately if an untrusted or plaintext host may have been used.
  11. Add automated tests covering http://, attacker-controlled domains, deceptive hostnames, embedded credentials, unusual ports, paths, and cross-origin redirects.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (6)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

md
npm install

# 3. Configure
cp .env.example .env
# Edit .env with your Jira Cloud credentials

# 4. Use

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

md
// ── Config ──────────────────────────────────────────────────────────────────

config(); // load .env

let _cfg;
function getCfg() {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/jira.mjs (reported line 21)May include surrounding context.

js
// ── Config ──────────────────────────────────────────────────────────────────

config(); // load .env

let _cfg;
function getCfg() {

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill explicitly requires environment variables containing Jira credentials and performs outbound network operations against the Jira REST API, but it does not declare any tool scope such as permissions or allowed-tools. That mismatch weakens sandboxing and informed consent because an agent or user may invoke a skill with broader access than is transparently documented, increasing the risk of unintended credential use or remote actions in Jira.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

The dependency uses a caret range (^12.0.0), which permits automatic installation of newer minor/patch releases. While common in Node.js projects, this weakens supply-chain reproducibility and can expose consumers to a compromised or breaking upstream release without any code change in this skill. In a credentialed Jira automation skill, dependency compromise could affect API tokens or issue data handled by the CLI.

Content

Scanner excerpt · package.json (reported line 29)May include surrounding context.

json
"url": "https://github.com/ALT-F1-OpenClaw/openclaw-skill-atlassian-jira.git"
  },
  "dependencies": {
    "commander": "^12.0.0",
    "dotenv": "^16.0.0"
  },
  "engines": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

The dependency uses a caret range (^16.0.0), allowing npm to resolve newer compatible releases automatically. This creates a supply-chain risk and reduces build determinism; if the package or one of its transitive dependencies is compromised, the skill could ingest malicious code during installation. Because this skill likely processes Jira credentials from environment files, a dependency compromise could expose sensitive tokens.

Content

Scanner excerpt · package.json (reported line 30)May include surrounding context.

json
},
  "dependencies": {
    "commander": "^12.0.0",
    "dotenv": "^16.0.0"
  },
  "engines": {
    "node": ">=18.0.0"

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/jira.mjs:27