prowler-attack-paths-query
Creates Prowler Attack Paths openCypher queries for graph analysis (compatible with Neo4j and Neptune). Trigger: When creating or updating Attack Paths queries that detect privilege escalation paths, network exposure, or security misconfigurations in cloud environments.
Install
mkdir -p .claude/skills/prowler-attack-paths-query && curl -L -o skill.zip "https://mcp.directory/api/skills/download/5163" && unzip -o skill.zip -d .claude/skills/prowler-attack-paths-query && rm skill.zipInstalls to .claude/skills/prowler-attack-paths-query
About this skill
Overview
Attack Paths queries are openCypher queries that analyze cloud infrastructure graphs (ingested via Cartography) to detect security risks like privilege escalation paths, network exposure, and misconfigurations.
Queries are written in openCypher Version 9 for compatibility with both Neo4j and Amazon Neptune.
Two query audiences
This skill covers two types of queries with different isolation mechanisms:
| Predefined queries | Custom queries | |
|---|---|---|
| Where they live | api/src/backend/api/attack_paths/queries/{provider}.py | User/LLM-supplied via the custom query API endpoint |
| Provider isolation | AWSAccount {id: $provider_uid} anchor + path connectivity | Automatic _Provider_{uuid} label injection via cypher_sanitizer.py |
| What to write | Chain every MATCH from the aws variable | Plain Cypher, no isolation boilerplate needed |
| Internal labels | Never use (_ProviderResource, _Tenant_*, _Provider_*) | Never use (injected automatically by the system) |
For predefined queries: every node must be reachable from the AWSAccount root via graph traversal. This is the isolation boundary.
For custom queries: write natural Cypher without isolation concerns. The query runner injects a _Provider_{uuid} label into every node pattern before execution, and a post-query filter catches edge cases.
Input Sources
Queries can be created from:
-
pathfinding.cloud ID (e.g.,
ECS-001,GLUE-001)- Reference: https://github.com/DataDog/pathfinding.cloud
- The aggregated
paths.jsonis too large for WebFetch. Use Bash:
# Fetch a single path by ID curl -s https://raw.githubusercontent.com/DataDog/pathfinding.cloud/main/docs/paths.json \ | jq '.[] | select(.id == "ecs-002")' # List all path IDs and names curl -s https://raw.githubusercontent.com/DataDog/pathfinding.cloud/main/docs/paths.json \ | jq -r '.[] | "\(.id): \(.name)"' # Filter by service prefix curl -s https://raw.githubusercontent.com/DataDog/pathfinding.cloud/main/docs/paths.json \ | jq -r '.[] | select(.id | startswith("ecs")) | "\(.id): \(.name)"'If
jqis not available, usepython3 -c "import json,sys; ..."as a fallback. -
Natural language description from the user
Query Structure
Provider scoping parameter
One parameter is injected automatically by the query runner:
| Parameter | Property it matches | Used on | Purpose |
|---|---|---|---|
$provider_uid | id | AWSAccount | Scopes to a specific AWS account |
All other nodes are isolated by path connectivity from the AWSAccount anchor.
Imports
All query files start with these imports:
from api.attack_paths.queries.types import (
AttackPathsQueryAttribution,
AttackPathsQueryDefinition,
AttackPathsQueryParameterDefinition,
)
from tasks.jobs.attack_paths.config import PROWLER_FINDING_LABEL
The PROWLER_FINDING_LABEL constant (value: "ProwlerFinding") is used via f-string interpolation in all queries. Never hardcode the label string.
Privilege escalation sub-patterns
There are four distinct privilege escalation patterns. Choose based on the attack type:
| Sub-pattern | Target | path_target shape | Example |
|---|---|---|---|
| Self-escalation | Principal's own policies | (aws)--(target_policy:AWSPolicy)--(principal) | IAM-001 |
| Lateral to user | Other IAM users | (aws)--(target_user:AWSUser) | IAM-002 |
| Assume-role lateral | Assumable roles | (aws)--(target_role:AWSRole)<-[:STS_ASSUMEROLE_ALLOW]-(principal) | IAM-014 |
| PassRole + service | Service-trusting roles | (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(...) | EC2-001 |
Self-escalation (e.g., IAM-001)
The principal modifies resources attached to itself. path_target loops back to principal:
AWS_{QUERY_NAME} = AttackPathsQueryDefinition(
id="aws-{kebab-case-name}",
name="{Human-friendly label} ({REFERENCE_ID})",
short_description="{Brief explanation, no technical permissions.}",
description="{Detailed description of the attack vector and impact.}",
attribution=AttackPathsQueryAttribution(
text="pathfinding.cloud - {REFERENCE_ID} - {permission}",
link="https://pathfinding.cloud/paths/{reference_id_lowercase}",
),
provider="aws",
cypher=f"""
// Find principals with {permission}
MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
WHERE stmt.effect = 'Allow'
AND any(action IN stmt.action WHERE
toLower(action) = '{permission_lowercase}'
OR toLower(action) = '{service}:*'
OR action = '*'
)
// Find target resources attached to the same principal
MATCH path_target = (aws)--(target_policy:AWSPolicy)--(principal)
WHERE target_policy.arn CONTAINS $provider_uid
AND any(resource IN stmt.resource WHERE
resource = '*'
OR target_policy.arn CONTAINS resource
)
WITH collect(path_principal) + collect(path_target) AS paths
UNWIND paths AS p
UNWIND nodes(p) AS n
WITH paths, collect(DISTINCT n) AS unique_nodes
UNWIND unique_nodes AS n
OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL'}})
RETURN paths, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
""",
parameters=[],
)
Other sub-pattern path_target shapes
The other 3 sub-patterns share the same path_principal, deduplication tail, and RETURN as self-escalation. Only the path_target MATCH differs:
// Lateral to user (e.g., IAM-002) - targets other IAM users
MATCH path_target = (aws)--(target_user:AWSUser)
WHERE any(resource IN stmt.resource WHERE resource = '*' OR target_user.arn CONTAINS resource OR resource CONTAINS target_user.name)
// Assume-role lateral (e.g., IAM-014) - targets roles the principal can assume
MATCH path_target = (aws)--(target_role:AWSRole)<-[:STS_ASSUMEROLE_ALLOW]-(principal)
WHERE any(resource IN stmt.resource WHERE resource = '*' OR target_role.arn CONTAINS resource OR resource CONTAINS target_role.name)
// PassRole + service (e.g., EC2-001) - targets roles trusting a service
MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {arn: '{service}.amazonaws.com'})
WHERE any(resource IN stmt.resource WHERE resource = '*' OR target_role.arn CONTAINS resource OR resource CONTAINS target_role.name)
Multi-permission: PassRole queries require a second permission. Add MATCH (principal)--(policy2:AWSPolicy)--(stmt2:AWSPolicyStatement) with its own WHERE before path_target, then check BOTH stmt.resource AND stmt2.resource against the target. See IAM-015 or EC2-001 in aws.py for examples.
Network exposure pattern
The Internet node is reached via CAN_ACCESS through the already-scoped resource, not via a standalone lookup:
AWS_{QUERY_NAME} = AttackPathsQueryDefinition(
id="aws-{kebab-case-name}",
name="{Human-friendly label}",
short_description="{Brief explanation.}",
description="{Detailed description.}",
provider="aws",
cypher=f"""
// Match exposed resources (MUST chain from `aws`)
MATCH path = (aws:AWSAccount {{id: $provider_uid}})--(resource:EC2Instance)
WHERE resource.exposed_internet = true
// Internet node reached via path connectivity through the resource
OPTIONAL MATCH (internet:Internet)-[can_access:CAN_ACCESS]->(resource)
WITH collect(path) AS paths, head(collect(internet)) AS internet, collect(can_access) AS can_access
UNWIND paths AS p
UNWIND nodes(p) AS n
WITH paths, internet, can_access, collect(DISTINCT n) AS unique_nodes
UNWIND unique_nodes AS n
OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL'}})
RETURN paths, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr,
internet, can_access
""",
parameters=[],
)
Register in query list
Add to the {PROVIDER}_QUERIES list at the bottom of the file:
AWS_QUERIES: list[AttackPathsQueryDefinition] = [
# ... existing queries ...
AWS_{NEW_QUERY_NAME}, # Add here
]
Step-by-step creation process
1. Read the queries module
FIRST, read all files in the queries module to understand the structure, type definitions, registration, and existing style:
api/src/backend/api/attack_paths/queries/
├── __init__.py # Module exports
├── types.py # AttackPathsQueryDefinition, AttackPathsQueryParameterDefinition
├── registry.py # Query registry logic
└── {provider}.py # Provider-specific queries (e.g., aws.py)
DO NOT use generic templates. Match the exact style of existing queries in the file.
2. Fetch and consult the Cartography schema
This is the most important step. Every node label, property, and relationship in the query must exist in the Cartography schema for the pinned version. Do not guess or rely on memory.
Check api/pyproject.toml for the Cartography dependency, then fetch the schema:
grep cartography api/pyproject.toml
Build the schema URL (ALWAYS use the specific tag, not master/main):
# Git dependency (prowler-cloud/cartography@0.126.1):
https://raw.githubusercontent.com/prowler-cloud/cartography/refs/tags/0.126.1/docs/root/modules/{provider}/schema.md
# PyPI dependency (cartography = "^0.126.0"):
https://raw.githubusercontent.com/cartography-cncf/cartography/refs/tags/0.126.0/docs/root/modules/{provider}/schema.md
Read the schema to discover available node labels, properties, and
Content truncated.
More by prowler-cloud
View all skills by prowler-cloud →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
Related MCP Servers
Browse all serversBreak down complex problems with Sequential Thinking, a structured tool and step by step math solver for dynamic, reflec
Structured spec-driven development workflow for AI-assisted software development. Creates detailed specifications before
Vizro creates and validates data-visualization dashboards from natural language, auto-generating chart code and interact
Acemcp: semantic code search across codebases with incremental indexing. Find relevant snippets, file paths and line num
Convert Figma designs into clean HTML & CSS with customizable file paths and organization—fast, accurate code generation
Generate and edit images instantly using GPT Image Generator, an advanced AI image generator for creative visual content
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.