Skip to content

feat(attack-paths): Add 4 IAM privilege escalation detection queries - #11460

Merged
danibarranqueroo merged 6 commits into
prowler-cloud:masterfrom
paramanandmallik:add-iam-privesc-attack-paths-queries
Jul 31, 2026
Merged

feat(attack-paths): Add 4 IAM privilege escalation detection queries#11460
danibarranqueroo merged 6 commits into
prowler-cloud:masterfrom
paramanandmallik:add-iam-privesc-attack-paths-queries

Conversation

@paramanandmallik

@paramanandmallik paramanandmallik commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Context

Adds 8 openCypher queries that detect IAM privilege escalation patterns in AWS environments. These queries analyze Cartography-ingested graph data to identify principals with dangerous permission combinations that enable lateral movement and privilege escalation.

What's Included

# Query ID Attack Pattern
1 aws-iam-privesc-cross-account-no-external-id Cross-account role without ExternalId → confused deputy
2 aws-iam-privesc-wildcard-trust Role trust with Principal: "*" → universal access
3 aws-iam-privesc-update-trust-self-assume UpdateAssumeRolePolicy → inject self into any role trust
4 aws-iam-privesc-passrole-lambda PassRole + Lambda CreateFunction + InvokeFunction
5 aws-iam-privesc-passrole-ec2 PassRole + RunInstances → IMDS credential theft
6 aws-iam-privesc-create-policy-version-self-escalation CreatePolicyVersion with wildcard resource → instant admin
7 aws-iam-privesc-boundary-removal DeletePermissionsBoundary → unlock unconstrained access
8 aws-sso-privesc-permission-set-escalation SSO CreatePermissionSet + CreateAccountAssignment → org-wide admin

Research Source

All queries are based on documented attack paths from pathfinding.cloud PR #29. Each query's attribution field links directly to the corresponding documented path.

Compatibility

  • Queries use openCypher v9 syntax compatible with both Neo4j and Amazon Neptune
  • No CALL subqueries (Neptune limitation)
  • No mutating statements (read-only enforcement)
  • All queries use $provider_uid for account scoping and include the Prowler findings join

What Was Tested

  • All 145 structural validation tests pass (test_attack_paths_queries.py)
  • All 61 existing attack paths tests continue to pass
  • No duplicate query IDs in the registry
  • Python syntax validation passes

Checklist

  • Queries are read-only (no CREATE/MERGE/SET/DELETE)
  • Each query uses $provider_uid for account scoping
  • Each query ends with the Prowler findings UNWIND/OPTIONAL MATCH
  • Attribution links point to valid pathfinding.cloud paths
  • Query IDs are unique and follow kebab-case convention
  • Queries are registered in AWS_QUERIES list
  • Under 10,000 character limit per query
  • Tests added for structural validation of all new queries

Summary by CodeRabbit

  • New Features
    • Added four new AWS privilege-escalation attack-path detection queries: STS cross-account trust, STS wildcard trust, IAM permission-boundary removal, and Identity Center permission-set escalation.
  • Tests
    • Added comprehensive tests to validate query registration, required metadata, Cypher compatibility/safety constraints, and uniqueness of query IDs.

@github-actions github-actions Bot added component/api community Opened by the Community labels Jun 3, 2026
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

No Conflicts

No conflict markers, and the branch merges cleanly into its base.

@paramanandmallik
paramanandmallik marked this pull request as ready for review June 3, 2026 16:50
@paramanandmallik
paramanandmallik requested a review from a team as a code owner June 3, 2026 16:50
@paramanandmallik

Copy link
Copy Markdown
Contributor Author

@tmonk42 @kij @slmingol @dlorch When can I expect an update on this PR?

…d graph schema

Rewrite the IAM/STS/SSO privilege-escalation queries so they run correctly on
the Cartography graph and on both Neo4j and Neptune sinks:

- Traverse HAS_ACTION/HAS_RESOURCE child item nodes instead of reading
  stmt.action/stmt.resource, which are normalized off the statement node at sync
- Replace any()/=~ (unsupported on Neptune) with size([...]) > 0 and CONTAINS
- Type the finding probe (:HAS_FINDING) and filter ProwlerFinding on status only
  (the node carries no provider_uid), and restore the paths/dpf/dpfr RETURN contract
- Drop four queries that duplicate existing catalog coverage
  (EC2-001, IAM-001, LAMBDA-001, and UpdateAssumeRolePolicy/IAM-012)
- Keep the four genuinely new paths with correct reference IDs: STS-002
  (cross-account trust), STS-003 (wildcard trust), IAM-022 (user permissions-
  boundary removal), and SSO-001 (permission-set escalation)
- Rewrite the structural tests to assert these conventions

Verified against the dev graph: all four execute and match the expected resources.
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds four AWS privilege-escalation attack-path queries for STS trust, IAM permissions-boundary deletion, and Identity Center permission-set escalation. Registers and documents them, with structural and Cypher compatibility tests.

Changes

AWS attack-path query expansion

Layer / File(s) Summary
Privilege-escalation query definitions
api/src/backend/api/attack_paths/queries/aws.py, api/changelog.d/...
Adds STS-002, STS-003, IAM-022, and SSO-001 queries, registers them in AWS_QUERIES, and documents the additions.
Query contract and compatibility validation
api/src/backend/api/tests/test_attack_paths_queries.py
Validates registration, metadata, read-only Cypher, Neptune compatibility, finding linkage, account anchoring, and unique query IDs.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested reviewers: adriiiprodri

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding four IAM privilege-escalation detection queries.
Description check ✅ Passed The description is detailed and well-structured, covering context, included queries, compatibility, testing, and checklist items.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@danibarranqueroo

Copy link
Copy Markdown
Member

Hi @paramanandmallik — thanks a lot for this, and for digging into the pathfinding.cloud paths! 🙏

Heads-up on a few things I pushed a fix commit for:

  • 4 of the 8 were already covered in the catalog (EC2-001, IAM-001, LAMBDA-001, and UpdateAssumeRolePolicy = IAM-012), so I dropped those to avoid duplicates.
  • The other 4 I kept and rewrote to match our conventions: STS-002 (cross-account trust), STS-003 (wildcard trust), IAM-022 (user permissions-boundary removal), and SSO-001 (permission-set escalation).
  • Main reason for the rewrite: action/resource aren't fields on the statement node (they're normalized into HAS_ACTION/HAS_RESOURCE child nodes), and any()/=~ aren't supported on Neptune — so the originals returned nothing. The corrected versions use the child-node traversal + size([...]) > 0, the typed HAS_FINDING probe, and the standard paths, dpf, dpfr return shape.

I tested all four against a real dev graph and they return the expected resources. Really appreciate the contribution — this got us solid new coverage. 🚀

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@api/src/backend/api/tests/test_attack_paths_queries.py`:
- Around line 141-144: Fix the assertion in the query validation test so the
searched needle and query text use the same whitespace normalization. Preserve
the intended check that no query filters the finding node on the non-existent
provider_uid property, and keep the existing query.id failure context.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9af5d84d-70f2-4a29-ae6a-89fb2a50c58d

📥 Commits

Reviewing files that changed from the base of the PR and between eb7949c and 1c47e7c.

📒 Files selected for processing (2)
  • api/src/backend/api/attack_paths/queries/aws.py
  • api/src/backend/api/tests/test_attack_paths_queries.py

Comment thread api/src/backend/api/tests/test_attack_paths_queries.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@api/src/backend/api/attack_paths/queries/aws.py`:
- Around line 3617-3618: Update the IAM action predicates in the affected
attack-path queries to match Neptune-compatible glob patterns, supporting exact
actions, service-wide patterns such as iam:*, and partial * or ? wildcards in
action names. Avoid any() and =~, and apply the same matcher consistently to the
logic around the existing act.value filters.
- Around line 3615-3618: Update the IAM-022 query to model an actual
self-boundary removal: require the authorized principal to be the targeted AWS
user, ensure a permissions boundary is attached to that user, and match the
policy statement resource to the same user. Exclude roles, unrelated users, and
statements lacking a concrete boundary-removal target while preserving valid
wildcard action handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: cf446600-daf5-452f-ae49-ddbaf6b5b220

