claude/plugins/fix-prodsec-vulnerabilities/skills/fix-prodsec-vulnerabilities/SKILL.md
Discover vulnerabilities from Jira and automatically fix GitHub Dependabot alerts by applying dependency updates. Use when asked to: fix vulnerabilities, fix Dependabot alerts, remediate security issues, fix VDB tickets, or run /fix-prodsec-vulnerabilities.
npx skillsauth add raphi011/skills fix-prodsec-vulnerabilitiesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are a Security Engineer. This skill discovers Jira vulnerabilities with GitHub Dependabot alerts, analyzes the fix strategy, applies dependency updates, and creates a pull request.
CLI tools — must be installed and on your PATH:
gh (GitHub CLI) — authenticated via gh auth login with access to your org's reposgit — configured with push access to the target repositoriesClaude Code configuration:
mcp__plugin_atlassian_atlassian__getAccessibleAtlassianResources return your cloud ID?Permissions required:
| System | Access needed | |---|---| | Jira | Read access to the "Vulnerability Database" project | | GitHub | Read Dependabot alerts on target repos | | GitHub | Create branches and pull requests on target repos | | GitHub | Clone repos (if not already local) |
Target repositories must have one of:
./gradlew (Gradle wrapper) — for Gradle-based projects./mvnw (Maven wrapper) — for Maven-based projects$ARGUMENTS
Parse $ARGUMENTS to determine the execution path:
Path A — Jira ticket ID (matches VDB-\d+):
VDB-35671)Path B — Assignee with optional project filter:
john.smith or "John Smith")piperine translator), or empty for all projectsPath C — No arguments:
Examples:
/fix-prodsec-vulnerabilities VDB-35671 → Path A, fix that specific ticket/fix-prodsec-vulnerabilities john.smith piperine → Path B, discover for "John Smith" in piperine/fix-prodsec-vulnerabilities john.smith piperine translator → Path B, discover in piperine + translator/fix-prodsec-vulnerabilities john.smith → Path B, discover across all projectsGet Atlassian Cloud ID via mcp__plugin_atlassian_atlassian__getAccessibleAtlassianResources. Store for reuse in Phase 5.
Execute JQL query via mcp__plugin_atlassian_atlassian__searchJiraIssuesUsingJql:
["summary", "description", "status", "priority", "assignee", "created", "updated", "labels", "duedate", "Segment[Dropdown]", "Severity[Dropdown]"]project = "Vulnerability Database" AND issuetype = Vulnerability AND statusCategory != Done AND labels = burman AND duedate >= startOfDay() AND "Segment[Dropdown]" = "Core Systems" AND "Severity[Dropdown]" in (High, Critical, Major) AND assignee = "{normalized_assignee}"{project_clause}
Where {project_clause} is:
AND textfields ~ "proj1" for single project AND textfields ~ "proj1 OR proj2" for multiple projectsInput sanitization: Before inserting project names into JQL, strip any characters that are not alphanumeric, hyphens, or underscores (i.e., remove quotes, parentheses, backslashes, and other JQL-special characters). If a project name is empty after sanitization, skip it. This prevents JQL injection from malformed input.
For each issue, extract alert_url from description using regex: \|\s*alert_url\s*\|\s*(https://github\.com/[^\s|]+)\s*\|
Keep only issues with valid GitHub Dependabot alert URLs.
Sort by due date (soonest first) and display:
=================================================================
VULNERABILITY DISCOVERY - GitHub Dependabot Alerts
=================================================================
Query: [JQL used]
Found: [X] total issues, [Y] with Dependabot alerts
=================================================================
# | KEY | DUE DATE | SEVERITY | REPOSITORY | ALERT
--|-----------|------------|----------|--------------|-------
1 | VDB-35671 | 2026-01-14 | High | piperine | ...bot/79
=================================================================
Let user select ONE vulnerability via AskUserQuestion (multiSelect=false):
"{VDB-KEY} - {Severity} - {Repository/Package}""Due: {date} | Alert: {short-url}"If Path A (direct ticket ID): Fetch the Jira ticket via mcp__plugin_atlassian_atlassian__getJiraIssue or mcp__plugin_atlassian_atlassian__searchJiraIssuesUsingJql with key = "{VDB-KEY}". Extract alert_url from description using the same regex. If no valid Dependabot URL found, inform user and stop.
Parse the GitHub URL to extract owner, repo, and alert_number.
Fetch alert details: gh api repos/{owner}/{repo}/dependabot/alerts/{alert_number}
Extract: security_vulnerability.package.name, .vulnerable_version_range, .first_patched_version.identifier, security_advisory.cve_id, .summary, dependency.package.ecosystem, dependency.manifest_path, state.
If state is not "open", inform user and stop.
Check for existing Dependabot PRs: gh pr list --repo {owner}/{repo} --state open --app dependabot --json number,title,url,body
Match by package name in title/body.
If existing PR found: Display it and ask user via AskUserQuestion:
If no existing PR: Continue to Phase 3.
Clone or navigate to the repository. If not local: gh repo clone {owner}/{repo} /tmp/{repo}. If /tmp/{repo} already exists from a previous run, remove it first (rm -rf /tmp/{repo}) to avoid stale state.
Create feature branch before making any changes: git checkout -b fix-{VDB-KEY}-{package-name}
Analyze dependency tree (./gradlew dependencies or ./mvnw dependency:tree) to determine if the vulnerable package is direct or transitive.
Determine fix strategy (in preference order):
resolutionStrategy.force() (Gradle) or <dependencyManagement> (Maven), with a comment explaining why. Caveat: force() only works for same-artifact version upgrades. For vulnerabilities where the fix requires a different artifact (e.g., org.lz4:lz4-java → at.yawk.lz4:lz4-java), use dependencySubstitution instead.Apply the fix: edit the build file (pom.xml / build.gradle / build.gradle.kts). Also remove any obsolete force() calls or dependency management overrides that are no longer needed.
Verify the fix:
./gradlew dependencyInsight --dependency {package} (or ./mvnw dependency:tree | grep {package})./gradlew test or ./mvnw testPresent verification results and use AskUserQuestion: "Fix verified. Proceed with commit, push, and PR creation?" If user declines, stop.
Stage and commit using heredoc:
git add {modified-files} && git commit -m "$(cat <<'EOF'
[{VDB-KEY}] Fix {severity} severity {package} vulnerability
Fixed GitHub Dependabot alert from Jira:
- {VDB-KEY}: {package} {old-version} -> {new-version} ({CVE}: {summary})
Strategy: {strategy description}
Reason: {why this strategy was chosen}
Alert URL: {github-alert-url}
Verification:
- Dependency resolution: {old} -> {new} confirmed
- Tests: {results summary}
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
EOF
)"
Push: git push -u origin {branch-name}
Create PR:
gh pr create --title "[{VDB-KEY}] Fix {severity} severity {package} vulnerability" --body "$(cat <<'EOF'
## Summary
- **{VDB-KEY}**: {package} {old-version} -> {new-version}
- **CVE**: {CVE-ID} - {description}
- **Severity**: {severity}
- **Strategy**: {strategy description}
## Verification
- Dependency resolution confirmed: `{old-version} -> {new-version}`
- Unit tests: {PASSED/FAILED with details}
## Test plan
- [x] Dependency insight verification
- [x] Unit tests
- [ ] CI/CD pipeline validation
- [ ] Verify Dependabot alert closes after merge
## Links
- Jira: [{VDB-KEY}]({jira-url})
- Dependabot Alert: {github-alert-url}
Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"
Construct the Jira ticket URL using the Cloud ID from Phase 1 (or fetch via mcp__plugin_atlassian_atlassian__getAccessibleAtlassianResources if Path A): https://{site-name}.atlassian.net/browse/{VDB-KEY}
Display summary:
=================================================================
VULNERABILITY REMEDIATION SUMMARY
=================================================================
Discovery: Found {X} issues, {Y} with Dependabot alerts
Selected: {VDB-KEY}
Repository: {repo}
{status_icon} {package} v{old} -> v{new}
CVE: {CVE-ID} | Severity: {severity}
Strategy: {strategy}
Jira: {jira-url}
Alert: {github-alert-url}
PR: {pr-url or "Skipped - existing Dependabot PR: {existing-pr-url}"}
=================================================================
Next Steps:
- {context-appropriate next steps}
- Run this command again to fix additional vulnerabilities
When reporting for Path A (direct ticket), omit the discovery stats line.
If the repository was cloned to /tmp/{repo}, remove it after Phase 4 completes (or after any phase failure): rm -rf /tmp/{repo}. This prevents stale clones from accumulating.
If any phase fails (invalid URL, API error, build failure, git conflict), log the error clearly, run cleanup, and stop. Do not retry silently. Only modify dependency configuration files — never test files or application code.
development
Create polished, professional reveal.js presentations. Use when the user asks to create slides, a presentation, a deck, or a slideshow. Supports themes, multi-column layouts, code highlighting, animations, speaker notes, and custom styling. Generates HTML + CSS with no build step required.
tools
Use when writing Tailwind CSS v4 code, configuring Tailwind v4 with @theme or @variant directives, migrating from Tailwind v3 to v4, setting up CSS-native config (no tailwind.config.js), defining semantic color tokens, implementing dark mode with class-based @variant, creating design system tokens, or styling components with utility classes. Covers @import "tailwindcss", @theme blocks, @variant, @layer, CSS custom properties for colors, and common layout/component patterns.
development
Use whenever working with SurrealDB — writing queries, defining schemas, configuring indexes, debugging errors, handling record IDs, using the Go SDK, or discussing SurrealDB architecture. Activate on any mention of SurrealDB, SurrealQL, HNSW indexes, or surreal-related Go SDK code.
development
Use when visually verifying terminal UI rendering, testing TUI interactions, debugging Bubbletea display issues, or when asked to "test the TUI", "screenshot the terminal", "check what the TUI looks like", or "visually verify". Requires Kitty terminal with allow_remote_control and macOS for screencapture.