Jira Integration
Jira Integration
The following files were used as context for generating this wiki page:
- .github/workflows/ghcr-publish.yml
- README.md
- RELEASE_3.0.0.md
- RELEASE_SUMMARY.md
- docs/V3_COMPLETE_GUIDE.md
- requirements.txt
- wshawk/advanced_cli.py
- wshawk/scanner_v2.py
Purpose and Scope
This document describes WSHawk's automated Jira integration system, which enables automatic creation of Jira Software tickets for discovered vulnerabilities. The integration is part of the Integration Collaboration Plane and supports both Jira Cloud and Jira Data Center/Server deployments.
For webhook-based notifications to Slack/Discord/Teams, see Webhook Notifications. For DefectDojo vulnerability management integration, see DefectDojo Integration.
Integration Architecture Overview
WSHawk's Jira integration operates as a post-scan automation step within the resilience-wrapped integration layer. The system converts vulnerability findings into structured Jira issues with complete reproduction details, CVSS scoring, and remediation recommendations.
Jira Integration Data Flow
graph TB
subgraph "Scanning Phase"
Scanner["WSHawkV2<br/>scanner_v2.py"]
Vulnerabilities["vulnerabilities[]<br/>List of Findings"]
end
subgraph "Configuration Resolution"
Config["WSHawkConfig<br/>wshawk.yaml"]
EnvVars["Environment Variables<br/>JIRA_EMAIL<br/>JIRA_API_TOKEN"]
CLIArgs["CLI Arguments<br/>--jira<br/>--jira-project"]
end
subgraph "Integration Layer"
JiraInt["JiraIntegration<br/>jira_connector.py"]
ResilientSession["ResilientSession<br/>Circuit Breaker<br/>Exponential Backoff"]
end
subgraph "Jira Platform"
JiraAPI["Jira REST API v2/v3<br/>/rest/api/2/issue"]
Project["Project: SEC<br/>Issue Type: Bug/Task"]
end
subgraph "Ticket Creation"
Filter["Severity Filter<br/>CRITICAL/HIGH only"]
Formatter["Ticket Formatter<br/>CVSS + Reproduction<br/>Steps"]
Tickets["Created Issues<br/>SEC-123, SEC-124"]
end
Scanner --> Vulnerabilities
Vulnerabilities --> Filter
Config --> JiraInt
EnvVars --> JiraInt
CLIArgs --> JiraInt
Filter --> Formatter
Formatter --> JiraInt
JiraInt --> ResilientSession
ResilientSession --> JiraAPI
JiraAPI --> Project
Project --> Tickets
Tickets --> Scanner
Sources: wshawk/scanner_v2.py:807-828, wshawk/advanced_cli.py:251-265
Configuration Methods
The Jira integration supports three configuration methods with hierarchical precedence: CLI flags override environment variables, which override wshawk.yaml settings.
Hierarchical Configuration System
graph LR
subgraph "Configuration Sources"
YAML["wshawk.yaml<br/>integrations.jira"]
Env["Environment Variables<br/>JIRA_EMAIL<br/>JIRA_API_TOKEN"]
CLI["CLI Flags<br/>--jira<br/>--jira-project"]
end
subgraph "WSHawkConfig Resolution"
Loader["WSHawkConfig.load()"]
Resolver["Secret Resolution<br/>env: prefix"]
Merge["Hierarchical Merge<br/>CLI > Env > YAML"]
end
subgraph "Integration Initialization"
JiraInit["JiraIntegration<br/>__init__"]
Validation["Credential Validation<br/>URL + Email + Token"]
end
YAML --> Loader
Env --> Resolver
CLI --> Merge
Loader --> Merge
Resolver --> Merge
Merge --> JiraInit
JiraInit --> Validation
Sources: README.md:137-150, wshawk/advanced_cli.py:86-98
Configuration via wshawk.yaml
The recommended method for persistent configuration is wshawk.yaml. Generate a template configuration:
python3 -m wshawk.config --generate
Edit the generated wshawk.yaml file:
integrations:
jira:
enabled: true
url: "https://yourcompany.atlassian.net"
email: "env:JIRA_EMAIL" # Resolves from environment variable
api_token: "env:JIRA_API_TOKEN" # Resolves from environment variable
project_key: "SEC"
auto_create: true
severity_filter:
- "CRITICAL"
- "HIGH"
Secret Resolution: The env: prefix indicates that the value should be resolved from an environment variable, preventing credential exposure in version control.
Sources: README.md:137-150, docs/V3_COMPLETE_GUIDE.md:337-340
Configuration via Environment Variables
For CI/CD pipelines and containerized deployments, use environment variables:
export JIRA_EMAIL="security-team@example.com"
export JIRA_API_TOKEN="your-api-token-here"
export JIRA_PROJECT="SEC"
Sources: wshawk/advanced_cli.py:252-255
Configuration via CLI Flags
For ad-hoc scans, override configuration with CLI flags:
# Basic Jira integration
wshawk-advanced ws://target.com \
--jira https://yourcompany.atlassian.net \
--jira-project SEC
# With environment credentials
export JIRA_EMAIL="user@example.com"
export JIRA_API_TOKEN="token"
wshawk-advanced ws://target.com --jira https://jira.company.com
CLI Arguments:
| Flag | Description | Default |
|------|-------------|---------|
| --jira URL | Jira instance base URL | None (disabled) |
| --jira-project KEY | Project key for ticket creation | SEC |
Sources: wshawk/advanced_cli.py:62-65
Authentication System
WSHawk uses API token authentication for Jira Cloud and Basic Auth for Jira Data Center/Server. This section describes the authentication flow and credential management.
API Token Generation
For Jira Cloud:
- Navigate to: https://id.atlassian.com/manage-profile/security/api-tokens
- Click "Create API token"
- Label: "WSHawk Security Scanner"
- Copy the generated token
- Store securely in environment variables or secrets manager
For Jira Data Center/Server:
- Use username/password or personal access tokens (PAT)
- Configure in the same way as Jira Cloud credentials
Authentication Flow
sequenceDiagram
participant CLI as "wshawk-advanced CLI"
participant Config as "WSHawkConfig"
participant JiraInt as "JiraIntegration"
participant Resilient as "ResilientSession"
participant JiraAPI as "Jira REST API"
CLI->>Config: Load configuration
Config->>Config: Resolve env:JIRA_EMAIL
Config->>Config: Resolve env:JIRA_API_TOKEN
Config->>JiraInt: Initialize(url, email, token)
JiraInt->>JiraInt: Validate credentials
JiraInt->>Resilient: Wrap HTTP session
Note over JiraInt: Scan completes
JiraInt->>Resilient: POST /rest/api/2/issue
Resilient->>Resilient: Apply exponential backoff
Resilient->>JiraAPI: Authorization: Basic base64(email:token)
JiraAPI-->>Resilient: 201 Created + issue key
Resilient-->>JiraInt: Issue created: SEC-123
JiraInt-->>CLI: Success: 3 tickets created
Authentication Header: WSHawk constructs Basic Authentication headers as base64(email:api_token) for Jira Cloud, following Atlassian's authentication standards.
Sources: wshawk/advanced_cli.py:251-265, RELEASE_SUMMARY.md:32
JiraIntegration Class
The JiraIntegration class is the core component responsible for ticket creation. It resides in wshawk/integrations/jira_connector.py and provides a high-level interface for converting vulnerability findings into Jira issues.
Class Architecture
classDiagram
class JiraIntegration {
-url: str
-email: str
-api_token: str
-project_key: str
-session: ResilientSession
+__init__(url, email, api_token, project_key)
+create_tickets(vulnerabilities, scan_info) List~str~
-_format_issue_description(vuln, scan_info) str
-_calculate_priority(cvss_score) str
-_create_single_ticket(issue_data) str
}
class ResilientSession {
+post(url, json, headers)
+get(url, headers)
}
class WSHawkV2 {
+vulnerabilities: List
+run_heuristic_scan()
}
JiraIntegration --> ResilientSession: "wraps HTTP calls"
WSHawkV2 --> JiraIntegration: "calls after scan"
Sources: wshawk/advanced_cli.py:257-263
Key Methods
| Method | Purpose | Return Type |
|--------|---------|-------------|
| __init__() | Initialize with Jira credentials and project | None |
| create_tickets() | Convert vulnerabilities to Jira issues | List[str] (issue keys) |
| _format_issue_description() | Format vulnerability details as Jira markdown | str |
| _calculate_priority() | Map CVSS score to Jira priority (Blocker/Critical/Major) | str |
Sources: wshawk/advanced_cli.py:258-265
Automatic Ticket Creation Workflow
WSHawk automatically creates Jira tickets at the end of a scan if the integration is enabled. The workflow includes severity filtering, deduplication, and resilient API calls.
Ticket Creation Pipeline
graph TB
subgraph "Scan Completion"
Complete["Scan Complete<br/>vulnerabilities[]"]
end
subgraph "Integration Check"
Enabled{"Jira Enabled?<br/>args.jira or<br/>config.jira.enabled"}
CredsCheck{"Credentials Valid?<br/>JIRA_EMAIL +<br/>JIRA_API_TOKEN"}
end
subgraph "Vulnerability Processing"
Filter["Severity Filter<br/>CRITICAL/HIGH only"]
Dedupe["Deduplication<br/>by payload hash"]
Format["Format Issue Data<br/>Summary + Description"]
end
subgraph "Resilient API Calls"
Circuit{"Circuit Breaker<br/>State?"}
Backoff["Exponential Backoff<br/>on 429/5xx"]
Create["POST /rest/api/2/issue"]
end
subgraph "Result Handling"
Success["Ticket Created<br/>SEC-123"]
Log["Logger.success<br/>3 tickets created"]
end
Complete --> Enabled
Enabled -->|Yes| CredsCheck
Enabled -->|No| Skip["Skip Integration"]
CredsCheck -->|Valid| Filter
CredsCheck -->|Invalid| Error["Logger.error<br/>Missing credentials"]
Filter --> Dedupe
Dedupe --> Format
Format --> Circuit
Circuit -->|CLOSED| Create
Circuit -->|OPEN| Backoff
Backoff --> Circuit
Create -->|201| Success
Create -->|429| Backoff
Create -->|4xx| Error
Success --> Log
Sources: wshawk/advanced_cli.py:251-265, wshawk/scanner_v2.py:807-828
Invocation Points
The Jira integration is invoked in two primary contexts:
-
CLI Scan Completion - wshawk/advanced_cli.py:251-265
if args.jira and vuln_list: # ... credential validation ... jira = JiraIntegration(url, email, api_token, project_key) tickets = await jira.create_tickets(vuln_list, scan_info) Logger.success(f"Jira: {len(tickets)} tickets created") -
Scanner Auto-Integration - wshawk/scanner_v2.py:807-828
- After report generation, if configured via
wshawk.yaml
- After report generation, if configured via
Sources: wshawk/advanced_cli.py:251-265, wshawk/scanner_v2.py:807-828
Ticket Content Structure
Jira tickets created by WSHawk follow a standardized format that includes all information necessary for security teams to reproduce, assess, and remediate vulnerabilities.
Ticket Field Mapping
| Jira Field | Source Data | Example |
|------------|-------------|---------|
| Project | project_key config | SEC |
| Issue Type | Hardcoded | Bug or Security |
| Summary | vuln['type'] + target | SQL Injection on ws://api.example.com |
| Priority | CVSS score mapping | Blocker (9.0-10.0), Critical (7.0-8.9) |
| Description | Formatted vulnerability details | See below |
| Labels | ['wshawk', 'websocket', 'automated'] | wshawk, sqli, high |
Description Template
The ticket description follows this structure:
h2. Vulnerability Details
*Type:* SQL Injection
*Severity:* HIGH
*Confidence:* HIGH
*CVSS v3.1 Score:* 8.6 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L)
h2. Target Information
*WebSocket URL:* ws://vulnerable.example.com/api/chat
*Protocol:* WebSocket (RFC 6455)
*Scan Date:* 2024-01-15 14:32:10 UTC
h2. Reproduction Steps
1. Connect to WebSocket endpoint: ws://vulnerable.example.com/api/chat
2. Send authentication handshake (if required)
3. Inject payload into message field:
{code:json}
{"action": "query", "user": "admin' OR '1'='1"}
{code}
4. Observe SQL error message in response:
{code}
{"error": "SQL syntax error near 'admin' OR '1'='1'"}
{code}
h2. Evidence
*Payload:* {code}admin' OR '1'='1{code}
*Response Snippet:* {code}SQL syntax error near 'admin'{code}
h2. Remediation
Use parameterized queries (prepared statements) to prevent SQL injection:
- For Python: Use `cursor.execute("SELECT * FROM users WHERE name=?", (user_input,))`
- For Node.js: Use parameterized queries with libraries like `pg` or `mysql2`
- Validate and sanitize all WebSocket message inputs
- Implement input length restrictions
- Apply principle of least privilege for database connections
h2. References
- OWASP WebSocket Security Cheat Sheet
- CWE-89: SQL Injection
- WSHawk Report: wshawk_report_20240115_143210.html
Sources: RELEASE_SUMMARY.md:32, docs/V3_COMPLETE_GUIDE.md:337-340
CVSS to Jira Priority Mapping
WSHawk maps CVSS v3.1 severity scores to Jira priorities using the following scheme:
graph LR
subgraph "CVSS Score Ranges"
Critical["CRITICAL<br/>9.0 - 10.0"]
High["HIGH<br/>7.0 - 8.9"]
Medium["MEDIUM<br/>4.0 - 6.9"]
Low["LOW<br/>0.1 - 3.9"]
end
subgraph "Jira Priority"
Blocker["Blocker<br/>P1"]
CriticalP["Critical<br/>P2"]
Major["Major<br/>P3"]
Minor["Minor<br/>P4"]
end
Critical --> Blocker
High --> CriticalP
Medium --> Major
Low --> Minor
Default Severity Filter: By default, only CRITICAL and HIGH severity vulnerabilities generate Jira tickets to reduce noise. This is configurable via wshawk.yaml:
integrations:
jira:
severity_filter:
- "CRITICAL"
- "HIGH"
- "MEDIUM" # Uncomment to include MEDIUM severity
Sources: RELEASE_SUMMARY.md:32
Integration with ResilientSession
All Jira API calls are wrapped in ResilientSession to handle network failures, rate limiting, and API throttling gracefully. This ensures that temporary Jira outages or rate limits do not cause scan failures.
Resilience Features
stateDiagram-v2
[*] --> Closed: "Initial State"
Closed --> Attempt: "Create Ticket"
Attempt --> Success: "201 Created"
Attempt --> Retry: "429 Rate Limited"
Attempt --> Retry: "5xx Server Error"
Attempt --> Open: "Max Retries Exceeded"
Attempt --> Failed: "4xx Client Error"
Retry --> Backoff: "Calculate Delay"
Backoff --> Attempt: "Wait Complete"
Open --> Cooldown: "60s Wait"
Cooldown --> HalfOpen: "Test Recovery"
HalfOpen --> Closed: "Success"
HalfOpen --> Open: "Still Failing"
Success --> [*]
Failed --> [*]
Circuit Breaker Behavior:
- CLOSED: Normal operation, requests proceed immediately
- OPEN: Jira is experiencing issues, fail fast for 60 seconds
- HALF_OPEN: Test if Jira has recovered with a single request
Exponential Backoff Formula:
Wait = min(60s, 2s * 2^attempt) + random(0, 1s)
Sources: RELEASE_SUMMARY.md:9-13, docs/V3_COMPLETE_GUIDE.md:134-173
Configuration Examples
Example 1: Basic Jira Integration
Minimal configuration for automated ticket creation:
# wshawk.yaml
integrations:
jira:
enabled: true
url: "https://company.atlassian.net"
email: "env:JIRA_EMAIL"
api_token: "env:JIRA_API_TOKEN"
project_key: "SEC"
auto_create: true
# Environment setup
export JIRA_EMAIL="security-scanner@company.com"
export JIRA_API_TOKEN="ATATxxxxxxxxxxxxxx"
# Run scan with automatic Jira integration
wshawk-advanced ws://target.com --full
Sources: README.md:137-150, wshawk/advanced_cli.py:251-265
Example 2: CLI-Only Integration
Override configuration entirely via CLI flags:
export JIRA_EMAIL="pentester@company.com"
export JIRA_API_TOKEN="token-here"
wshawk-advanced ws://vulnerable-app.com \
--jira https://jira.company.com \
--jira-project PENTEST \
--smart-payloads \
--playwright
This creates tickets in the PENTEST project instead of the default SEC project.
Sources: wshawk/advanced_cli.py:251-265
Example 3: CI/CD Pipeline Integration
GitHub Actions workflow with Jira integration:
name: WebSocket Security Scan
on: [push]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- name: Run WSHawk with Jira
run: |
docker run --rm \
-e JIRA_EMAIL="${{ secrets.JIRA_EMAIL }}" \
-e JIRA_API_TOKEN="${{ secrets.JIRA_API_TOKEN }}" \
rothackers/wshawk \
wshawk-advanced ws://staging.example.com \
--jira https://company.atlassian.net \
--jira-project STAGING \
--format sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: wshawk_report.sarif
Secrets Configuration:
JIRA_EMAIL: Service account emailJIRA_API_TOKEN: Scoped API token with "Create Issues" permission
Sources: docs/V3_COMPLETE_GUIDE.md:362-376
Example 4: Custom Severity Filtering
Only create tickets for CRITICAL vulnerabilities:
# wshawk.yaml
integrations:
jira:
enabled: true
url: "https://company.atlassian.net"
email: "env:JIRA_EMAIL"
api_token: "env:JIRA_API_TOKEN"
project_key: "SEC"
auto_create: true
severity_filter:
- "CRITICAL" # Only create tickets for critical issues
# Optional: Custom issue type
issue_type: "Security Vulnerability"
Sources: README.md:137-150
Troubleshooting
Common Issues and Solutions
| Issue | Cause | Solution |
|-------|-------|----------|
| Set JIRA_EMAIL and JIRA_API_TOKEN environment variables | Missing credentials | Export both environment variables before running scan |
| Jira: 401 Unauthorized | Invalid API token or email | Regenerate API token at id.atlassian.com |
| Jira: 404 Not Found | Invalid Jira URL or project | Verify base URL and project key existence |
| Jira: 0 tickets created | No HIGH/CRITICAL findings | Check severity filter or reduce filter threshold |
| Circuit Breaker OPEN | Jira API rate limit exceeded | Wait 60s for cooldown, or reduce scan frequency |
Validation Steps
Verify Jira integration configuration:
# Test credentials
curl -u "$JIRA_EMAIL:$JIRA_API_TOKEN" \
https://company.atlassian.net/rest/api/2/myself
# Verify project exists
curl -u "$JIRA_EMAIL:$JIRA_API_TOKEN" \
https://company.atlassian.net/rest/api/2/project/SEC
# Test ticket creation manually
wshawk-advanced ws://echo.websocket.org \
--jira https://company.atlassian.net \
--jira-project TEST
Sources: wshawk/advanced_cli.py:252-265
Security Considerations
Credential Management
Best Practices:
- Never commit credentials to
wshawk.yaml- useenv:prefix for secret resolution - Use dedicated service accounts with minimal permissions (create issues only)
- Rotate API tokens every 90 days
- Store tokens in secrets managers (AWS Secrets Manager, HashiCorp Vault, etc.)
- Audit Jira API access regularly via Atlassian access logs
Permission Requirements
The Jira service account requires these minimum permissions:
- Browse Projects - View project details
- Create Issues - Create new issues/bugs
- Add Comments - (Optional) Add follow-up comments
Sources: README.md:137-150
Performance and Rate Limiting
Jira API Rate Limits
Atlassian enforces the following rate limits:
| Jira Type | Rate Limit | WSHawk Behavior | |-----------|------------|-----------------| | Cloud (Free/Standard) | 300 req/min | Circuit breaker opens at threshold | | Cloud (Premium) | 1000 req/min | Exponential backoff on 429 | | Data Center | Varies by config | Respects Retry-After header |
Optimization Strategies
Batch Processing: WSHawk processes all vulnerabilities before making Jira API calls, minimizing connection overhead.
Deduplication: Identical vulnerabilities (same type + payload + target) are deduplicated to avoid creating duplicate tickets.
Async Operations: Jira ticket creation is asynchronous and non-blocking; scan reports are generated immediately even if Jira is slow.
Sources: RELEASE_SUMMARY.md:9-13