cartography 0.93.0rc1__py3-none-any.whl → 0.123.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cartography/__main__.py +1 -2
- cartography/_version.py +34 -0
- cartography/cli.py +903 -225
- cartography/client/aws/__init__.py +19 -0
- cartography/client/aws/ecr.py +51 -0
- cartography/client/core/tx.py +400 -27
- cartography/config.py +215 -10
- cartography/data/azure_permission_relationships.yaml +20 -0
- cartography/data/gcp_permission_relationships.yaml +21 -0
- cartography/data/indexes.cypher +1 -200
- cartography/data/jobs/analysis/aws_ec2_asset_exposure.json +17 -2
- cartography/data/jobs/analysis/aws_ec2_keypair_analysis.json +2 -2
- cartography/data/jobs/analysis/gcp_compute_asset_inet_exposure.json +1 -1
- cartography/data/jobs/analysis/keycloak_inheritance.json +30 -0
- cartography/data/jobs/cleanup/crowdstrike_import_cleanup.json +0 -5
- cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -12
- cartography/data/jobs/cleanup/github_repos_cleanup.json +27 -0
- cartography/data/jobs/scoped_analysis/aws_ec2_iaminstanceprofile.json +15 -0
- cartography/data/jobs/scoped_analysis/semgrep_sca_risk_analysis.json +13 -13
- cartography/driftdetect/__main__.py +1 -2
- cartography/driftdetect/add_shortcut.py +10 -2
- cartography/driftdetect/cli.py +72 -75
- cartography/driftdetect/detect_deviations.py +7 -3
- cartography/driftdetect/get_states.py +20 -8
- cartography/driftdetect/model.py +5 -5
- cartography/driftdetect/serializers.py +8 -6
- cartography/driftdetect/storage.py +2 -2
- cartography/graph/cleanupbuilder.py +255 -35
- cartography/graph/job.py +104 -20
- cartography/graph/querybuilder.py +689 -91
- cartography/graph/statement.py +49 -36
- cartography/intel/airbyte/__init__.py +105 -0
- cartography/intel/airbyte/connections.py +120 -0
- cartography/intel/airbyte/destinations.py +81 -0
- cartography/intel/airbyte/organizations.py +59 -0
- cartography/intel/airbyte/sources.py +78 -0
- cartography/intel/airbyte/tags.py +64 -0
- cartography/intel/airbyte/users.py +106 -0
- cartography/intel/airbyte/util.py +122 -0
- cartography/intel/airbyte/workspaces.py +63 -0
- cartography/intel/analysis.py +4 -1
- cartography/intel/anthropic/__init__.py +62 -0
- cartography/intel/anthropic/apikeys.py +72 -0
- cartography/intel/anthropic/users.py +75 -0
- cartography/intel/anthropic/util.py +51 -0
- cartography/intel/anthropic/workspaces.py +95 -0
- cartography/intel/aws/__init__.py +137 -59
- cartography/intel/aws/acm.py +124 -0
- cartography/intel/aws/apigateway.py +482 -217
- cartography/intel/aws/apigatewayv2.py +116 -0
- cartography/intel/aws/cloudtrail.py +105 -0
- cartography/intel/aws/cloudtrail_management_events.py +962 -0
- cartography/intel/aws/cloudwatch.py +239 -0
- cartography/intel/aws/codebuild.py +132 -0
- cartography/intel/aws/cognito.py +201 -0
- cartography/intel/aws/config.py +63 -23
- cartography/intel/aws/dynamodb.py +108 -40
- cartography/intel/aws/ec2/__init__.py +2 -2
- cartography/intel/aws/ec2/auto_scaling_groups.py +254 -189
- cartography/intel/aws/ec2/elastic_ip_addresses.py +44 -14
- cartography/intel/aws/ec2/images.py +74 -39
- cartography/intel/aws/ec2/instances.py +262 -137
- cartography/intel/aws/ec2/internet_gateways.py +44 -13
- cartography/intel/aws/ec2/key_pairs.py +72 -39
- cartography/intel/aws/ec2/launch_templates.py +143 -66
- cartography/intel/aws/ec2/load_balancer_v2s.py +119 -45
- cartography/intel/aws/ec2/load_balancers.py +165 -147
- cartography/intel/aws/ec2/network_acls.py +233 -0
- cartography/intel/aws/ec2/network_interfaces.py +150 -87
- cartography/intel/aws/ec2/reserved_instances.py +48 -17
- cartography/intel/aws/ec2/route_tables.py +327 -0
- cartography/intel/aws/ec2/security_groups.py +189 -121
- cartography/intel/aws/ec2/snapshots.py +93 -91
- cartography/intel/aws/ec2/subnets.py +70 -58
- cartography/intel/aws/ec2/tgw.py +111 -39
- cartography/intel/aws/ec2/util.py +1 -1
- cartography/intel/aws/ec2/volumes.py +69 -41
- cartography/intel/aws/ec2/vpc.py +157 -116
- cartography/intel/aws/ec2/vpc_peerings.py +317 -121
- cartography/intel/aws/ecr.py +336 -93
- cartography/intel/aws/ecr_image_layers.py +923 -0
- cartography/intel/aws/ecs.py +310 -403
- cartography/intel/aws/efs.py +261 -0
- cartography/intel/aws/eks.py +55 -29
- cartography/intel/aws/elasticache.py +130 -83
- cartography/intel/aws/elasticsearch.py +70 -24
- cartography/intel/aws/emr.py +61 -23
- cartography/intel/aws/eventbridge.py +164 -0
- cartography/intel/aws/glue.py +181 -0
- cartography/intel/aws/guardduty.py +443 -0
- cartography/intel/aws/iam.py +978 -464
- cartography/intel/aws/iam_instance_profiles.py +73 -0
- cartography/intel/aws/identitycenter.py +847 -0
- cartography/intel/aws/inspector.py +330 -133
- cartography/intel/aws/kms.py +235 -209
- cartography/intel/aws/lambda_function.py +328 -176
- cartography/intel/aws/organizations.py +40 -19
- cartography/intel/aws/permission_relationships.py +144 -68
- cartography/intel/aws/rds.py +467 -412
- cartography/intel/aws/redshift.py +116 -50
- cartography/intel/aws/resourcegroupstaggingapi.py +198 -82
- cartography/intel/aws/resources.py +80 -42
- cartography/intel/aws/route53.py +419 -318
- cartography/intel/aws/s3.py +489 -96
- cartography/intel/aws/s3accountpublicaccessblock.py +157 -0
- cartography/intel/aws/secretsmanager.py +217 -40
- cartography/intel/aws/securityhub.py +23 -10
- cartography/intel/aws/sns.py +226 -0
- cartography/intel/aws/sqs.py +74 -96
- cartography/intel/aws/ssm.py +142 -33
- cartography/intel/aws/util/arns.py +7 -7
- cartography/intel/aws/util/common.py +31 -4
- cartography/intel/azure/__init__.py +259 -46
- cartography/intel/azure/aks.py +175 -0
- cartography/intel/azure/app_service.py +105 -0
- cartography/intel/azure/compute.py +141 -120
- cartography/intel/azure/container_instances.py +95 -0
- cartography/intel/azure/cosmosdb.py +706 -519
- cartography/intel/azure/data_factory.py +85 -0
- cartography/intel/azure/data_factory_dataset.py +128 -0
- cartography/intel/azure/data_factory_linked_service.py +119 -0
- cartography/intel/azure/data_factory_pipeline.py +142 -0
- cartography/intel/azure/data_lake.py +124 -0
- cartography/intel/azure/event_grid.py +94 -0
- cartography/intel/azure/functions.py +124 -0
- cartography/intel/azure/load_balancers.py +263 -0
- cartography/intel/azure/logic_apps.py +101 -0
- cartography/intel/azure/monitor.py +105 -0
- cartography/intel/azure/network.py +467 -0
- cartography/intel/azure/permission_relationships.py +466 -0
- cartography/intel/azure/rbac.py +309 -0
- cartography/intel/azure/resource_groups.py +82 -0
- cartography/intel/azure/security_center.py +106 -0
- cartography/intel/azure/sql.py +436 -392
- cartography/intel/azure/storage.py +467 -335
- cartography/intel/azure/subscription.py +49 -55
- cartography/intel/azure/tenant.py +46 -28
- cartography/intel/azure/util/common.py +13 -0
- cartography/intel/azure/util/credentials.py +58 -143
- cartography/intel/azure/util/tag.py +41 -0
- cartography/intel/bigfix/__init__.py +2 -2
- cartography/intel/bigfix/computers.py +93 -65
- cartography/intel/cloudflare/__init__.py +74 -0
- cartography/intel/cloudflare/accounts.py +57 -0
- cartography/intel/cloudflare/dnsrecords.py +64 -0
- cartography/intel/cloudflare/members.py +75 -0
- cartography/intel/cloudflare/roles.py +65 -0
- cartography/intel/cloudflare/zones.py +64 -0
- cartography/intel/create_indexes.py +5 -3
- cartography/intel/crowdstrike/__init__.py +26 -12
- cartography/intel/crowdstrike/endpoints.py +17 -45
- cartography/intel/crowdstrike/spotlight.py +13 -5
- cartography/intel/cve/__init__.py +91 -26
- cartography/intel/cve/feed.py +77 -56
- cartography/intel/digitalocean/__init__.py +22 -13
- cartography/intel/digitalocean/compute.py +75 -108
- cartography/intel/digitalocean/management.py +44 -80
- cartography/intel/digitalocean/platform.py +48 -43
- cartography/intel/dns.py +41 -12
- cartography/intel/duo/__init__.py +21 -16
- cartography/intel/duo/api_host.py +14 -9
- cartography/intel/duo/endpoints.py +50 -45
- cartography/intel/duo/groups.py +18 -14
- cartography/intel/duo/phones.py +37 -34
- cartography/intel/duo/tokens.py +26 -23
- cartography/intel/duo/users.py +54 -50
- cartography/intel/duo/web_authn_credentials.py +30 -25
- cartography/intel/entra/__init__.py +160 -0
- cartography/intel/entra/app_role_assignments.py +284 -0
- cartography/intel/entra/applications.py +182 -0
- cartography/intel/entra/federation/__init__.py +0 -0
- cartography/intel/entra/federation/aws_identity_center.py +77 -0
- cartography/intel/entra/groups.py +198 -0
- cartography/intel/entra/ou.py +136 -0
- cartography/intel/entra/service_principals.py +217 -0
- cartography/intel/entra/users.py +259 -0
- cartography/intel/gcp/__init__.py +381 -175
- cartography/intel/gcp/bigtable_app_profile.py +101 -0
- cartography/intel/gcp/bigtable_backup.py +91 -0
- cartography/intel/gcp/bigtable_cluster.py +93 -0
- cartography/intel/gcp/bigtable_instance.py +86 -0
- cartography/intel/gcp/bigtable_table.py +87 -0
- cartography/intel/gcp/cai.py +292 -0
- cartography/intel/gcp/clients.py +112 -0
- cartography/intel/gcp/compute.py +521 -325
- cartography/intel/gcp/crm/__init__.py +0 -0
- cartography/intel/gcp/crm/folders.py +114 -0
- cartography/intel/gcp/crm/orgs.py +70 -0
- cartography/intel/gcp/crm/projects.py +120 -0
- cartography/intel/gcp/dns.py +134 -179
- cartography/intel/gcp/gke.py +100 -107
- cartography/intel/gcp/iam.py +262 -0
- cartography/intel/gcp/permission_relationships.py +394 -0
- cartography/intel/gcp/policy_bindings.py +225 -0
- cartography/intel/gcp/storage.py +103 -158
- cartography/intel/github/__init__.py +66 -27
- cartography/intel/github/commits.py +423 -0
- cartography/intel/github/repos.py +871 -160
- cartography/intel/github/teams.py +386 -53
- cartography/intel/github/users.py +214 -49
- cartography/intel/github/util.py +50 -35
- cartography/intel/googleworkspace/__init__.py +193 -0
- cartography/intel/googleworkspace/devices.py +254 -0
- cartography/intel/googleworkspace/groups.py +568 -0
- cartography/intel/googleworkspace/oauth_apps.py +259 -0
- cartography/intel/googleworkspace/tenant.py +85 -0
- cartography/intel/googleworkspace/users.py +138 -0
- cartography/intel/gsuite/__init__.py +101 -42
- cartography/intel/gsuite/groups.py +291 -0
- cartography/intel/gsuite/users.py +142 -0
- cartography/intel/jamf/__init__.py +19 -1
- cartography/intel/jamf/computers.py +37 -8
- cartography/intel/jamf/util.py +7 -2
- cartography/intel/kandji/__init__.py +6 -3
- cartography/intel/kandji/devices.py +40 -10
- cartography/intel/keycloak/__init__.py +153 -0
- cartography/intel/keycloak/authenticationexecutions.py +322 -0
- cartography/intel/keycloak/authenticationflows.py +77 -0
- cartography/intel/keycloak/clients.py +187 -0
- cartography/intel/keycloak/groups.py +126 -0
- cartography/intel/keycloak/identityproviders.py +94 -0
- cartography/intel/keycloak/organizations.py +163 -0
- cartography/intel/keycloak/realms.py +61 -0
- cartography/intel/keycloak/roles.py +202 -0
- cartography/intel/keycloak/scopes.py +73 -0
- cartography/intel/keycloak/users.py +70 -0
- cartography/intel/keycloak/util.py +47 -0
- cartography/intel/kubernetes/__init__.py +60 -14
- cartography/intel/kubernetes/clusters.py +86 -0
- cartography/intel/kubernetes/eks.py +402 -0
- cartography/intel/kubernetes/namespaces.py +60 -55
- cartography/intel/kubernetes/pods.py +171 -75
- cartography/intel/kubernetes/rbac.py +597 -0
- cartography/intel/kubernetes/secrets.py +95 -45
- cartography/intel/kubernetes/services.py +131 -63
- cartography/intel/kubernetes/util.py +142 -14
- cartography/intel/lastpass/__init__.py +2 -2
- cartography/intel/lastpass/users.py +23 -12
- cartography/intel/oci/__init__.py +44 -11
- cartography/intel/oci/iam.py +157 -47
- cartography/intel/oci/organizations.py +16 -7
- cartography/intel/oci/utils.py +71 -25
- cartography/intel/okta/__init__.py +66 -15
- cartography/intel/okta/applications.py +57 -25
- cartography/intel/okta/awssaml.py +105 -41
- cartography/intel/okta/factors.py +19 -5
- cartography/intel/okta/groups.py +61 -31
- cartography/intel/okta/organization.py +8 -2
- cartography/intel/okta/origins.py +9 -3
- cartography/intel/okta/roles.py +20 -7
- cartography/intel/okta/users.py +31 -10
- cartography/intel/okta/utils.py +6 -4
- cartography/intel/ontology/__init__.py +44 -0
- cartography/intel/ontology/devices.py +54 -0
- cartography/intel/ontology/users.py +54 -0
- cartography/intel/ontology/utils.py +176 -0
- cartography/intel/openai/__init__.py +86 -0
- cartography/intel/openai/adminapikeys.py +89 -0
- cartography/intel/openai/apikeys.py +96 -0
- cartography/intel/openai/projects.py +97 -0
- cartography/intel/openai/serviceaccounts.py +82 -0
- cartography/intel/openai/users.py +75 -0
- cartography/intel/openai/util.py +45 -0
- cartography/intel/pagerduty/__init__.py +8 -7
- cartography/intel/pagerduty/escalation_policies.py +31 -12
- cartography/intel/pagerduty/schedules.py +21 -8
- cartography/intel/pagerduty/services.py +18 -7
- cartography/intel/pagerduty/teams.py +13 -5
- cartography/intel/pagerduty/users.py +6 -2
- cartography/intel/pagerduty/vendors.py +6 -2
- cartography/intel/scaleway/__init__.py +127 -0
- cartography/intel/scaleway/iam/__init__.py +0 -0
- cartography/intel/scaleway/iam/apikeys.py +71 -0
- cartography/intel/scaleway/iam/applications.py +71 -0
- cartography/intel/scaleway/iam/groups.py +71 -0
- cartography/intel/scaleway/iam/users.py +71 -0
- cartography/intel/scaleway/instances/__init__.py +0 -0
- cartography/intel/scaleway/instances/flexibleips.py +86 -0
- cartography/intel/scaleway/instances/instances.py +92 -0
- cartography/intel/scaleway/projects.py +79 -0
- cartography/intel/scaleway/storage/__init__.py +0 -0
- cartography/intel/scaleway/storage/snapshots.py +86 -0
- cartography/intel/scaleway/storage/volumes.py +84 -0
- cartography/intel/scaleway/utils.py +37 -0
- cartography/intel/semgrep/__init__.py +30 -5
- cartography/intel/semgrep/dependencies.py +255 -0
- cartography/intel/semgrep/deployment.py +69 -0
- cartography/intel/semgrep/findings.py +157 -117
- cartography/intel/sentinelone/__init__.py +75 -0
- cartography/intel/sentinelone/account.py +140 -0
- cartography/intel/sentinelone/agent.py +139 -0
- cartography/intel/sentinelone/api.py +124 -0
- cartography/intel/sentinelone/application.py +248 -0
- cartography/intel/sentinelone/cve.py +119 -0
- cartography/intel/sentinelone/utils.py +28 -0
- cartography/intel/slack/__init__.py +78 -0
- cartography/intel/slack/channels.py +80 -0
- cartography/intel/slack/groups.py +90 -0
- cartography/intel/slack/teams.py +65 -0
- cartography/intel/slack/users.py +57 -0
- cartography/intel/slack/utils.py +29 -0
- cartography/intel/snipeit/__init__.py +44 -0
- cartography/intel/snipeit/asset.py +80 -0
- cartography/intel/snipeit/user.py +78 -0
- cartography/intel/snipeit/util.py +40 -0
- cartography/intel/spacelift/__init__.py +161 -0
- cartography/intel/spacelift/account.py +73 -0
- cartography/intel/spacelift/ec2_ownership.py +280 -0
- cartography/intel/spacelift/runs.py +463 -0
- cartography/intel/spacelift/spaces.py +112 -0
- cartography/intel/spacelift/stacks.py +119 -0
- cartography/intel/spacelift/util.py +122 -0
- cartography/intel/spacelift/workerpools.py +131 -0
- cartography/intel/spacelift/workers.py +128 -0
- cartography/intel/tailscale/__init__.py +77 -0
- cartography/intel/tailscale/acls.py +146 -0
- cartography/intel/tailscale/devices.py +127 -0
- cartography/intel/tailscale/postureintegrations.py +81 -0
- cartography/intel/tailscale/tailnets.py +76 -0
- cartography/intel/tailscale/users.py +80 -0
- cartography/intel/tailscale/utils.py +132 -0
- cartography/intel/trivy/__init__.py +272 -0
- cartography/intel/trivy/scanner.py +386 -0
- cartography/models/airbyte/__init__.py +0 -0
- cartography/models/airbyte/connection.py +138 -0
- cartography/models/airbyte/destination.py +75 -0
- cartography/models/airbyte/organization.py +19 -0
- cartography/models/airbyte/source.py +75 -0
- cartography/models/airbyte/stream.py +74 -0
- cartography/models/airbyte/tag.py +69 -0
- cartography/models/airbyte/user.py +115 -0
- cartography/models/airbyte/workspace.py +46 -0
- cartography/models/anthropic/__init__.py +0 -0
- cartography/models/anthropic/apikey.py +94 -0
- cartography/models/anthropic/organization.py +19 -0
- cartography/models/anthropic/user.py +52 -0
- cartography/models/anthropic/workspace.py +90 -0
- cartography/models/aws/acm/__init__.py +0 -0
- cartography/models/aws/acm/certificate.py +75 -0
- cartography/models/aws/apigateway/__init__.py +0 -0
- cartography/models/aws/apigateway/apigateway.py +51 -0
- cartography/models/aws/apigateway/apigatewaycertificate.py +72 -0
- cartography/models/aws/apigateway/apigatewaydeployment.py +74 -0
- cartography/models/aws/apigateway/apigatewayintegration.py +79 -0
- cartography/models/aws/apigateway/apigatewaymethod.py +74 -0
- cartography/models/aws/apigateway/apigatewayresource.py +70 -0
- cartography/models/aws/apigateway/apigatewaystage.py +75 -0
- cartography/models/aws/apigatewayv2/__init__.py +0 -0
- cartography/models/aws/apigatewayv2/apigatewayv2.py +53 -0
- cartography/models/aws/cloudtrail/__init__.py +0 -0
- cartography/models/aws/cloudtrail/management_events.py +153 -0
- cartography/models/aws/cloudtrail/trail.py +106 -0
- cartography/models/aws/cloudwatch/__init__.py +0 -0
- cartography/models/aws/cloudwatch/log_metric_filter.py +79 -0
- cartography/models/aws/cloudwatch/loggroup.py +52 -0
- cartography/models/aws/cloudwatch/metric_alarm.py +53 -0
- cartography/models/aws/codebuild/__init__.py +0 -0
- cartography/models/aws/codebuild/project.py +49 -0
- cartography/models/aws/cognito/__init__.py +0 -0
- cartography/models/aws/cognito/identity_pool.py +70 -0
- cartography/models/aws/cognito/user_pool.py +47 -0
- cartography/models/aws/dynamodb/gsi.py +30 -22
- cartography/models/aws/dynamodb/tables.py +27 -17
- cartography/models/aws/ec2/auto_scaling_groups.py +224 -0
- cartography/models/aws/ec2/images.py +36 -34
- cartography/models/aws/ec2/instances.py +85 -38
- cartography/models/aws/ec2/keypair.py +59 -0
- cartography/models/aws/ec2/keypair_instance.py +76 -0
- cartography/models/aws/ec2/launch_configurations.py +59 -0
- cartography/models/aws/ec2/launch_template_versions.py +48 -38
- cartography/models/aws/ec2/launch_templates.py +21 -17
- cartography/models/aws/ec2/load_balancer_listeners.py +72 -0
- cartography/models/aws/ec2/load_balancers.py +112 -0
- cartography/models/aws/ec2/network_acl_rules.py +106 -0
- cartography/models/aws/ec2/network_acls.py +95 -0
- cartography/models/aws/ec2/networkinterface_instance.py +52 -39
- cartography/models/aws/ec2/networkinterfaces.py +57 -37
- cartography/models/aws/ec2/privateip_networkinterface.py +32 -22
- cartography/models/aws/ec2/reservations.py +18 -14
- cartography/models/aws/ec2/route_table_associations.py +97 -0
- cartography/models/aws/ec2/route_tables.py +128 -0
- cartography/models/aws/ec2/routes.py +85 -0
- cartography/models/aws/ec2/security_group_rules.py +109 -0
- cartography/models/aws/ec2/security_groups.py +90 -0
- cartography/models/aws/ec2/securitygroup_instance.py +29 -20
- cartography/models/aws/ec2/securitygroup_networkinterface.py +24 -15
- cartography/models/aws/ec2/snapshots.py +58 -0
- cartography/models/aws/ec2/subnet_instance.py +26 -19
- cartography/models/aws/ec2/subnet_networkinterface.py +42 -31
- cartography/models/aws/ec2/subnets.py +65 -0
- cartography/models/aws/ec2/volumes.py +67 -40
- cartography/models/aws/ec2/vpc.py +46 -0
- cartography/models/aws/ec2/vpc_cidr.py +102 -0
- cartography/models/aws/ec2/vpc_peering.py +157 -0
- cartography/models/aws/ecr/__init__.py +0 -0
- cartography/models/aws/ecr/image.py +146 -0
- cartography/models/aws/ecr/image_layer.py +107 -0
- cartography/models/aws/ecr/repository.py +72 -0
- cartography/models/aws/ecr/repository_image.py +95 -0
- cartography/models/aws/ecs/__init__.py +0 -0
- cartography/models/aws/ecs/clusters.py +64 -0
- cartography/models/aws/ecs/container_definitions.py +93 -0
- cartography/models/aws/ecs/container_instances.py +84 -0
- cartography/models/aws/ecs/containers.py +101 -0
- cartography/models/aws/ecs/services.py +134 -0
- cartography/models/aws/ecs/task_definitions.py +135 -0
- cartography/models/aws/ecs/tasks.py +134 -0
- cartography/models/aws/efs/__init__.py +0 -0
- cartography/models/aws/efs/access_point.py +77 -0
- cartography/models/aws/efs/file_system.py +60 -0
- cartography/models/aws/efs/mount_target.py +79 -0
- cartography/models/aws/eks/clusters.py +23 -21
- cartography/models/aws/elasticache/__init__.py +0 -0
- cartography/models/aws/elasticache/cluster.py +65 -0
- cartography/models/aws/elasticache/topic.py +67 -0
- cartography/models/aws/emr.py +32 -30
- cartography/models/aws/eventbridge/__init__.py +0 -0
- cartography/models/aws/eventbridge/rule.py +77 -0
- cartography/models/aws/eventbridge/target.py +71 -0
- cartography/models/aws/glue/__init__.py +0 -0
- cartography/models/aws/glue/connection.py +51 -0
- cartography/models/aws/glue/job.py +69 -0
- cartography/models/aws/guardduty/__init__.py +1 -0
- cartography/models/aws/guardduty/detectors.py +50 -0
- cartography/models/aws/guardduty/findings.py +121 -0
- cartography/models/aws/iam/__init__.py +0 -0
- cartography/models/aws/iam/access_key.py +103 -0
- cartography/models/aws/iam/account_role.py +24 -0
- cartography/models/aws/iam/federated_principal.py +60 -0
- cartography/models/aws/iam/group.py +60 -0
- cartography/models/aws/iam/group_membership.py +27 -0
- cartography/models/aws/iam/inline_policy.py +78 -0
- cartography/models/aws/iam/instanceprofile.py +76 -0
- cartography/models/aws/iam/managed_policy.py +51 -0
- cartography/models/aws/iam/policy_statement.py +57 -0
- cartography/models/aws/iam/role.py +83 -0
- cartography/models/aws/iam/root_principal.py +52 -0
- cartography/models/aws/iam/service_principal.py +30 -0
- cartography/models/aws/iam/sts_assumerole_allow.py +38 -0
- cartography/models/aws/iam/user.py +59 -0
- cartography/models/aws/identitycenter/__init__.py +0 -0
- cartography/models/aws/identitycenter/awsidentitycenter.py +49 -0
- cartography/models/aws/identitycenter/awspermissionset.py +162 -0
- cartography/models/aws/identitycenter/awssogroup.py +70 -0
- cartography/models/aws/identitycenter/awsssouser.py +110 -0
- cartography/models/aws/inspector/findings.py +124 -58
- cartography/models/aws/inspector/packages.py +18 -42
- cartography/models/aws/kms/__init__.py +0 -0
- cartography/models/aws/kms/aliases.py +86 -0
- cartography/models/aws/kms/grants.py +65 -0
- cartography/models/aws/kms/keys.py +88 -0
- cartography/models/aws/lambda_function/__init__.py +0 -0
- cartography/models/aws/lambda_function/alias.py +74 -0
- cartography/models/aws/lambda_function/event_source_mapping.py +88 -0
- cartography/models/aws/lambda_function/lambda_function.py +91 -0
- cartography/models/aws/lambda_function/layer.py +72 -0
- cartography/models/aws/rds/__init__.py +0 -0
- cartography/models/aws/rds/cluster.py +91 -0
- cartography/models/aws/rds/event_subscription.py +146 -0
- cartography/models/aws/rds/instance.py +156 -0
- cartography/models/aws/rds/snapshot.py +108 -0
- cartography/models/aws/rds/subnet_group.py +101 -0
- cartography/models/aws/route53/__init__.py +0 -0
- cartography/models/aws/route53/dnsrecord.py +235 -0
- cartography/models/aws/route53/nameserver.py +63 -0
- cartography/models/aws/route53/subzone.py +40 -0
- cartography/models/aws/route53/zone.py +47 -0
- cartography/models/aws/s3/__init__.py +0 -0
- cartography/models/aws/s3/account_public_access_block.py +51 -0
- cartography/models/aws/s3/notification.py +24 -0
- cartography/models/aws/secretsmanager/__init__.py +0 -0
- cartography/models/aws/secretsmanager/secret.py +106 -0
- cartography/models/aws/secretsmanager/secret_version.py +114 -0
- cartography/models/aws/sns/__init__.py +0 -0
- cartography/models/aws/sns/topic.py +50 -0
- cartography/models/aws/sns/topic_subscription.py +74 -0
- cartography/models/aws/sqs/__init__.py +0 -0
- cartography/models/aws/sqs/queue.py +89 -0
- cartography/models/aws/ssm/instance_information.py +51 -39
- cartography/models/aws/ssm/instance_patch.py +32 -26
- cartography/models/aws/ssm/parameters.py +84 -0
- cartography/models/azure/__init__.py +0 -0
- cartography/models/azure/aks_cluster.py +54 -0
- cartography/models/azure/aks_nodepool.py +54 -0
- cartography/models/azure/app_service.py +59 -0
- cartography/models/azure/container_instance.py +57 -0
- cartography/models/azure/cosmosdb/__init__.py +0 -0
- cartography/models/azure/cosmosdb/account.py +77 -0
- cartography/models/azure/cosmosdb/accountfailoverpolicy.py +77 -0
- cartography/models/azure/cosmosdb/cassandrakeyspace.py +82 -0
- cartography/models/azure/cosmosdb/cassandratable.py +81 -0
- cartography/models/azure/cosmosdb/corspolicy.py +74 -0
- cartography/models/azure/cosmosdb/dblocation.py +120 -0
- cartography/models/azure/cosmosdb/mongodbcollection.py +82 -0
- cartography/models/azure/cosmosdb/mongodbdatabase.py +78 -0
- cartography/models/azure/cosmosdb/privateendpointconnection.py +81 -0
- cartography/models/azure/cosmosdb/sqlcontainer.py +88 -0
- cartography/models/azure/cosmosdb/sqldatabase.py +78 -0
- cartography/models/azure/cosmosdb/tableresource.py +76 -0
- cartography/models/azure/cosmosdb/virtualnetworkrule.py +78 -0
- cartography/models/azure/data_factory/__init__.py +0 -0
- cartography/models/azure/data_factory/data_factory.py +51 -0
- cartography/models/azure/data_factory/data_factory_dataset.py +94 -0
- cartography/models/azure/data_factory/data_factory_linked_service.py +78 -0
- cartography/models/azure/data_factory/data_factory_pipeline.py +93 -0
- cartography/models/azure/data_lake_filesystem.py +51 -0
- cartography/models/azure/event_grid_topic.py +57 -0
- cartography/models/azure/function_app.py +59 -0
- cartography/models/azure/load_balancer/__init__.py +0 -0
- cartography/models/azure/load_balancer/load_balancer.py +49 -0
- cartography/models/azure/load_balancer/load_balancer_backend_pool.py +73 -0
- cartography/models/azure/load_balancer/load_balancer_frontend_ip.py +75 -0
- cartography/models/azure/load_balancer/load_balancer_inbound_nat_rule.py +78 -0
- cartography/models/azure/load_balancer/load_balancer_rule.py +108 -0
- cartography/models/azure/logic_apps.py +56 -0
- cartography/models/azure/monitor.py +54 -0
- cartography/models/azure/network_interface.py +112 -0
- cartography/models/azure/network_security_group.py +50 -0
- cartography/models/azure/permission_relationships.py +60 -0
- cartography/models/azure/principal.py +41 -0
- cartography/models/azure/public_ip_address.py +50 -0
- cartography/models/azure/rbac.py +268 -0
- cartography/models/azure/resource_groups.py +52 -0
- cartography/models/azure/security_center.py +50 -0
- cartography/models/azure/sql/__init__.py +0 -0
- cartography/models/azure/sql/databasethreatdetectionpolicy.py +85 -0
- cartography/models/azure/sql/elasticpool.py +77 -0
- cartography/models/azure/sql/failovergroup.py +73 -0
- cartography/models/azure/sql/recoverabledatabase.py +75 -0
- cartography/models/azure/sql/replicationlink.py +81 -0
- cartography/models/azure/sql/restorabledroppeddatabase.py +82 -0
- cartography/models/azure/sql/restorepoint.py +74 -0
- cartography/models/azure/sql/serveradadministrator.py +74 -0
- cartography/models/azure/sql/serverdnsalias.py +71 -0
- cartography/models/azure/sql/sqldatabase.py +85 -0
- cartography/models/azure/sql/sqlserver.py +50 -0
- cartography/models/azure/sql/transparentdataencryption.py +76 -0
- cartography/models/azure/storage/__init__.py +0 -0
- cartography/models/azure/storage/account.py +59 -0
- cartography/models/azure/storage/blobcontainer.py +85 -0
- cartography/models/azure/storage/blobservice.py +71 -0
- cartography/models/azure/storage/fileservice.py +71 -0
- cartography/models/azure/storage/fileshare.py +82 -0
- cartography/models/azure/storage/queue.py +71 -0
- cartography/models/azure/storage/queueservice.py +73 -0
- cartography/models/azure/storage/table.py +72 -0
- cartography/models/azure/storage/tableservice.py +73 -0
- cartography/models/azure/subnet.py +101 -0
- cartography/models/azure/subscription.py +47 -0
- cartography/models/azure/tags/__init__.py +0 -0
- cartography/models/azure/tags/storage_tag.py +40 -0
- cartography/models/azure/tags/tag.py +37 -0
- cartography/models/azure/tenant.py +17 -0
- cartography/models/azure/virtual_network.py +49 -0
- cartography/models/azure/vm/__init__.py +0 -0
- cartography/models/azure/vm/datadisk.py +80 -0
- cartography/models/azure/vm/disk.py +55 -0
- cartography/models/azure/vm/snapshot.py +56 -0
- cartography/models/azure/vm/virtualmachine.py +59 -0
- cartography/models/bigfix/bigfix_computer.py +42 -38
- cartography/models/bigfix/bigfix_root.py +3 -3
- cartography/models/cloudflare/__init__.py +0 -0
- cartography/models/cloudflare/account.py +25 -0
- cartography/models/cloudflare/dnsrecord.py +55 -0
- cartography/models/cloudflare/member.py +86 -0
- cartography/models/cloudflare/role.py +44 -0
- cartography/models/cloudflare/zone.py +59 -0
- cartography/models/core/common.py +53 -2
- cartography/models/core/nodes.py +20 -4
- cartography/models/core/relationships.py +58 -6
- cartography/models/crowdstrike/__init__.py +0 -0
- cartography/models/crowdstrike/hosts.py +51 -0
- cartography/models/cve/cve.py +34 -32
- cartography/models/cve/cve_feed.py +6 -6
- cartography/models/digitalocean/__init__.py +0 -0
- cartography/models/digitalocean/account.py +21 -0
- cartography/models/digitalocean/droplet.py +58 -0
- cartography/models/digitalocean/project.py +48 -0
- cartography/models/duo/api_host.py +3 -3
- cartography/models/duo/endpoint.py +43 -41
- cartography/models/duo/group.py +14 -14
- cartography/models/duo/phone.py +27 -27
- cartography/models/duo/token.py +16 -16
- cartography/models/duo/user.py +50 -44
- cartography/models/duo/web_authn_credential.py +27 -19
- cartography/models/entra/__init__.py +0 -0
- cartography/models/entra/app_role_assignment.py +115 -0
- cartography/models/entra/application.py +49 -0
- cartography/models/entra/entra_user_to_aws_sso.py +41 -0
- cartography/models/entra/group.py +117 -0
- cartography/models/entra/ou.py +48 -0
- cartography/models/entra/service_principal.py +104 -0
- cartography/models/entra/tenant.py +39 -0
- cartography/models/entra/user.py +90 -0
- cartography/models/gcp/__init__.py +0 -0
- cartography/models/gcp/bigtable/__init__.py +0 -0
- cartography/models/gcp/bigtable/app_profile.py +94 -0
- cartography/models/gcp/bigtable/backup.py +91 -0
- cartography/models/gcp/bigtable/cluster.py +73 -0
- cartography/models/gcp/bigtable/instance.py +52 -0
- cartography/models/gcp/bigtable/table.py +69 -0
- cartography/models/gcp/compute/__init__.py +0 -0
- cartography/models/gcp/compute/subnet.py +74 -0
- cartography/models/gcp/compute/vpc.py +50 -0
- cartography/models/gcp/crm/__init__.py +0 -0
- cartography/models/gcp/crm/folders.py +98 -0
- cartography/models/gcp/crm/organizations.py +21 -0
- cartography/models/gcp/crm/projects.py +100 -0
- cartography/models/gcp/dns.py +109 -0
- cartography/models/gcp/gke.py +69 -0
- cartography/models/gcp/iam.py +73 -0
- cartography/models/gcp/permission_relationships.py +61 -0
- cartography/models/gcp/policy_bindings.py +93 -0
- cartography/models/gcp/storage/__init__.py +0 -0
- cartography/models/gcp/storage/bucket.py +119 -0
- cartography/models/github/commits.py +63 -0
- cartography/models/github/dependencies.py +73 -0
- cartography/models/github/manifests.py +49 -0
- cartography/models/github/orgs.py +27 -0
- cartography/models/github/teams.py +74 -22
- cartography/models/github/users.py +149 -0
- cartography/models/googleworkspace/__init__.py +0 -0
- cartography/models/googleworkspace/device.py +132 -0
- cartography/models/googleworkspace/group.py +382 -0
- cartography/models/googleworkspace/oauth_app.py +124 -0
- cartography/models/googleworkspace/tenant.py +30 -0
- cartography/models/googleworkspace/user.py +113 -0
- cartography/models/gsuite/__init__.py +0 -0
- cartography/models/gsuite/group.py +218 -0
- cartography/models/gsuite/tenant.py +29 -0
- cartography/models/gsuite/user.py +107 -0
- cartography/models/kandji/device.py +22 -17
- cartography/models/kandji/tenant.py +6 -4
- cartography/models/keycloak/__init__.py +0 -0
- cartography/models/keycloak/authenticationexecution.py +160 -0
- cartography/models/keycloak/authenticationflow.py +54 -0
- cartography/models/keycloak/client.py +179 -0
- cartography/models/keycloak/group.py +101 -0
- cartography/models/keycloak/identityprovider.py +89 -0
- cartography/models/keycloak/organization.py +116 -0
- cartography/models/keycloak/organizationdomain.py +73 -0
- cartography/models/keycloak/realm.py +173 -0
- cartography/models/keycloak/role.py +126 -0
- cartography/models/keycloak/scope.py +73 -0
- cartography/models/keycloak/user.py +55 -0
- cartography/models/kubernetes/__init__.py +0 -0
- cartography/models/kubernetes/clusterrolebindings.py +138 -0
- cartography/models/kubernetes/clusterroles.py +52 -0
- cartography/models/kubernetes/clusters.py +26 -0
- cartography/models/kubernetes/containers.py +133 -0
- cartography/models/kubernetes/groups.py +107 -0
- cartography/models/kubernetes/namespaces.py +51 -0
- cartography/models/kubernetes/oidc.py +51 -0
- cartography/models/kubernetes/pods.py +80 -0
- cartography/models/kubernetes/rolebindings.py +159 -0
- cartography/models/kubernetes/roles.py +76 -0
- cartography/models/kubernetes/secrets.py +79 -0
- cartography/models/kubernetes/serviceaccounts.py +77 -0
- cartography/models/kubernetes/services.py +108 -0
- cartography/models/kubernetes/users.py +105 -0
- cartography/models/lastpass/tenant.py +3 -3
- cartography/models/lastpass/user.py +36 -28
- cartography/models/ontology/__init__.py +0 -0
- cartography/models/ontology/device.py +137 -0
- cartography/models/ontology/mapping/__init__.py +76 -0
- cartography/models/ontology/mapping/data/__init__.py +0 -0
- cartography/models/ontology/mapping/data/apikeys.py +93 -0
- cartography/models/ontology/mapping/data/computeinstance.py +95 -0
- cartography/models/ontology/mapping/data/containers.py +88 -0
- cartography/models/ontology/mapping/data/databases.py +182 -0
- cartography/models/ontology/mapping/data/devices.py +194 -0
- cartography/models/ontology/mapping/data/thirdpartyapps.py +140 -0
- cartography/models/ontology/mapping/data/useraccounts.py +416 -0
- cartography/models/ontology/mapping/data/users.py +63 -0
- cartography/models/ontology/mapping/specs.py +85 -0
- cartography/models/ontology/user.py +51 -0
- cartography/models/openai/__init__.py +0 -0
- cartography/models/openai/adminapikey.py +94 -0
- cartography/models/openai/apikey.py +88 -0
- cartography/models/openai/organization.py +17 -0
- cartography/models/openai/project.py +89 -0
- cartography/models/openai/serviceaccount.py +50 -0
- cartography/models/openai/user.py +53 -0
- cartography/models/scaleway/__init__.py +0 -0
- cartography/models/scaleway/iam/__init__.py +0 -0
- cartography/models/scaleway/iam/apikey.py +100 -0
- cartography/models/scaleway/iam/application.py +52 -0
- cartography/models/scaleway/iam/group.py +95 -0
- cartography/models/scaleway/iam/user.py +64 -0
- cartography/models/scaleway/instance/__init__.py +0 -0
- cartography/models/scaleway/instance/flexibleip.py +52 -0
- cartography/models/scaleway/instance/instance.py +120 -0
- cartography/models/scaleway/organization.py +19 -0
- cartography/models/scaleway/project.py +48 -0
- cartography/models/scaleway/storage/__init__.py +0 -0
- cartography/models/scaleway/storage/snapshot.py +78 -0
- cartography/models/scaleway/storage/volume.py +51 -0
- cartography/models/semgrep/dependencies.py +102 -0
- cartography/models/semgrep/deployment.py +5 -5
- cartography/models/semgrep/findings.py +58 -40
- cartography/models/semgrep/locations.py +27 -21
- cartography/models/sentinelone/__init__.py +1 -0
- cartography/models/sentinelone/account.py +40 -0
- cartography/models/sentinelone/agent.py +50 -0
- cartography/models/sentinelone/application.py +44 -0
- cartography/models/sentinelone/application_version.py +96 -0
- cartography/models/sentinelone/cve.py +73 -0
- cartography/models/slack/__init__.py +0 -0
- cartography/models/slack/channels.py +92 -0
- cartography/models/slack/group.py +129 -0
- cartography/models/slack/team.py +22 -0
- cartography/models/slack/user.py +62 -0
- cartography/models/snipeit/__init__.py +0 -0
- cartography/models/snipeit/asset.py +92 -0
- cartography/models/snipeit/tenant.py +19 -0
- cartography/models/snipeit/user.py +60 -0
- cartography/models/spacelift/__init__.py +0 -0
- cartography/models/spacelift/cloudtrailevent.py +120 -0
- cartography/models/spacelift/run.py +162 -0
- cartography/models/spacelift/space.py +131 -0
- cartography/models/spacelift/spaceliftaccount.py +31 -0
- cartography/models/spacelift/spaceliftgitcommit.py +157 -0
- cartography/models/spacelift/stack.py +96 -0
- cartography/models/spacelift/user.py +63 -0
- cartography/models/spacelift/worker.py +97 -0
- cartography/models/spacelift/workerpool.py +90 -0
- cartography/models/tailscale/__init__.py +0 -0
- cartography/models/tailscale/device.py +96 -0
- cartography/models/tailscale/group.py +86 -0
- cartography/models/tailscale/postureintegration.py +58 -0
- cartography/models/tailscale/tag.py +102 -0
- cartography/models/tailscale/tailnet.py +29 -0
- cartography/models/tailscale/user.py +57 -0
- cartography/models/trivy/__init__.py +0 -0
- cartography/models/trivy/findings.py +66 -0
- cartography/models/trivy/fix.py +66 -0
- cartography/models/trivy/package.py +71 -0
- cartography/rules/README.md +1 -0
- cartography/rules/__init__.py +0 -0
- cartography/rules/cli.py +261 -0
- cartography/rules/data/__init__.py +0 -0
- cartography/rules/data/rules/__init__.py +46 -0
- cartography/rules/data/rules/cloud_security_product_deactivated.py +49 -0
- cartography/rules/data/rules/compute_instance_exposed.py +51 -0
- cartography/rules/data/rules/database_instance_exposed.py +53 -0
- cartography/rules/data/rules/delegation_boundary_modifiable.py +90 -0
- cartography/rules/data/rules/identity_administration_privileges.py +100 -0
- cartography/rules/data/rules/inactive_user_active_accounts.py +48 -0
- cartography/rules/data/rules/malicious_npm_dependencies_shai_hulud.py +2222 -0
- cartography/rules/data/rules/mfa_missing.py +46 -0
- cartography/rules/data/rules/object_storage_public.py +100 -0
- cartography/rules/data/rules/policy_administration_privileges.py +104 -0
- cartography/rules/data/rules/unmanaged_accounts.py +43 -0
- cartography/rules/data/rules/workload_identity_admin_capabilities.py +193 -0
- cartography/rules/formatters.py +108 -0
- cartography/rules/runners.py +216 -0
- cartography/rules/spec/__init__.py +0 -0
- cartography/rules/spec/model.py +267 -0
- cartography/rules/spec/result.py +38 -0
- cartography/stats.py +4 -4
- cartography/sync.py +137 -31
- cartography/util.py +187 -77
- cartography-0.123.0.dist-info/METADATA +230 -0
- cartography-0.123.0.dist-info/RECORD +856 -0
- {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/WHEEL +1 -1
- {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/entry_points.txt +1 -0
- {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info/licenses}/LICENSE +1 -1
- cartography/data/jobs/analysis/aws_ec2_iaminstance.json +0 -10
- cartography/data/jobs/analysis/aws_ec2_iaminstanceprofile.json +0 -10
- cartography/data/jobs/cleanup/aws_apigateway_details.json +0 -10
- cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -65
- cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -17
- cartography/data/jobs/cleanup/aws_import_apigateway_cleanup.json +0 -45
- cartography/data/jobs/cleanup/aws_import_ec2_security_groupinfo_cleanup.json +0 -24
- cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
- cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -50
- cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -30
- cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -23
- cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -47
- cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -23
- cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -13
- cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
- cartography/data/jobs/cleanup/aws_import_snapshots_cleanup.json +0 -30
- cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -8
- cartography/data/jobs/cleanup/aws_import_vpc_cleanup.json +0 -23
- cartography/data/jobs/cleanup/aws_import_vpc_peering_cleanup.json +0 -45
- cartography/data/jobs/cleanup/aws_kms_details.json +0 -10
- cartography/data/jobs/cleanup/azure_cosmosdb_cassandra_keyspace_cleanup.json +0 -25
- cartography/data/jobs/cleanup/azure_cosmosdb_cors_details.json +0 -15
- cartography/data/jobs/cleanup/azure_cosmosdb_mongodb_database_cleanup.json +0 -25
- cartography/data/jobs/cleanup/azure_cosmosdb_sql_database_cleanup.json +0 -25
- cartography/data/jobs/cleanup/azure_cosmosdb_table_resources_cleanup.json +0 -15
- cartography/data/jobs/cleanup/azure_database_account_cleanup.json +0 -85
- cartography/data/jobs/cleanup/azure_import_disks_cleanup.json +0 -15
- cartography/data/jobs/cleanup/azure_import_snapshots_cleanup.json +0 -15
- cartography/data/jobs/cleanup/azure_import_virtual_machines_cleanup.json +0 -25
- cartography/data/jobs/cleanup/azure_sql_server_cleanup.json +0 -125
- cartography/data/jobs/cleanup/azure_storage_account_cleanup.json +0 -95
- cartography/data/jobs/cleanup/azure_subscriptions_cleanup.json +0 -14
- cartography/data/jobs/cleanup/azure_tenant_cleanup.json +0 -9
- cartography/data/jobs/cleanup/crxcavator_import_cleanup.json +0 -18
- cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -35
- cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -23
- cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -17
- cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -23
- cartography/data/jobs/cleanup/gcp_dns_cleanup.json +0 -29
- cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -17
- cartography/data/jobs/cleanup/gcp_storage_bucket_cleanup.json +0 -29
- cartography/data/jobs/cleanup/github_users_cleanup.json +0 -23
- cartography/data/jobs/cleanup/gsuite_ingest_groups_cleanup.json +0 -23
- cartography/data/jobs/cleanup/gsuite_ingest_users_cleanup.json +0 -11
- cartography/data/jobs/cleanup/kubernetes_import_cleanup.json +0 -70
- cartography/intel/crxcavator/__init__.py +0 -44
- cartography/intel/crxcavator/crxcavator.py +0 -329
- cartography/intel/gcp/crm.py +0 -302
- cartography/intel/gsuite/api.py +0 -284
- cartography/models/aws/ec2/keypairs.py +0 -64
- cartography-0.93.0rc1.dist-info/METADATA +0 -55
- cartography-0.93.0rc1.dist-info/NOTICE +0 -4
- cartography-0.93.0rc1.dist-info/RECORD +0 -341
- /cartography/data/jobs/{analysis → scoped_analysis}/aws_s3acl_analysis.json +0 -0
- {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/top_level.txt +0 -0
cartography/rules/cli.py
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Cartography RunRules CLI
|
|
3
|
+
|
|
4
|
+
Execute security frameworks and present facts about your environment.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import builtins
|
|
8
|
+
import logging
|
|
9
|
+
import os
|
|
10
|
+
from enum import Enum
|
|
11
|
+
from typing import Generator
|
|
12
|
+
|
|
13
|
+
import typer
|
|
14
|
+
from typing_extensions import Annotated
|
|
15
|
+
|
|
16
|
+
from cartography.rules.data.rules import RULES
|
|
17
|
+
from cartography.rules.runners import run_rules
|
|
18
|
+
|
|
19
|
+
app = typer.Typer(
|
|
20
|
+
help="Execute Cartography security frameworks",
|
|
21
|
+
no_args_is_help=True,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class OutputFormat(str, Enum):
|
|
26
|
+
"""Output format options."""
|
|
27
|
+
|
|
28
|
+
text = "text"
|
|
29
|
+
json = "json"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# ----------------------------
|
|
33
|
+
# Autocompletion functions
|
|
34
|
+
# ----------------------------
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def complete_rules(incomplete: str) -> Generator[str, None, None]:
|
|
38
|
+
"""Autocomplete rules names."""
|
|
39
|
+
for name in RULES.keys():
|
|
40
|
+
if name.startswith(incomplete):
|
|
41
|
+
yield name
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def complete_rules_with_all(incomplete: str) -> Generator[str, None, None]:
|
|
45
|
+
"""Autocomplete rules names plus 'all'."""
|
|
46
|
+
for name in builtins.list(RULES.keys()) + ["all"]:
|
|
47
|
+
if name.startswith(incomplete):
|
|
48
|
+
yield name
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def complete_facts(
|
|
52
|
+
ctx: typer.Context, incomplete: str
|
|
53
|
+
) -> Generator[tuple[str, str], None, None]:
|
|
54
|
+
"""Autocomplete facts IDs with descriptions based on selected rule."""
|
|
55
|
+
rule = ctx.params.get("rule")
|
|
56
|
+
if not rule or rule not in RULES:
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
for fact in RULES[rule].facts:
|
|
60
|
+
if fact.id.lower().startswith(incomplete.lower()):
|
|
61
|
+
yield (fact.id, fact.name)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# ----------------------------
|
|
65
|
+
# CLI Commands
|
|
66
|
+
# ----------------------------
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@app.command(name="list") # type: ignore[misc]
|
|
70
|
+
def list_cmd(
|
|
71
|
+
rule: Annotated[
|
|
72
|
+
str | None,
|
|
73
|
+
typer.Argument(
|
|
74
|
+
help="Rule name (e.g., mfa-missing)",
|
|
75
|
+
autocompletion=complete_rules,
|
|
76
|
+
),
|
|
77
|
+
] = None,
|
|
78
|
+
) -> None:
|
|
79
|
+
"""
|
|
80
|
+
List available rules and facts.
|
|
81
|
+
|
|
82
|
+
\b
|
|
83
|
+
Examples:
|
|
84
|
+
cartography-rules list
|
|
85
|
+
cartography-rules list mfa-missing
|
|
86
|
+
cartography-rules list mfa-missing missing-mfa-cloudflare
|
|
87
|
+
"""
|
|
88
|
+
# List all frameworks
|
|
89
|
+
if not rule:
|
|
90
|
+
typer.secho("\nAvailable Rules\n", bold=True)
|
|
91
|
+
for rule_name, rule_obj in RULES.items():
|
|
92
|
+
typer.secho(f"{rule_name}", fg=typer.colors.CYAN)
|
|
93
|
+
typer.echo(f" Name: {rule_obj.name}")
|
|
94
|
+
typer.echo(f" Version: {rule_obj.version}")
|
|
95
|
+
typer.echo(f" Facts: {len(rule_obj.facts)}")
|
|
96
|
+
if rule_obj.references:
|
|
97
|
+
typer.echo(" References:")
|
|
98
|
+
for ref in rule_obj.references:
|
|
99
|
+
typer.echo(f" - [{ref.text}]({ref.url})")
|
|
100
|
+
typer.echo()
|
|
101
|
+
return
|
|
102
|
+
|
|
103
|
+
# Validate rule
|
|
104
|
+
if rule not in RULES:
|
|
105
|
+
typer.secho(f"Error: Unknown rule '{rule}'", fg=typer.colors.RED, err=True)
|
|
106
|
+
typer.echo(f"Available: {', '.join(RULES.keys())}", err=True)
|
|
107
|
+
raise typer.Exit(1)
|
|
108
|
+
|
|
109
|
+
rule_obj = RULES[rule]
|
|
110
|
+
|
|
111
|
+
typer.secho(f"\n{rule_obj.name}", bold=True)
|
|
112
|
+
typer.echo(f"ID: {rule_obj.id}")
|
|
113
|
+
typer.secho(f"\nFacts ({len(rule_obj.facts)})\n", bold=True)
|
|
114
|
+
|
|
115
|
+
for fact in rule_obj.facts:
|
|
116
|
+
typer.secho(f"{fact.id}", fg=typer.colors.CYAN)
|
|
117
|
+
typer.echo(f" Name: {fact.name}")
|
|
118
|
+
typer.echo(f" Description: {fact.description}")
|
|
119
|
+
typer.echo(f" Maturity: {fact.maturity.value}")
|
|
120
|
+
typer.echo(f" Provider: {fact.module.value}")
|
|
121
|
+
typer.echo()
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
@app.command(name="run") # type: ignore[misc]
|
|
125
|
+
def run_cmd(
|
|
126
|
+
rule: Annotated[
|
|
127
|
+
str | None,
|
|
128
|
+
typer.Argument(
|
|
129
|
+
help="Specific rule ID to run",
|
|
130
|
+
autocompletion=complete_rules_with_all,
|
|
131
|
+
),
|
|
132
|
+
] = None,
|
|
133
|
+
fact: Annotated[
|
|
134
|
+
str | None,
|
|
135
|
+
typer.Argument(
|
|
136
|
+
help="Specific fact ID to run",
|
|
137
|
+
autocompletion=complete_facts,
|
|
138
|
+
),
|
|
139
|
+
] = None,
|
|
140
|
+
uri: Annotated[
|
|
141
|
+
str,
|
|
142
|
+
typer.Option(help="Neo4j URI", envvar="NEO4J_URI"),
|
|
143
|
+
] = "bolt://localhost:7687",
|
|
144
|
+
user: Annotated[
|
|
145
|
+
str,
|
|
146
|
+
typer.Option(help="Neo4j username", envvar="NEO4J_USER"),
|
|
147
|
+
] = "neo4j",
|
|
148
|
+
database: Annotated[
|
|
149
|
+
str,
|
|
150
|
+
typer.Option(help="Neo4j database name", envvar="NEO4J_DATABASE"),
|
|
151
|
+
] = "neo4j",
|
|
152
|
+
neo4j_password_env_var: Annotated[
|
|
153
|
+
str | None,
|
|
154
|
+
typer.Option(help="Environment variable containing Neo4j password"),
|
|
155
|
+
] = None,
|
|
156
|
+
neo4j_password_prompt: Annotated[
|
|
157
|
+
bool,
|
|
158
|
+
typer.Option(help="Prompt for Neo4j password interactively"),
|
|
159
|
+
] = False,
|
|
160
|
+
output: Annotated[
|
|
161
|
+
OutputFormat,
|
|
162
|
+
typer.Option(help="Output format"),
|
|
163
|
+
] = OutputFormat.text,
|
|
164
|
+
experimental: bool = typer.Option(
|
|
165
|
+
True,
|
|
166
|
+
"--experimental/--no-experimental",
|
|
167
|
+
help="Enable or disable experimental facts.",
|
|
168
|
+
),
|
|
169
|
+
) -> None:
|
|
170
|
+
"""
|
|
171
|
+
Execute a security framework.
|
|
172
|
+
|
|
173
|
+
\b
|
|
174
|
+
Examples:
|
|
175
|
+
cartography-rules run all
|
|
176
|
+
cartography-rules run mfa-missing
|
|
177
|
+
cartography-rules run mfa-missing missing-mfa-cloudflare
|
|
178
|
+
"""
|
|
179
|
+
# Validate rule
|
|
180
|
+
valid_rules = builtins.list(RULES.keys()) + ["all"]
|
|
181
|
+
if rule not in valid_rules:
|
|
182
|
+
typer.secho(f"Error: Unknown rule '{rule}'", fg=typer.colors.RED, err=True)
|
|
183
|
+
typer.echo(f"Available: {', '.join(valid_rules)}", err=True)
|
|
184
|
+
raise typer.Exit(1)
|
|
185
|
+
|
|
186
|
+
# Validate fact requires rule
|
|
187
|
+
if fact and not rule:
|
|
188
|
+
typer.secho(
|
|
189
|
+
"Error: Cannot specify fact without rule",
|
|
190
|
+
fg=typer.colors.RED,
|
|
191
|
+
err=True,
|
|
192
|
+
)
|
|
193
|
+
raise typer.Exit(1)
|
|
194
|
+
|
|
195
|
+
# Validate filtering with 'all'
|
|
196
|
+
if rule == "all" and fact:
|
|
197
|
+
typer.secho(
|
|
198
|
+
"Error: Cannot filter by fact when running all rules",
|
|
199
|
+
fg=typer.colors.RED,
|
|
200
|
+
err=True,
|
|
201
|
+
)
|
|
202
|
+
raise typer.Exit(1)
|
|
203
|
+
|
|
204
|
+
# Validate fact exists
|
|
205
|
+
if fact and rule != "all":
|
|
206
|
+
rule_obj = RULES[rule]
|
|
207
|
+
fact_obj = rule_obj.get_fact_by_id(fact)
|
|
208
|
+
if not fact_obj:
|
|
209
|
+
typer.secho(
|
|
210
|
+
f"Error: Fact '{fact}' not found in rule '{rule}'",
|
|
211
|
+
fg=typer.colors.RED,
|
|
212
|
+
err=True,
|
|
213
|
+
)
|
|
214
|
+
typer.echo("\nAvailable facts:", err=True)
|
|
215
|
+
for fa in rule_obj.facts:
|
|
216
|
+
typer.echo(f" {fa.id}", err=True)
|
|
217
|
+
raise typer.Exit(1)
|
|
218
|
+
|
|
219
|
+
# Get password
|
|
220
|
+
password = None
|
|
221
|
+
if neo4j_password_prompt:
|
|
222
|
+
password = typer.prompt("Neo4j password", hide_input=True)
|
|
223
|
+
elif neo4j_password_env_var:
|
|
224
|
+
password = os.environ.get(neo4j_password_env_var)
|
|
225
|
+
else:
|
|
226
|
+
password = os.getenv("NEO4J_PASSWORD")
|
|
227
|
+
if not password:
|
|
228
|
+
password = typer.prompt("Neo4j password", hide_input=True)
|
|
229
|
+
|
|
230
|
+
# Determine rules to run
|
|
231
|
+
if rule == "all":
|
|
232
|
+
rules_to_run = builtins.list(RULES.keys())
|
|
233
|
+
else:
|
|
234
|
+
rules_to_run = [rule]
|
|
235
|
+
|
|
236
|
+
# Execute
|
|
237
|
+
try:
|
|
238
|
+
exit_code = run_rules(
|
|
239
|
+
rules_to_run,
|
|
240
|
+
uri,
|
|
241
|
+
user,
|
|
242
|
+
password,
|
|
243
|
+
database,
|
|
244
|
+
output.value,
|
|
245
|
+
fact_filter=fact,
|
|
246
|
+
exclude_experimental=not experimental,
|
|
247
|
+
)
|
|
248
|
+
raise typer.Exit(exit_code)
|
|
249
|
+
except KeyboardInterrupt:
|
|
250
|
+
raise typer.Exit(130)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def main():
|
|
254
|
+
"""Entrypoint for cartography-rules CLI."""
|
|
255
|
+
logging.basicConfig(level=logging.INFO)
|
|
256
|
+
logging.getLogger("neo4j").setLevel(logging.ERROR)
|
|
257
|
+
app()
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
if __name__ == "__main__":
|
|
261
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from cartography.rules.data.rules.cloud_security_product_deactivated import (
|
|
2
|
+
cloud_security_product_deactivated,
|
|
3
|
+
)
|
|
4
|
+
from cartography.rules.data.rules.compute_instance_exposed import (
|
|
5
|
+
compute_instance_exposed,
|
|
6
|
+
)
|
|
7
|
+
from cartography.rules.data.rules.database_instance_exposed import (
|
|
8
|
+
database_instance_exposed,
|
|
9
|
+
)
|
|
10
|
+
from cartography.rules.data.rules.delegation_boundary_modifiable import (
|
|
11
|
+
delegation_boundary_modifiable,
|
|
12
|
+
)
|
|
13
|
+
from cartography.rules.data.rules.identity_administration_privileges import (
|
|
14
|
+
identity_administration_privileges,
|
|
15
|
+
)
|
|
16
|
+
from cartography.rules.data.rules.inactive_user_active_accounts import (
|
|
17
|
+
inactive_user_active_accounts,
|
|
18
|
+
)
|
|
19
|
+
from cartography.rules.data.rules.malicious_npm_dependencies_shai_hulud import (
|
|
20
|
+
malicious_npm_dependencies_shai_hulud,
|
|
21
|
+
)
|
|
22
|
+
from cartography.rules.data.rules.mfa_missing import missing_mfa_rule
|
|
23
|
+
from cartography.rules.data.rules.object_storage_public import object_storage_public
|
|
24
|
+
from cartography.rules.data.rules.policy_administration_privileges import (
|
|
25
|
+
policy_administration_privileges,
|
|
26
|
+
)
|
|
27
|
+
from cartography.rules.data.rules.unmanaged_accounts import unmanaged_accounts
|
|
28
|
+
from cartography.rules.data.rules.workload_identity_admin_capabilities import (
|
|
29
|
+
workload_identity_admin_capabilities,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Rule registry - all available rules
|
|
33
|
+
RULES = {
|
|
34
|
+
compute_instance_exposed.id: compute_instance_exposed,
|
|
35
|
+
database_instance_exposed.id: database_instance_exposed,
|
|
36
|
+
delegation_boundary_modifiable.id: delegation_boundary_modifiable,
|
|
37
|
+
identity_administration_privileges.id: identity_administration_privileges,
|
|
38
|
+
inactive_user_active_accounts.id: inactive_user_active_accounts,
|
|
39
|
+
missing_mfa_rule.id: missing_mfa_rule,
|
|
40
|
+
object_storage_public.id: object_storage_public,
|
|
41
|
+
policy_administration_privileges.id: policy_administration_privileges,
|
|
42
|
+
unmanaged_accounts.id: unmanaged_accounts,
|
|
43
|
+
workload_identity_admin_capabilities.id: workload_identity_admin_capabilities,
|
|
44
|
+
cloud_security_product_deactivated.id: cloud_security_product_deactivated,
|
|
45
|
+
malicious_npm_dependencies_shai_hulud.id: malicious_npm_dependencies_shai_hulud,
|
|
46
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from cartography.rules.spec.model import Fact
|
|
2
|
+
from cartography.rules.spec.model import Finding
|
|
3
|
+
from cartography.rules.spec.model import Maturity
|
|
4
|
+
from cartography.rules.spec.model import Module
|
|
5
|
+
from cartography.rules.spec.model import Rule
|
|
6
|
+
|
|
7
|
+
# AWS
|
|
8
|
+
aws_guard_duty_detector_disabled = Fact(
|
|
9
|
+
id="aws_guard_duty_detector_disabled",
|
|
10
|
+
name="GuardDuty Detector Disabled",
|
|
11
|
+
description="Finds regions where GuardDuty Detector is disabled.",
|
|
12
|
+
cypher_query="""
|
|
13
|
+
MATCH (a:AWSAccount)-[:RESOURCE]-(r:EC2Instance|EKSCluster|AWSLambda|ECSCluster|RDSInstance|RDSCluster)
|
|
14
|
+
WHERE NOT EXISTS {
|
|
15
|
+
MATCH (a)-[:RESOURCE]->(d:GuardDutyDetector{status: "ENABLED"})
|
|
16
|
+
WHERE d.region = r.region
|
|
17
|
+
}
|
|
18
|
+
RETURN DISTINCT r.region AS region, a.name AS account_name, a.id AS account_id
|
|
19
|
+
ORDER BY r.region, a.name
|
|
20
|
+
""",
|
|
21
|
+
cypher_visual_query="""
|
|
22
|
+
MATCH (a:AWSAccount)-[:RESOURCE]-(r:EC2Instance|EKSCluster|AWSLambda|ECSCluster|RDSInstance|RDSCluster)
|
|
23
|
+
WHERE NOT EXISTS {
|
|
24
|
+
MATCH (a)-[:RESOURCE]->(d:GuardDutyDetector{status: "ENABLED"})
|
|
25
|
+
WHERE d.region = r.region
|
|
26
|
+
}
|
|
27
|
+
RETURN *
|
|
28
|
+
""",
|
|
29
|
+
module=Module.AWS,
|
|
30
|
+
maturity=Maturity.EXPERIMENTAL,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# Rule
|
|
35
|
+
class CloudSecurityProductDeactivated(Finding):
|
|
36
|
+
region: str | None = None
|
|
37
|
+
account_name: str | None = None
|
|
38
|
+
account_id: str | None = None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
cloud_security_product_deactivated = Rule(
|
|
42
|
+
id="cloud_security_product_deactivated",
|
|
43
|
+
name="Cloud Security Product Deactivated",
|
|
44
|
+
description="Detects accounts (or regions) where cloud security products are deactivated.",
|
|
45
|
+
output_model=CloudSecurityProductDeactivated,
|
|
46
|
+
tags=("cloud_security",),
|
|
47
|
+
facts=(aws_guard_duty_detector_disabled,),
|
|
48
|
+
version="0.1.0",
|
|
49
|
+
)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from cartography.rules.spec.model import Fact
|
|
2
|
+
from cartography.rules.spec.model import Finding
|
|
3
|
+
from cartography.rules.spec.model import Maturity
|
|
4
|
+
from cartography.rules.spec.model import Module
|
|
5
|
+
from cartography.rules.spec.model import Rule
|
|
6
|
+
|
|
7
|
+
# AWS Facts
|
|
8
|
+
_aws_ec2_instance_internet_exposed = Fact(
|
|
9
|
+
id="aws_ec2_instance_internet_exposed",
|
|
10
|
+
name="Internet-Exposed EC2 Instances on Common Management Ports",
|
|
11
|
+
description=(
|
|
12
|
+
"EC2 instances exposed to the internet on ports 22, 3389, 3306, 5432, 6379, 9200, 27017"
|
|
13
|
+
),
|
|
14
|
+
cypher_query="""
|
|
15
|
+
MATCH (a:AWSAccount)-[:RESOURCE]->(ec2:EC2Instance)-[:MEMBER_OF_EC2_SECURITY_GROUP]->(sg:EC2SecurityGroup)<-[:MEMBER_OF_EC2_SECURITY_GROUP]-(rule:IpPermissionInbound)
|
|
16
|
+
MATCH (rule)<-[:MEMBER_OF_IP_RULE]-(ip:IpRange{range:'0.0.0.0/0'})
|
|
17
|
+
WHERE rule.fromport IN [22, 3389, 3306, 5432, 6379, 9200, 27017]
|
|
18
|
+
RETURN a.id as account_id, a.name AS account, ec2.instanceid AS instance_id, rule.fromport AS port, sg.groupid AS security_group order by account, instance_id, port, security_group
|
|
19
|
+
""",
|
|
20
|
+
cypher_visual_query="""
|
|
21
|
+
MATCH p=(a:AWSAccount)-[:RESOURCE]->(ec2:EC2Instance)-[:MEMBER_OF_EC2_SECURITY_GROUP]->(sg:EC2SecurityGroup)<-[:MEMBER_OF_EC2_SECURITY_GROUP]-(rule:IpPermissionInbound)
|
|
22
|
+
MATCH p2=(rule)<-[:MEMBER_OF_IP_RULE]-(ip:IpRange{range:'0.0.0.0/0'})
|
|
23
|
+
WHERE rule.fromport IN [22, 3389, 3306, 5432, 6379, 9200, 27017]
|
|
24
|
+
RETURN *
|
|
25
|
+
""",
|
|
26
|
+
module=Module.AWS,
|
|
27
|
+
maturity=Maturity.EXPERIMENTAL,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# Rule
|
|
32
|
+
class ComputeInstanceExposed(Finding):
|
|
33
|
+
instance: str | None = None
|
|
34
|
+
instance_id: str | None = None
|
|
35
|
+
account: str | None = None
|
|
36
|
+
account_id: str | None = None
|
|
37
|
+
port: int | None = None
|
|
38
|
+
security_group: str | None = None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
compute_instance_exposed = Rule(
|
|
42
|
+
id="compute_instance_exposed",
|
|
43
|
+
name="Internet-Exposed Compute Instances on Common Management Ports",
|
|
44
|
+
description=(
|
|
45
|
+
"Compute instances exposed to the internet on ports 22, 3389, 3306, 5432, 6379, 9200, 27017"
|
|
46
|
+
),
|
|
47
|
+
output_model=ComputeInstanceExposed,
|
|
48
|
+
facts=(_aws_ec2_instance_internet_exposed,),
|
|
49
|
+
tags=("infrastructure", "compute", "attack_surface"),
|
|
50
|
+
version="0.1.0",
|
|
51
|
+
)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from cartography.rules.spec.model import Fact
|
|
2
|
+
from cartography.rules.spec.model import Finding
|
|
3
|
+
from cartography.rules.spec.model import Maturity
|
|
4
|
+
from cartography.rules.spec.model import Module
|
|
5
|
+
from cartography.rules.spec.model import Rule
|
|
6
|
+
|
|
7
|
+
# AWS Facts
|
|
8
|
+
_aws_rds_public_access = Fact(
|
|
9
|
+
id="aws_rds_public_access",
|
|
10
|
+
name="Internet-Accessible RDS Database Attack Surface",
|
|
11
|
+
description="AWS RDS instances accessible from the internet",
|
|
12
|
+
cypher_query="""
|
|
13
|
+
MATCH (rds:RDSInstance)
|
|
14
|
+
WHERE rds.publicly_accessible = true
|
|
15
|
+
RETURN rds.id AS id,
|
|
16
|
+
rds.engine AS engine,
|
|
17
|
+
rds.db_instance_class AS instance_class,
|
|
18
|
+
rds.endpoint_address AS host,
|
|
19
|
+
rds.endpoint_port AS port,
|
|
20
|
+
rds.region AS region,
|
|
21
|
+
rds.storage_encrypted AS encrypted
|
|
22
|
+
""",
|
|
23
|
+
cypher_visual_query="""
|
|
24
|
+
MATCH p1=(rds:RDSInstance{publicly_accessible: true})
|
|
25
|
+
OPTIONAL MATCH p2=(rds)-[:MEMBER_OF_EC2_SECURITY_GROUP]->(sg:EC2SecurityGroup)
|
|
26
|
+
OPTIONAL MATCH p3=(rds)-[:MEMBER_OF_EC2_SECURITY_GROUP]->(sg:EC2SecurityGroup)<-[:MEMBER_OF_EC2_SECURITY_GROUP]-(rule:IpPermissionInbound:IpRule)
|
|
27
|
+
OPTIONAL MATCH p4=(rds)-[:MEMBER_OF_EC2_SECURITY_GROUP]->(sg:EC2SecurityGroup)<-[:MEMBER_OF_EC2_SECURITY_GROUP]-(rule:IpPermissionInbound:IpRule)<-[:MEMBER_OF_IP_RULE]-(ip:IpRange)
|
|
28
|
+
RETURN *
|
|
29
|
+
""",
|
|
30
|
+
module=Module.AWS,
|
|
31
|
+
maturity=Maturity.EXPERIMENTAL,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# Rule
|
|
36
|
+
class DatabaseInstanceExposed(Finding):
|
|
37
|
+
host: str | None = None
|
|
38
|
+
id: str | None = None
|
|
39
|
+
engine: str | None = None
|
|
40
|
+
port: int | None = None
|
|
41
|
+
region: str | None = None
|
|
42
|
+
encrypted: bool | None = None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
database_instance_exposed = Rule(
|
|
46
|
+
id="database_instance_exposed",
|
|
47
|
+
name="Internet-Exposed Databases",
|
|
48
|
+
description=("Database instances accessible from the internet"),
|
|
49
|
+
output_model=DatabaseInstanceExposed,
|
|
50
|
+
facts=(_aws_rds_public_access,),
|
|
51
|
+
tags=("infrastructure", "databases", "attack_surface"),
|
|
52
|
+
version="0.1.0",
|
|
53
|
+
)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from cartography.rules.spec.model import Fact
|
|
2
|
+
from cartography.rules.spec.model import Finding
|
|
3
|
+
from cartography.rules.spec.model import Maturity
|
|
4
|
+
from cartography.rules.spec.model import Module
|
|
5
|
+
from cartography.rules.spec.model import Rule
|
|
6
|
+
|
|
7
|
+
# AWS
|
|
8
|
+
_aws_trust_relationship_manipulation = Fact(
|
|
9
|
+
id="aws_trust_relationship_manipulation",
|
|
10
|
+
name="Roles with Cross-Account Trust Relationship Modification Capabilities",
|
|
11
|
+
description=(
|
|
12
|
+
"AWS IAM principals with permissions to modify role trust policies "
|
|
13
|
+
"(specifically AssumeRolePolicyDocuments)."
|
|
14
|
+
),
|
|
15
|
+
cypher_query="""
|
|
16
|
+
MATCH (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
|
|
17
|
+
MATCH (principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement {effect:"Allow"})
|
|
18
|
+
WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
|
|
19
|
+
AND NOT principal.name CONTAINS 'QuickSetup'
|
|
20
|
+
AND principal.name <> 'OrganizationAccountAccessRole'
|
|
21
|
+
WITH a, principal, policy, stmt,
|
|
22
|
+
[label IN labels(principal) WHERE label <> 'AWSPrincipal'][0] AS principal_type,
|
|
23
|
+
['iam:UpdateAssumeRolePolicy', 'iam:CreateRole'] AS patterns
|
|
24
|
+
// Filter for matching Allow actions
|
|
25
|
+
WITH a, principal, principal_type, stmt, policy,
|
|
26
|
+
[action IN stmt.action
|
|
27
|
+
WHERE ANY(p IN patterns WHERE action = p)
|
|
28
|
+
OR action = 'iam:*'
|
|
29
|
+
OR action = '*'
|
|
30
|
+
] AS matched_allow_actions
|
|
31
|
+
WHERE size(matched_allow_actions) > 0
|
|
32
|
+
// Look for any explicit Deny statement on same principal that matches those actions
|
|
33
|
+
OPTIONAL MATCH (principal)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(deny_stmt:AWSPolicyStatement {effect:"Deny"})
|
|
34
|
+
WHERE ANY(action IN deny_stmt.action
|
|
35
|
+
WHERE action IN matched_allow_actions
|
|
36
|
+
OR action = 'iam:*'
|
|
37
|
+
OR action = '*')
|
|
38
|
+
// Exclude principals with an explicit Deny that overlaps
|
|
39
|
+
WITH a, principal, principal_type, policy, stmt, matched_allow_actions, deny_stmt
|
|
40
|
+
WHERE deny_stmt IS NULL
|
|
41
|
+
UNWIND matched_allow_actions AS action
|
|
42
|
+
RETURN DISTINCT
|
|
43
|
+
a.name AS account,
|
|
44
|
+
a.id AS account_id,
|
|
45
|
+
principal.name AS principal_name,
|
|
46
|
+
principal.arn AS principal_identifier,
|
|
47
|
+
policy.name AS policy_name,
|
|
48
|
+
principal_type,
|
|
49
|
+
collect(DISTINCT action) AS actions,
|
|
50
|
+
stmt.resource AS resources
|
|
51
|
+
ORDER BY account, principal_name
|
|
52
|
+
""",
|
|
53
|
+
cypher_visual_query="""
|
|
54
|
+
MATCH p = (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
|
|
55
|
+
MATCH p1 = (principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
56
|
+
MATCH (principal)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
57
|
+
WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
|
|
58
|
+
AND principal.name <> 'OrganizationAccountAccessRole'
|
|
59
|
+
AND stmt.effect = 'Allow'
|
|
60
|
+
RETURN *
|
|
61
|
+
""",
|
|
62
|
+
module=Module.AWS,
|
|
63
|
+
maturity=Maturity.EXPERIMENTAL,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
# Rule
|
|
68
|
+
class DelegationBoundaryModifiable(Finding):
|
|
69
|
+
principal_name: str | None = None
|
|
70
|
+
principal_identifier: str | None = None
|
|
71
|
+
principal_type: str | None = None
|
|
72
|
+
account: str | None = None
|
|
73
|
+
account_id: str | None = None
|
|
74
|
+
policy_name: str | None = None
|
|
75
|
+
actions: list[str] = []
|
|
76
|
+
resources: list[str] = []
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
delegation_boundary_modifiable = Rule(
|
|
80
|
+
id="delegation_boundary_modifiable",
|
|
81
|
+
name="Delegation Boundary Modifiable",
|
|
82
|
+
description=(
|
|
83
|
+
"Principals can edit role trust/assume policies or create roles with arbitrary trust—"
|
|
84
|
+
"allowing cross-account or lateral impersonation paths."
|
|
85
|
+
),
|
|
86
|
+
output_model=DelegationBoundaryModifiable,
|
|
87
|
+
facts=(_aws_trust_relationship_manipulation,),
|
|
88
|
+
tags=("iam", "privilege_escalation"),
|
|
89
|
+
version="0.1.0",
|
|
90
|
+
)
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
from cartography.rules.spec.model import Fact
|
|
2
|
+
from cartography.rules.spec.model import Finding
|
|
3
|
+
from cartography.rules.spec.model import Maturity
|
|
4
|
+
from cartography.rules.spec.model import Module
|
|
5
|
+
from cartography.rules.spec.model import Rule
|
|
6
|
+
|
|
7
|
+
# AWS
|
|
8
|
+
_aws_account_manipulation_permissions = Fact(
|
|
9
|
+
id="aws_account_manipulation_permissions",
|
|
10
|
+
name="IAM Principals with Account Creation and Modification Permissions",
|
|
11
|
+
description=(
|
|
12
|
+
"AWS IAM users and roles with permissions to create, modify, or delete IAM "
|
|
13
|
+
"accounts and their associated policies."
|
|
14
|
+
),
|
|
15
|
+
cypher_query="""
|
|
16
|
+
MATCH (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
|
|
17
|
+
MATCH (principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
18
|
+
WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
|
|
19
|
+
AND NOT principal.name CONTAINS 'QuickSetup'
|
|
20
|
+
AND principal.name <> 'OrganizationAccountAccessRole'
|
|
21
|
+
AND stmt.effect = 'Allow'
|
|
22
|
+
WITH a, principal, stmt, policy,
|
|
23
|
+
[label IN labels(principal) WHERE label <> 'AWSPrincipal'][0] AS principal_type,
|
|
24
|
+
[p IN ['iam:Create','iam:Attach','iam:Put','iam:Update','iam:Add'] | p] AS patterns
|
|
25
|
+
// Match only Allow statements whose actions fit the patterns
|
|
26
|
+
WITH a, principal, principal_type, stmt, policy,
|
|
27
|
+
[action IN stmt.action
|
|
28
|
+
WHERE ANY(prefix IN patterns WHERE action STARTS WITH prefix)
|
|
29
|
+
OR action = 'iam:*'
|
|
30
|
+
OR action = '*'
|
|
31
|
+
] AS matched_allow_actions
|
|
32
|
+
WHERE size(matched_allow_actions) > 0
|
|
33
|
+
// Find explicit Deny statements for the same principal that overlap
|
|
34
|
+
OPTIONAL MATCH (principal)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(deny_stmt:AWSPolicyStatement {effect:"Deny"})
|
|
35
|
+
WHERE ANY(deny_action IN deny_stmt.action
|
|
36
|
+
WHERE deny_action IN matched_allow_actions
|
|
37
|
+
OR deny_action = 'iam:*'
|
|
38
|
+
OR deny_action = '*')
|
|
39
|
+
// If a deny exists, exclude those principals
|
|
40
|
+
WITH a, principal, principal_type, policy, stmt, matched_allow_actions, deny_stmt
|
|
41
|
+
WHERE deny_stmt IS NULL
|
|
42
|
+
UNWIND matched_allow_actions AS action
|
|
43
|
+
RETURN DISTINCT
|
|
44
|
+
a.name AS account,
|
|
45
|
+
a.id AS account_id,
|
|
46
|
+
principal.name AS principal_name,
|
|
47
|
+
principal.arn AS principal_identifier,
|
|
48
|
+
principal_type,
|
|
49
|
+
policy.name AS policy_name,
|
|
50
|
+
collect(DISTINCT action) AS actions,
|
|
51
|
+
stmt.resource AS resources
|
|
52
|
+
ORDER BY account, principal_name
|
|
53
|
+
""",
|
|
54
|
+
cypher_visual_query="""
|
|
55
|
+
MATCH p = (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
|
|
56
|
+
MATCH p1 = (principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
57
|
+
WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
|
|
58
|
+
AND NOT principal.name CONTAINS 'QuickSetup'
|
|
59
|
+
AND NOT principal.name = 'OrganizationAccountAccessRole'
|
|
60
|
+
AND stmt.effect = 'Allow'
|
|
61
|
+
AND ANY(action IN stmt.action WHERE
|
|
62
|
+
action STARTS WITH 'iam:Create'
|
|
63
|
+
OR action STARTS WITH 'iam:Attach'
|
|
64
|
+
OR action STARTS WITH 'iam:Put'
|
|
65
|
+
OR action STARTS WITH 'iam:Update'
|
|
66
|
+
OR action STARTS WITH 'iam:Add'
|
|
67
|
+
OR action = 'iam:*'
|
|
68
|
+
OR action = '*'
|
|
69
|
+
)
|
|
70
|
+
RETURN *
|
|
71
|
+
""",
|
|
72
|
+
module=Module.AWS,
|
|
73
|
+
maturity=Maturity.EXPERIMENTAL,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# Rule
|
|
78
|
+
class IdentityAdministrationPrivileges(Finding):
|
|
79
|
+
principal_name: str | None = None
|
|
80
|
+
principal_identifier: str | None = None
|
|
81
|
+
account: str | None = None
|
|
82
|
+
account_id: str | None = None
|
|
83
|
+
principal_type: str | None = None
|
|
84
|
+
policy_name: str | None = None
|
|
85
|
+
actions: list[str] = []
|
|
86
|
+
resources: list[str] = []
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
identity_administration_privileges = Rule(
|
|
90
|
+
id="identity_administration_privileges",
|
|
91
|
+
name="Identity Administration Privileges",
|
|
92
|
+
description=(
|
|
93
|
+
"Principals can create, attach, update, or otherwise administer identities "
|
|
94
|
+
"(users/roles/groups) and their bindings—classic escalation surface."
|
|
95
|
+
),
|
|
96
|
+
output_model=IdentityAdministrationPrivileges,
|
|
97
|
+
facts=(_aws_account_manipulation_permissions,),
|
|
98
|
+
tags=("iam", "privilege_escalation"),
|
|
99
|
+
version="0.1.0",
|
|
100
|
+
)
|