📥 Commits

Reviewing files that changed from the base of the PR and between 1c47e7c and 43c35bd.

📒 Files selected for processing (2)
  • api/changelog.d/attack-paths-pathfinding-privesc-queries.added.md
  • api/src/backend/api/attack_paths/queries/aws.py

Comment thread api/src/backend/api/attack_paths/queries/aws.py Outdated
Comment thread api/src/backend/api/attack_paths/queries/aws.py
@danibarranqueroo danibarranqueroo self-assigned this Jul 29, 2026
…t order

The provider_uid finding-probe assertion stripped spaces from the query text
but kept a space in the needle, so it could never match. Remove the space so
the check actually catches a provider_uid filter on the finding node. Also sort
the import block to satisfy ruff (I001).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@api/src/backend/api/tests/test_attack_paths_queries.py`:
- Around line 140-143: Update the assertion in the query test to use a
whitespace-tolerant regular expression that matches provider_uid only within the
ProwlerFinding node pattern. Replace the space-only normalization and global
substring check, preserving the test’s intent to reject provider_uid filtering
on findings while allowing the property on unrelated nodes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f75bcdd9-bafa-49b3-bcf3-b9804ca0b3f8

📥 Commits

Reviewing files that changed from the base of the PR and between 43c35bd and 36511d7.

📒 Files selected for processing (1)
  • api/src/backend/api/tests/test_attack_paths_queries.py

Comment thread api/src/backend/api/tests/test_attack_paths_queries.py
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 29, 2026
@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.51%. Comparing base (03f2ab4) to head (6e9db59).
⚠️ Report is 27 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #11460      +/-   ##
==========================================
+ Coverage   94.37%   94.51%   +0.14%     
==========================================
  Files         268      270       +2     
  Lines       41109    41885     +776     
==========================================
+ Hits        38796    39588     +792     
+ Misses       2313     2297      -16     
Flag Coverage Δ
api 94.51% <100.00%> (+0.14%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
prowler ∅ <ø> (∅)
api 94.51% <100.00%> (+0.14%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@danibarranqueroo danibarranqueroo changed the title feat(attack-paths): Add 8 IAM privilege escalation detection queries feat(attack-paths): Add 4 IAM privilege escalation detection queries Jul 30, 2026
@josema-xyz

Copy link
Copy Markdown
Contributor

Changes made

  • Marked STS-003 as a potential issue that needs manual review.
  • Limited IAM-022 to users that can remove their own permissions boundary.
  • Updated SSO-001 to require Resource: "*" for all three permissions. This avoids mixing permissions for unrelated resources.
  • Added regression tests for these cases.

@danibarranqueroo
danibarranqueroo merged commit 88c666a into prowler-cloud:master Jul 31, 2026
44 checks passed
danibarranqueroo added a commit that referenced this pull request Jul 31, 2026
Resolve the aws.py Attack Paths conflict by keeping the union of all queries
(the 20 pathfinding privesc queries from this PR plus STS-002/003, IAM-022 and
SSO-001 merged from #11460) and re-sorting the whole pathfinding privesc section
and the AWS_QUERIES list by service then number, so the previously appended
queries land in their correct ordered positions (e.g. IAM-022/023 after IAM-021,
SSO-* between SSM and STS).
danibarranqueroo added a commit that referenced this pull request Jul 31, 2026
…privesc queries

Apply the same resource-scoping used for their IAM-022/SSO-001 siblings (#11460):
- IAM-023: require the iam:DeleteRolePermissionsBoundary statement resource to
  cover the assumable target role's ARN (not just that the action exists), and
  note in the description that boundary attachment is not recorded in the graph.
- SSO-002/003: require the sso action on a wildcard resource, since permission
  sets are not graph nodes and cannot otherwise be scoped to the actor.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community Opened by the Community component/api

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants