knarayan/cloud_posture_checks_name_and_desc huggingface dataset:
This policy identifies Azure Container Registries with anonymous authentication enabled, allowing unauthenticated access to the registry.

Allowing anonymous pull or access to container registries poses a significant security risk, exposing them to unauthorized users who may retrieve or manipulate container images. To enhance security, disable anonymous access and require authentication through Azure Active Directory (Azure AD). Additionally, local authentication methods such as admin user, repository-scoped access tokens, and anonymous pull should be turned off to ensure authentication relies solely on Azure AD, providing improved control and accountability.

As a security best practice, it is recommended to disable anonymous authentication for Azure Container Registries.
```config from cloud.resource where api.name = 'azure-container-registry' AND json.rule = (skuName contains Standard or skuName contains Premium) and properties.provisioningState equal ignore case Succeeded and properties.anonymousPullEnabled is false```
Azure Activity log alert for Create or update network security group rule does not exist
```config from cloud.resource where cloud.type = 'azure' AND api.name = 'azure-activity-log-alerts' AND json.rule = "location equal ignore case Global and properties.enabled equals true and properties.scopes[*] does not contain resourceGroups and properties.condition.allOf[?(@.field=='operationName')].equals equals Microsoft.Network/networkSecurityGroups/securityRules/write" as X; count(X) less than 1```
This policy identifies the Azure accounts in which activity log alert for Create or update network security group rule does not exist. Creating an activity log alert for Create or update network security group rule gives insight into network rule access changes and may reduce the time it takes to detect suspicious activity.
```config from cloud.resource where cloud.type = 'azure' AND api.name = 'azure-activity-log-alerts' AND json.rule = "location equal ignore case Global and properties.enabled equals true and properties.scopes[*] does not contain resourceGroups and properties.condition.allOf[?(@.field=='operationName')].equals equals Microsoft.Network/networkSecurityGroups/securityRules/write" as X; count(X) less than 1```
AWS RDS cluster encryption in transit is not configured
```config from cloud.resource where api.name = 'aws-rds-db-cluster' as X; config from cloud.resource where api.name = 'aws-rds-db-cluster-parameter-group' AND json.rule = (((DBParameterGroupFamily starts with "postgres" or DBParameterGroupFamily starts with "aurora-postgresql") and (['parameters'].['rds.force_ssl'].['ParameterValue'] does not equal 1 or ['parameters'].['rds.force_ssl'].['ParameterValue'] does not exist)) or ((DBParameterGroupFamily starts with "aurora-mysql" or DBParameterGroupFamily starts with "mysql") and (parameters.require_secure_transport.ParameterValue is not member of ("ON", "1") or parameters.require_secure_transport.ParameterValue does not exist))) as Y; filter '$.X.dBclusterParameterGroupArn equals $.Y.DBClusterParameterGroupArn' ; show X;```
This policy identifies AWS RDS database clusters that are not configured with encryption in transit. This covers MySQL, PostgreSQL, and Aurora clusters.

Enabling encryption is crucial to protect data as it moves through the network and enhances the security between clients and storage servers. Without encryption, sensitive data transmitted between your application and the database is vulnerable to interception by malicious actors. This could lead to unauthorized access, data breaches, and potential compromises of confidential information.

It is recommended that data be encrypted while in transit to ensure its security and reduce the risk of unauthorized access or data breaches.
```config from cloud.resource where api.name = 'aws-rds-db-cluster' as X; config from cloud.resource where api.name = 'aws-rds-db-cluster-parameter-group' AND json.rule = (((DBParameterGroupFamily starts with "postgres" or DBParameterGroupFamily starts with "aurora-postgresql") and (['parameters'].['rds.force_ssl'].['ParameterValue'] does not equal 1 or ['parameters'].['rds.force_ssl'].['ParameterValue'] does not exist)) or ((DBParameterGroupFamily starts with "aurora-mysql" or DBParameterGroupFamily starts with "mysql") and (parameters.require_secure_transport.ParameterValue is not member of ("ON", "1") or parameters.require_secure_transport.ParameterValue does not exist))) as Y; filter '$.X.dBclusterParameterGroupArn equals $.Y.DBClusterParameterGroupArn' ; show X;```
GCP Spanner Databases not encrypted with CMEK
```config from cloud.resource where cloud.type = 'gcp' AND api.name = 'gcloud-cloud-spanner-database' AND json.rule = state equal ignore case ready AND encryptionConfig.kmsKeyNames does not exist```
This policy identifies GCP Spanner databases that are not encrypted with a Customer-Managed Encryption Key (CMEK).

