Skip to content

feat: detect + link pathfinding.cloud privilege-escalation paths (37 new detections)#584

Merged
kmcquade merged 2 commits into
masterfrom
feat/privesc-pathfinding-links
May 30, 2026
Merged

feat: detect + link pathfinding.cloud privilege-escalation paths (37 new detections)#584
kmcquade merged 2 commits into
masterfrom
feat/privesc-pathfinding-links

Conversation

@kmcquade
Copy link
Copy Markdown
Collaborator

What & why

cloudsplaining only detected the ~22 Rhino-era privilege-escalation methods, so it missed 46 of pathfinding.cloud's 66 paths — entire services (apprunner, bedrock, ecs, sagemaker, codebuild, …). A policy with, say, an ECS/SageMaker PassRole pivot was not flagged at all. This PR (1) links every detected method to its pathfinding.cloud writeup and (2) expands detection to 37 of the missing paths.

1. Link privesc findings to pathfinding.cloud

Each detected method in the report now links to its pathfinding.cloud path (e.g. CreateAccessKey/paths/iam-002) instead of the generic readthedocs glossary.

  • cloudsplaining/output/src/util/pathfinding-paths.json + pathfinding.js, rendered by PrivilegeEscalationFormat.vue.
  • constants.py PRIVILEGE_ESCALATION_PATHFINDING_PATHS (canonical) + getFindingLinks so the data and report agree; a Python test enforces Python/JS parity + completeness.

2. Detect 37 additional pathfinding.cloud paths

Added to PRIVILEGE_ESCALATION_METHODS (all verified recognized by policy_sentry, precise multi-action signatures): AppRunner, Bedrock, CodeBuild, ECS ×6, Glue ×4, SageMaker ×5, Lambda, CloudFormation StackSet, EC2 PassRole, plus new IAM principal-access chains (CreateAndRotateAccessKey, AttachUserPolicyThenCreateAccessKey, *ThenUpdateAssumeRolePolicy, …).

privesc-high-priv-service-policy now flags 59 distinct methods (was 22). The example report gains 179 findings, drops 0, and links nearly the whole pathfinding.cloud catalog.

⚠️ Deliberately HELD (not added) — needs a precision decision

7 high-false-positive single broad-action paths were left out because flagging every policy containing them would be very noisy and contradicts the #581 sts:assumerole fix:

path action why held
sts-001 sts:AssumeRole every role-assuming policy would flag
ssm-001 ssm:StartSession broad, common
ssm-002 ssm:SendCommand broad, common
cloudformation-002 cloudformation:UpdateStack broad
apprunner-002 apprunner:UpdateService broad
codebuild-002 codebuild:StartBuild broad
codebuild-003 codebuild:StartBuildBatch broad

Also skipped 2 redundant paths (iam-014, iam-017) whose action sets equal existing AttachRolePolicy / PutRolePolicy.

Verification

  • just unit-tests (124), just type-check, just test-js (47), just lint, just safety-scan (0 credential findings) — all green.
  • New test/scanning/test_privilege_escalation_methods.py: every method self-detects from its own actions (also proves policy_sentry recognition).
  • report-regression-check: 179 added, 0 removed.
  • Browser-QA'd the regenerated index.html: new detections render and link to pathfinding.cloud.

Provenance

research/pathfinding-cloud/{method-to-pathfinding.json, proposed-new-methods.json} record how every mapping/method was derived (incl. held/skipped + FP rationale).

kmcquade added 2 commits May 29, 2026 22:23
…sh report

Each detected privilege-escalation method in the report now links to its pathfinding.cloud path page (e.g. CreateAccessKey -> /paths/iam-002) instead of the generic readthedocs glossary. Methods with no published path render as plain text.

- cloudsplaining/output/src/util/pathfinding-paths.json + pathfinding.js: method -> pathfinding URL map (mirrors PRIVILEGE_ESCALATION_METHODS; verified against repos/pathfinding.cloud).

- PrivilegeEscalationFormat.vue: render per-method pathfinding links.

- constants.py PRIVILEGE_ESCALATION_PATHFINDING_PATHS (canonical) + getFindingLinks in inline_policy.py/managed_policy_detail.py now emit pathfinding links in the data, so the data and report agree. Unmapped methods fall back to the glossary.

- Tests: mocha pathfinding-test.js + Python test_pathfinding_mapping.py (completeness + Python/JS parity + URL format).

- Regenerated example-iam-data.json, sampleData.js, dist bundle, and the published root index.html (now the comprehensive production report, not a dev build).

Covers the 20 existing Rhino-era paths. The 46 pathfinding.cloud paths cloudsplaining does not yet DETECT (apprunner, bedrock, ecs, sagemaker, codebuild, ssm, sts, newer iam/lambda/glue/cloudformation/ec2) are added in follow-on commits on this branch.
cloudsplaining previously detected only the ~22 Rhino-era privilege-escalation methods, missing 46 of pathfinding.cloud's 66 paths (entire services like apprunner, bedrock, ecs, sagemaker, codebuild). This adds detection for 37 of them to PRIVILEGE_ESCALATION_METHODS, each verified recognized by policy_sentry and mapped to its pathfinding.cloud writeup.

Added (low/medium false-positive risk, precise multi-action signatures): AppRunner/Bedrock/CodeBuild/ECS(x6)/Glue(x4)/SageMaker(x5)/Lambda/CloudFormation StackSet/EC2 PassRole + several new IAM principal-access chains (CreateAndRotateAccessKey, AttachUserPolicyThenCreateAccessKey, *ThenUpdateAssumeRolePolicy, etc.).

HELD (not added) - 7 high-FP single broad-action paths that would over-flag and contradict the #581 sts:assumerole fix: sts-001 (sts:AssumeRole alone), ssm-001/002 (StartSession/SendCommand), cloudformation-002 (UpdateStack), apprunner-002, codebuild-002/003. SKIPPED 2 redundant (iam-014/017 = existing AttachRolePolicy/PutRolePolicy).

- constants.py: +37 methods + matching PRIVILEGE_ESCALATION_PATHFINDING_PATHS entries (no duplicate keys; Python/JS parity + completeness tests enforce sync).

- test/scanning/test_privilege_escalation_methods.py: every method must self-detect from its own actions (also verifies policy_sentry recognition).

- Regenerated fixtures + report: privesc-high-priv-service-policy now flags 59 distinct methods (was 22); report adds 179 findings, drops 0; report links every detected method to pathfinding.cloud.

- docs/glossary/privilege-escalation.md: documents the 37 new paths.

- research/pathfinding-cloud/proposed-new-methods.json: provenance for all 46 (incl. held/skipped + FP rationale).
@kmcquade
Copy link
Copy Markdown
Collaborator Author

The 7 deliberately-held single-broad-action paths (sts:AssumeRole, ssm StartSession/SendCommand, cloudformation:UpdateStack, apprunner:UpdateService, codebuild:StartBuild[Batch]) are tracked in #585 — they're target-dependent and need a reachability-graph approach rather than action-level matching.

@kmcquade kmcquade merged commit 015f160 into master May 30, 2026
13 checks passed
@kmcquade kmcquade deleted the feat/privesc-pathfinding-links branch May 30, 2026 03:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant