Community
Questions Library
Docs
Blog
Events
Swag
Github
Slack
JupiterOne
Discussions
Release Notes
Contact Us
J1 Queries for AWS Config - AskJ1 Community
<main> <article class="userContent"> <p>AWS Config is a service provided by AWS that can be used to evaluate the configuration settings of your AWS resources. This is typically done by enabling AWS Config rules in one or multiple of your AWS accounts to represent your ideal configuration settings.</p> <p>There are a few downsides of AWS Config:</p> <ul><li><p>It can easily cost $500 to $1000+ per account per month depending on the number of resources in the account and number of rules you have configured.</p></li> <li><p>It is hard to fine tune AWS Config rules with the tags and other contextual data to reduce false positives.</p></li> <li><p>Setting up alerts and notifications requires additional configuration using SNS or CloudWatch.</p></li> </ul><p>Fortunately, almost all of evaluation of AWS Config rules can be done by a simple J1QL query/alert in JupiterOne. Additionally, each query can easily be modified to include tags or even relationship context.</p> <p>Here are some examples.</p> <h2 data-id="acm-rules">ACM Rules</h2> <p><strong>acm-certificate-expiration-check</strong></p> <p>Ensures ACM Certificates in your account are marked for expiration within the specified number of days.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_acm_certificate with expiresOn < date.now + 30days OR Find Certificate with expiresOn < date.now + 30days </pre> <h2 data-id="ec2-rules">EC2 Rules</h2> <p><strong>ec2-instances-in-vpc</strong></p> <p>Ensure all EC2 instances run in a VPC.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_instance with vpcId=undefined </pre> <p><strong>ec2-volume-inuse-check</strong></p> <p>Checks whether EBS volumes are attached to EC2 instances.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_ebs_volume that !USES aws_instance </pre> <p><strong>encrypted-volumes</strong></p> <p>Checks whether the EBS volumes that are in an attached state are encrypted.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_instance as i that USES aws_ebs_volume with encrypted!=true as v return i.tag.AccountName, i.name, i.instanceId, i.state, i.region, i.webLink, v.volumeId, v.encrypted, v.webLink </pre> <p><strong>restricted-ssh</strong></p> <p>Checks whether the incoming SSH traffic for the security groups is accessible.</p> <p>With AWS Config, this rule is compliant when the IP addresses of the incoming SSH traffic in the security groups are restricted. This rule applies only to IPv4.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_security_group as sg that ALLOWS as rule * as src where rule.ingress=true and rule.ipProtocol='tcp' and (rule.fromPort<=22 and rule.toPort>=22) return sg.displayName, rule.ipProtocol, rule.fromPort, rule.toPort, src.displayName, src.ipAddress, src.CIDR </pre> <h2 data-id="iam-rules">IAM Rules</h2> <p><strong>root-account-mfa-enabled</strong></p> <p>Ensure root AWS account has MFA enabled.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_account with _source!='system-mapper' and mfaEnabled!=true </pre> <p><strong>iam-root-access-key-check</strong></p> <p>Checks whether the root user access key is available.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_account with _source!='system-mapper' and rootUserAccessKeyEnabled!=false </pre> <p><strong>iam-password-policy</strong></p> <p>Ensure the account password policy for IAM users meets the specified requirements.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_iam_account_password_policy with requireUppercase != true or requireLowercase != true or requireSymbols != true or requireNumbers != true or minLength < 8 or maxAgeDays > 90 or historyCount < 12 </pre> <p>Adjust the above values to match your organization policy. You can also separate each into its own query.</p> <p><strong>iam-user-no-policies-check</strong></p> <p>Ensure that none of your IAM users have policies attached.</p> <p>IAM users should inherit permissions from IAM groups or roles.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_iam_user that assigned (aws_iam_user_policy|aws_iam_policy) </pre> <p>The <code class="code codeInline" spellcheck="false" tabindex="0">aws_iam_user_policy</code> in the above query specifies an inline policy whereas the <code class="code codeInline" spellcheck="false" tabindex="0">aws_iam_policy</code> is a managed policy.</p> <h2 data-id="lambda-rules">Lambda Rules</h2> <p><strong>lambda-function-public-access-prohibited</strong></p> <p>Checks whether the AWS Lambda function policy attached to the Lambda resource prohibits public access.</p> <p><strong>lambda-function-settings-check</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_lambda_function with runtime='nodejs6.10' Find aws_lambda_function with timeout < 5 or timeout > 300 Find aws_lambda_function with memorySize <= 128 or memorySize >= 1024 Find aws_lambda_function with role = '<role_arn>' </pre> <p>You can of course adjust any of the values in the above example queries.</p> <p><strong>Note that <code class="code codeInline" spellcheck="false" tabindex="0">nodejs6.10</code> is End-of-Life (EOL) as of April 2019.</strong><br> The first query above is an excellent check to ensure you have migrated all of your lambda functions to <code class="code codeInline" spellcheck="false" tabindex="0">nodejs8.10</code>.</p> <h2 data-id="rds-rules">RDS Rules</h2> <p><strong>db-instance-backup-enabled</strong></p> <p>Checks whether RDS DB instances have backups enabled.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find (aws_db_instance|aws_rds_cluster) with backupRetentionPeriod=undefined </pre> <p><em>Optionally, the rule checks the backup retention period and the backup window.</em></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find (aws_db_instance|aws_rds_cluster) with backupRetentionPeriod=undefined or backupRetentionPeriod<30 </pre> <p><strong>rds-instance-public-access-check</strong></p> <p>Check whether the Amazon RDS clusters and instances are publicly accessible.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find (aws_db_instance|aws_rds_cluster) with public=true </pre> <p><strong>rds-snapshots-public-prohibited</strong></p> <p>Checks if Amazon Relational Database Service (Amazon RDS) snapshots are public. The rule is non-compliant if any existing and new Amazon RDS snapshots are public.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find (aws_db_snapshot|aws_db_cluster_snapshot) with public=true </pre> <p><strong>rds-storage-encrypted</strong></p> <p>Checks whether storage encryption is enabled for your RDS DB instances.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find (aws_db_instance|aws_rds_cluster) with encrypted!=true </pre> <p>See a visual graph of which RDS cluster/instance is using which KMS key with the following query:</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find (aws_db_instance|aws_rds_cluster) that uses aws_kms_key return tree </pre> <p>You can easily extend the query to cover other data stores and check for their encryption status across the board:</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find DataStore with encrypted!=true </pre> <p>The above query covers <strong>RDS instances/clusters</strong>, <strong>S3 buckets</strong>, <strong>EBS volumes</strong>,<br><strong>DynamoDB tables</strong>, <strong>Redshift clusters</strong> all at once.</p> <p>This is often combined with some tagging to reduce false positives. For example:</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find DataStore with encrypted!=true and (classification='critical' or classification='confidential') </pre> <h2 data-id="dynamodb-rules">DynamoDB Rules</h2> <p><strong>dynamodb-throughput-limit-check</strong></p> <p>Checks whether provisioned DynamoDB throughput is approaching the maximum limit for your account. By default, the rule checks if provisioned throughput exceeds a threshold of 80% of your account limits.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">n/a </pre> <h2 data-id="s3-rules">S3 Rules</h2> <p><strong>s3-bucket-public-read-prohibited</strong></p> <p>Checks that your Amazon S3 buckets do not allow public read access.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_s3_bucket that ALLOWS as grant Everyone where grant.permission='READ' </pre> <p>Or, to return certain specific properties about the bucket and the rule:</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_s3_bucket as bucket that ALLOWS as grant everyone where grant.permission='READ' return bucket.displayName, bucket.tag.AccountName, grant.permission, grant.granteeType, grant.granteeURI </pre> <p><strong>s3-bucket-public-write-prohibited</strong></p> <p>Checks that your Amazon S3 buckets do not allow public write access.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_s3_bucket that ALLOWS as grant Everyone where grant.permission='WRITE' </pre> <p><strong>s3-bucket-replication-enabled</strong></p> <p>Checks whether S3 buckets have cross-region replication enabled.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_s3_bucket with replicationEnabled != true or destinationBuckets = undefined </pre> <p><strong>s3-bucket-server-side-encryption-enabled</strong></p> <p>Checks whether server side encryption is enabled for your S3 buckets.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_s3_bucket with encrypted=false and defaultEncryptionEnabled=false </pre> <p><strong>s3-bucket-ssl-requests-only</strong></p> <p>Checks whether S3 buckets have policies that require requests to use Secure Socket Layer (SSL/TLS).</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_s3_bucket with secureTransport != true </pre> <p><strong>s3-bucket-logging-enabled</strong></p> <p>Checks whether logging is enabled for your S3 buckets.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_s3_bucket with loggingEnabled != true </pre> <p><strong>s3-bucket-versioning-enabled</strong></p> <p>Checks whether versioning is enabled for your S3 buckets. Optionally, the rule checks if MFA delete is enabled for your S3 buckets.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_s3_bucket with versioningEnabled != true or mfaDelete != true </pre> <h2 data-id="other-rules">Other Rules</h2> <p><strong>cloudtrail-enabled</strong></p> <p>Ensure CloudTrail is enabled.</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">Find aws_account that !HAS aws_cloudtrail </pre> </article> </main>