Google Cloud Spanner is a scalable, globally distributed, and strongly consistent database service. By using CMEK with Spanner, you retain complete control over the encryption keys protecting your sensitive data, ensuring that only authorized users with access to these keys can decrypt and access the information. Without CMEK, data is encrypted with Google-managed keys, which may not provide the level of control required for handling sensitive data in certain industries.

It is recommended to encrypt Spanner database data using a Customer-Managed Encryption Key (CMEK).
```config from cloud.resource where cloud.type = 'gcp' AND api.name = 'gcloud-cloud-spanner-database' AND json.rule = state equal ignore case ready AND encryptionConfig.kmsKeyNames does not exist```
AWS CloudFormation template contains globally open resources
```config from cloud.resource where cloud.type = 'aws' AND api.name = 'aws-cloudformation-describe-stacks' AND json.rule = "(($.stackResources[?( @.resourceType == 'AWS::EC2::SecurityGroup' || @.resourceType == 'AWS::EC2::SecurityGroupIngress' || @.resourceType == 'AWS::EC2::NetworkAclEntry')].resourceStatus any equal CREATE_COMPLETE) or ($.stackResources[?( @.resourceType == 'AWS::EC2::SecurityGroup' || @.resourceType == 'AWS::EC2::SecurityGroupIngress' || @.resourceType == 'AWS::EC2::NetworkAclEntry')].resourceStatus any equal UPDATE_COMPLETE)) and (($.cloudFormationTemplate.Resources.{}.SecurityGroupIngress[*].CidrIp any equal 0.0.0.0/0 or $.cloudFormationTemplate.Resources.{}.SecurityGroupIngress[*].CidrIpv6 any equal ::/0 or $.cloudFormationTemplate.Resources.{}.Properties.CidrIp any equal 0.0.0.0/0 or $.cloudFormationTemplate.Resources.{}.Properties.CidrIpv6 any equal ::/0) or ($.cloudFormationTemplate.Resources.{}.Properties.CidrBlock any equal 0.0.0.0/0 or $.cloudFormationTemplate.Resources.{}.Properties.Ipv6CidrBlock any equal ::/0 or $.cloudFormationTemplate.Resources.{}.Properties.Protocol any equal -1))"```
This alert triggers if a CloudFormation template that when launched will result in resources allowing global network access. Below are three common causes:

- Security Group with a {0.0.0.0/0, ::/0} rule
- Network Access Control List with a {0.0.0.0/0, ::/0} rule
- Network Access Control List with -1 IpProtocol
```config from cloud.resource where cloud.type = 'aws' AND api.name = 'aws-cloudformation-describe-stacks' AND json.rule = "(($.stackResources[?( @.resourceType == 'AWS::EC2::SecurityGroup' || @.resourceType == 'AWS::EC2::SecurityGroupIngress' || @.resourceType == 'AWS::EC2::NetworkAclEntry')].resourceStatus any equal CREATE_COMPLETE) or ($.stackResources[?( @.resourceType == 'AWS::EC2::SecurityGroup' || @.resourceType == 'AWS::EC2::SecurityGroupIngress' || @.resourceType == 'AWS::EC2::NetworkAclEntry')].resourceStatus any equal UPDATE_COMPLETE)) and (($.cloudFormationTemplate.Resources.{}.SecurityGroupIngress[*].CidrIp any equal 0.0.0.0/0 or $.cloudFormationTemplate.Resources.{}.SecurityGroupIngress[*].CidrIpv6 any equal ::/0 or $.cloudFormationTemplate.Resources.{}.Properties.CidrIp any equal 0.0.0.0/0 or $.cloudFormationTemplate.Resources.{}.Properties.CidrIpv6 any equal ::/0) or ($.cloudFormationTemplate.Resources.{}.Properties.CidrBlock any equal 0.0.0.0/0 or $.cloudFormationTemplate.Resources.{}.Properties.Ipv6CidrBlock any equal ::/0 or $.cloudFormationTemplate.Resources.{}.Properties.Protocol any equal -1))"```
Azure Activity log alert for Create policy assignment does not exist
```config from cloud.resource where cloud.type = 'azure' AND api.name = 'azure-activity-log-alerts' AND json.rule = "location equal ignore case Global and properties.enabled equals true and properties.scopes[*] does not contain resourceGroups and properties.condition.allOf[?(@.field=='operationName')].equals equals Microsoft.Authorization/policyAssignments/write" as X; count(X) less than 1```
This policy identifies the Azure accounts in which activity log alert for Create policy assignment does not exist. Creating an activity log alert for Create policy assignment gives insight into changes done in azure policy - assignments and may reduce the time it takes to detect unsolicited changes.
```config from cloud.resource where cloud.type = 'azure' AND api.name = 'azure-activity-log-alerts' AND json.rule = "location equal ignore case Global and properties.enabled equals true and properties.scopes[*] does not contain resourceGroups and properties.condition.allOf[?(@.field=='operationName')].equals equals Microsoft.Authorization/policyAssignments/write" as X; count(X) less than 1```
AWS CloudFront origin protocol policy does not enforce HTTPS-only
```config from cloud.resource where cloud.type = 'aws' AND api.name = 'aws-cloudfront-list-distributions' AND json.rule = enabled is true and origins.items[*] contains customOriginConfig and origins.items[?any(customOriginConfig.originProtocolPolicy does not contain https-only and ( domainName contains ".data.mediastore." or domainName contains ".mediapackage." or domainName contains ".elb." ))] exists```
This policy identifies AWS CloudFront which has an origin protocol policy that does not enforce HTTPS-only. Enforcing HTTPS protocol policy between origin and CloudFront will encrypt all communication and will be more secure. As a security best practice, enforce HTTPS-only traffic between a CloudFront distribution and the origin.
```config from cloud.resource where cloud.type = 'aws' AND api.name = 'aws-cloudfront-list-distributions' AND json.rule = enabled is true and origins.items[*] contains customOriginConfig and origins.items[?any(customOriginConfig.originProtocolPolicy does not contain https-only and ( domainName contains ".data.mediastore." or domainName contains ".mediapackage." or domainName contains ".elb." ))] exists```
OCI Load balancer not configured with Web application firewall (WAF)
```config from cloud.resource where api.name = 'oci-networking-loadbalancer' AND json.rule = listeners.*.protocol equals HTTP and lifecycleState equals ACTIVE and isPrivate is false as X; config from cloud.resource where api.name = 'oci-loadbalancer-waf' AND json.rule = lifecycleState equal ignore case ACTIVE and (webAppFirewallPolicyId exists and webAppFirewallPolicyId does not equal "null") as Y; filter 'not ($.X.id equals $.Y.loadBalancerId) '; show X;```
This policy identifies OCI Load balancers that are not configured with a Web application firewall (WAF).

A Web Application Firewall (WAF) helps protect web applications by filtering and monitoring HTTP traffic between a web application and the Internet. Without WAF, load balancers are vulnerable to various web-based attacks, including SQL injection, cross-site scripting (XSS), and other common exploits. This can lead to unauthorized access, data breaches, and other security incidents.

As a best practice, it is recommended to configure Web Application Firewall (WAF) for OCI Load Balancers to enhance security.
```config from cloud.resource where api.name = 'oci-networking-loadbalancer' AND json.rule = listeners.*.protocol equals HTTP and lifecycleState equals ACTIVE and isPrivate is false as X; config from cloud.resource where api.name = 'oci-loadbalancer-waf' AND json.rule = lifecycleState equal ignore case ACTIVE and (webAppFirewallPolicyId exists and webAppFirewallPolicyId does not equal "null") as Y; filter 'not ($.X.id equals $.Y.loadBalancerId) '; show X;```
AWS EMR cluster is not enabled with termination protection
```config from cloud.resource where cloud.type = 'aws' AND api.name = 'aws-emr-describe-cluster' AND json.rule = status.state does not contain TERMINATING and terminationProtected is false```
This policy identifies the AWS EMR Cluster that is not enabled with termination protection.

Termination protection serves as a safeguard against unintentional termination of your clusters. When this feature is enabled, any efforts to terminate the cluster via the AWS Management Console, CLI, or API will be prevented unless the protection is deliberately disabled beforehand. This feature is particularly beneficial for long-running or essential clusters, as accidental termination could lead to data loss or considerable downtime.

It is advisable to activate termination protection on AWS EMR clusters to prevent accidental terminations.
```config from cloud.resource where cloud.type = 'aws' AND api.name = 'aws-emr-describe-cluster' AND json.rule = status.state does not contain TERMINATING and terminationProtected is false```
Azure Database for MySQL flexible server public network access setting is enabled
```config from cloud.resource where cloud.type = 'azure' AND api.name = 'azure-mysql-flexible-server' AND json.rule = properties.state equal ignore case Ready and firewallRules[*] is empty and properties.network.publicNetworkAccess equal ignore case Enabled```
This policy identifies Azure Database for MySQL flexible servers which have public network access setting enabled.

Publicly accessible MySQL servers are vulnerable to external threats with risk of unauthorized access or may remotely exploit any vulnerabilities.

As a best security practice, it is recommended to configure the MySQL servers with IP-based strict server-level firewall rules or virtual-network rules or private endpoints so that servers are accessible only to restricted entities.
```config from cloud.resource where cloud.type = 'azure' AND api.name = 'azure-mysql-flexible-server' AND json.rule = properties.state equal ignore case Ready and firewallRules[*] is empty and properties.network.publicNetworkAccess equal ignore case Enabled```
OCI Hosts test - Ali
```config from cloud.resource where resource.status = Active AND api.name = 'oci-compute-instance' AND json.rule = lifecycleState exists```
```config from cloud.resource where resource.status = Active AND api.name = 'oci-compute-instance' AND json.rule = lifecycleState exists```
GCP Firewall rule allows all traffic on SMTP port (25)
```config from cloud.resource where cloud.type = 'gcp' AND api.name = 'gcloud-compute-firewall-rules-list' AND json.rule = disabled is false and direction equals INGRESS and (sourceRanges[*] equals ::0 or sourceRanges[*] equals 0.0.0.0 or sourceRanges[*] equals 0.0.0.0/0 or sourceRanges[*] equals ::/0 or sourceRanges[*] equals ::) and allowed[?any(ports contains _Port.inRange(25,25) or (ports does not exist and (IPProtocol contains tcp or IPProtocol contains udp)))] exists```
This policy identifies GCP Firewall rules which allow all inbound traffic on SMTP port (25). Allowing access from arbitrary IP addresses to this port increases the attack surface of your network. It is recommended that the SMTP port (25) should be allowed to specific IP addresses.
```config from cloud.resource where cloud.type = 'gcp' AND api.name = 'gcloud-compute-firewall-rules-list' AND json.rule = disabled is false and direction equals INGRESS and (sourceRanges[*] equals ::0 or sourceRanges[*] equals 0.0.0.0 or sourceRanges[*] equals 0.0.0.0/0 or sourceRanges[*] equals ::/0 or sourceRanges[*] equals ::) and allowed[?any(ports contains _Port.inRange(25,25) or (ports does not exist and (IPProtocol contains tcp or IPProtocol contains udp)))] exists```
Azure Key Vault secret has no expiration date (RBAC Key vault)
```config from cloud.resource where cloud.type = 'azure' AND api.name = 'azure-key-vault-list' and json.rule = secrets[?any(attributes.exp equals -1 and attributes.enabled contains true)] exists and properties.enableRbacAuthorization is true```
This policy identifies Azure Key Vault secrets that do not have an expiry date for the RBAC Key vaults. As a best practice, set an expiration date for each secret and rotate the secret regularly.

Before you activate this policy, ensure that you have added the Prisma Cloud Service Principal to each Key Vault: https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin/connect-your-cloud-platform-to-prisma-cloud/onboard-your-azure-account/azure-onboarding-checklist

Alternatively, run the following command on the Azure cloud shell:
az keyvault list | jq '.[].id' | xargs -I {} az role assignment create --assignee "<Object ID of Prisma Cloud Principal>" --role "Key Vault Reader" --scope {}
```config from cloud.resource where cloud.type = 'azure' AND api.name = 'azure-key-vault-list' and json.rule = secrets[?any(attributes.exp equals -1 and attributes.enabled contains true)] exists and properties.enableRbacAuthorization is true```
AWS CodeBuild project environment privileged mode is enabled
```config from cloud.resource where api.name = 'aws-code-build-project' AND json.rule = environment.privilegedMode exists and environment.privilegedMode is true```
This policy identifies the CodeBuild projects where the privileged mode is enabled. Privileged mode grants unrestricted access to all devices and runs the Docker daemon inside the container. It is recommended to enable this mode only for building Docker images. It recommended disabling the privileged mode to prevent unintended access to Docker APIs and container hardware, reducing the risk of potential tampering or critical resource deletion.
```config from cloud.resource where api.name = 'aws-code-build-project' AND json.rule = environment.privilegedMode exists and environment.privilegedMode is true```
GCP SQL MySQL DB instance point-in-time recovery backup (Binary logs) is not enabled
```config from cloud.resource where api.name='gcloud-sql-instances-list' AND json.rule='$.settings.backupConfiguration.binaryLogEnabled is false and $.databaseVersion contains MYSQL'```
This policy identifies Cloud SQL MySQL DB instances whose point-in-time recovery backup is not enabled. In case of an error, point-in-time recovery helps you recover an instance to a specific point in time. It is recommended to enable automated backups with point-in-time recovery to prevent any data loss in case of an unwanted scenario.
```config from cloud.resource where api.name='gcloud-sql-instances-list' AND json.rule='$.settings.backupConfiguration.binaryLogEnabled is false and $.databaseVersion contains MYSQL'```
AWS Elastic IP not in use
```config from cloud.resource where cloud.type = 'aws' AND api.name = 'aws-ec2-elastic-address' AND json.rule = associationId does not exist```
This policy identifies unused Elastic IP (EIP) addresses in your AWS account. Any Elastic IP in your AWS account is adding charges to your monthly bill, although it is not associated with any resources. As a best practice, it is recommended to associate/remove Elastic IPs that are not associated with any resources, it will also help you avoid unexpected charges on your bill.

For more details:
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html#using-instance-addressing-eips-associating
```config from cloud.resource where cloud.type = 'aws' AND api.name = 'aws-ec2-elastic-address' AND json.rule = associationId does not exist```
AWS Auto Scaling group launch configuration configured with Instance Metadata Service hop count greater than 1
```config from cloud.resource where api.name = 'aws-ec2-autoscaling-launch-configuration' AND json.rule = metadataOptions.httpEndpoint exists and metadataOptions.httpEndpoint equals "enabled" and metadataOptions.httpPutResponseHopLimit greater than 1 as X; config from cloud.resource where api.name = 'aws-describe-auto-scaling-groups' as Y; filter ' $.X.launchConfigurationName equal ignore case $.Y.launchConfigurationName'; show X;```
This policy identifies the autoscaling group launch configuration where the Instance Metadata Service network hops count is set to greater than 1. A launch configuration is an instance configuration template that an Auto Scaling group uses to launch EC2 instances. With the metadata response hop limit count for the IMDS greater than 1, the PUT response that contains the secret token can travel outside the EC2 instance. Only metadata with a limited hop count for all your EC2 instances is recommended.
```config from cloud.resource where api.name = 'aws-ec2-autoscaling-launch-configuration' AND json.rule = metadataOptions.httpEndpoint exists and metadataOptions.httpEndpoint equals "enabled" and metadataOptions.httpPutResponseHopLimit greater than 1 as X; config from cloud.resource where api.name = 'aws-describe-auto-scaling-groups' as Y; filter ' $.X.launchConfigurationName equal ignore case $.Y.launchConfigurationName'; show X;```
AWS Security group changes are not monitored
```config from cloud.resource where api.name = 'aws-logs-describe-metric-filters' as X; config from cloud.resource where api.name = 'aws-cloudwatch-describe-alarms' as Y; config from cloud.resource where api.name = 'aws-cloudtrail-describe-trails' as Z; filter '(($.Z.cloudWatchLogsLogGroupArn is not empty and $.Z.cloudWatchLogsLogGroupArn contains $.X.logGroupName and $.Z.isMultiRegionTrail is true and $.Z.includeGlobalServiceEvents is true) and (($.X.filterPattern contains "eventName=" or $.X.filterPattern contains "eventName =") and ($.X.filterPattern does not contain "eventName!=" and $.X.filterPattern does not contain "eventName !=") and $.X.filterPattern contains AuthorizeSecurityGroupIngress and $.X.filterPattern contains AuthorizeSecurityGroupEgress and $.X.filterPattern contains RevokeSecurityGroupIngress and $.X.filterPattern contains RevokeSecurityGroupEgress and $.X.filterPattern contains CreateSecurityGroup and $.X.filterPattern contains DeleteSecurityGroup) and ($.X.metricTransformations[*] contains $.Y.metricName))'; show X; count(X) less than 1```
```config from cloud.resource where api.name = 'aws-logs-describe-metric-filters' as X; config from cloud.resource where api.name = 'aws-cloudwatch-describe-alarms' as Y; config from cloud.resource where api.name = 'aws-cloudtrail-describe-trails' as Z; filter '(($.Z.cloudWatchLogsLogGroupArn is not empty and $.Z.cloudWatchLogsLogGroupArn contains $.X.logGroupName and $.Z.isMultiRegionTrail is true and $.Z.includeGlobalServiceEvents is true) and (($.X.filterPattern contains "eventName=" or $.X.filterPattern contains "eventName =") and ($.X.filterPattern does not contain "eventName!=" and $.X.filterPattern does not contain "eventName !=") and $.X.filterPattern contains AuthorizeSecurityGroupIngress and $.X.filterPattern contains AuthorizeSecurityGroupEgress and $.X.filterPattern contains RevokeSecurityGroupIngress and $.X.filterPattern contains RevokeSecurityGroupEgress and $.X.filterPattern contains CreateSecurityGroup and $.X.filterPattern contains DeleteSecurityGroup) and ($.X.metricTransformations[*] contains $.Y.metricName))'; show X; count(X) less than 1```
GCP PostgreSQL instance database flag log_parser_stats is not set to off
```config from cloud.resource where cloud.type = 'gcp' AND api.name = 'gcloud-sql-instances-list' AND json.rule = "state equals RUNNABLE and databaseVersion contains POSTGRES and (settings.databaseFlags[*].name does not contain log_parser_stats or settings.databaseFlags[?any(name contains log_parser_stats and value contains on)] exists)"```