From 980a85e018658ba02d95a698848c03a7dddfca56 Mon Sep 17 00:00:00 2001 From: Yevgeny Pats <16490766+yevgenypats@users.noreply.github.com> Date: Thu, 20 Jul 2023 11:15:16 +0300 Subject: [PATCH] feat(aws-foundational): Initial commit --- README.md | 5 +- .../snowflake/.gitignore | 2 + aws/foundational_security/snowflake/README.md | 14 +++ .../snowflake/env.example | 6 + aws/foundational_security/snowflake/main.py | 51 ++++++++ .../snowflake/queries/__init__.py | 0 .../snowflake/queries/account.py | 24 ++++ .../snowflake/queries/acm.py | 19 +++ .../snowflake/queries/apigateway.py | 39 ++++++ .../snowflake/queries/awsconfig.py | 18 +++ .../snowflake/queries/cloudfront.py | 119 ++++++++++++++++++ .../snowflake/queries/cloudtrail.py | 74 +++++++++++ .../snowflake/queries/codebuild.py | 45 +++++++ .../snowflake/queries/dms.py | 17 +++ .../snowflake/queries/dynamodb.py | 66 ++++++++++ .../snowflake/queries/iam.py | 0 .../snowflake/requirements.txt | 20 +++ .../snowflake/sections.py | 75 +++++++++++ 18 files changed, 593 insertions(+), 1 deletion(-) create mode 100644 aws/foundational_security/snowflake/.gitignore create mode 100644 aws/foundational_security/snowflake/README.md create mode 100644 aws/foundational_security/snowflake/env.example create mode 100644 aws/foundational_security/snowflake/main.py create mode 100644 aws/foundational_security/snowflake/queries/__init__.py create mode 100644 aws/foundational_security/snowflake/queries/account.py create mode 100644 aws/foundational_security/snowflake/queries/acm.py create mode 100644 aws/foundational_security/snowflake/queries/apigateway.py create mode 100644 aws/foundational_security/snowflake/queries/awsconfig.py create mode 100644 aws/foundational_security/snowflake/queries/cloudfront.py create mode 100644 aws/foundational_security/snowflake/queries/cloudtrail.py create mode 100644 aws/foundational_security/snowflake/queries/codebuild.py create mode 100644 aws/foundational_security/snowflake/queries/dms.py create mode 100644 aws/foundational_security/snowflake/queries/dynamodb.py create mode 100644 aws/foundational_security/snowflake/queries/iam.py create mode 100644 aws/foundational_security/snowflake/requirements.txt create mode 100644 aws/foundational_security/snowflake/sections.py diff --git a/README.md b/README.md index f355aecbb..781dcd2a2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ -# policies-premium +# Premium Policies + Premium policies for CloudQuery plugins. + +Policies are split by plugin and then by policy type. Each policy can have multiple ports for different databases (for example Snowflake and BigQuery). \ No newline at end of file diff --git a/aws/foundational_security/snowflake/.gitignore b/aws/foundational_security/snowflake/.gitignore new file mode 100644 index 000000000..dc12cb744 --- /dev/null +++ b/aws/foundational_security/snowflake/.gitignore @@ -0,0 +1,2 @@ +.env +__pycache__ \ No newline at end of file diff --git a/aws/foundational_security/snowflake/README.md b/aws/foundational_security/snowflake/README.md new file mode 100644 index 000000000..152ba9e61 --- /dev/null +++ b/aws/foundational_security/snowflake/README.md @@ -0,0 +1,14 @@ +# AWS Foundational Security Best Practices pack with Snowflake SQL + +## Requirements + +### CloudQuery Sync + +Make sure you synced your AWS metadata with CloudQuery [AWS source plugin](https://www.cloudquery.io/docs/plugins/sources/overview) and [Snowflake destinatio](https://www.cloudquery.io/docs/plugins/destinations/snowflake/overview). + +### Run the policy + +- Install Python > 3.8 +- Run `pip install -r requirements.txt` +- Run `cp env.example` to `.env` and fill the snowflake environment credentials +- Run `python main.py` diff --git a/aws/foundational_security/snowflake/env.example b/aws/foundational_security/snowflake/env.example new file mode 100644 index 000000000..7ebdeeb9e --- /dev/null +++ b/aws/foundational_security/snowflake/env.example @@ -0,0 +1,6 @@ +SNOW_USER= +SNOW_PASS= +SNOW_ACCOUNT= +SNOW_WAREHOUSE= +SNOW_DATABASE= +SNOW_SCHEMA= \ No newline at end of file diff --git a/aws/foundational_security/snowflake/main.py b/aws/foundational_security/snowflake/main.py new file mode 100644 index 000000000..40a43374b --- /dev/null +++ b/aws/foundational_security/snowflake/main.py @@ -0,0 +1,51 @@ + +import os +import sys +import datetime +import argparse +import sections +import snowflake.connector + +from dotenv import load_dotenv + +load_dotenv() # take environment variables from .env. + +def run_policy(args): + print("Running doundational Security Policy") + conn = snowflake.connector.connect( + user=os.environ.get("SNOW_USER"), + password=os.environ.get("SNOW_PASSWORD"), + account=os.environ.get("SNOW_ACCOUNT"), + warehouse=os.environ.get("SNOW_WAREHOUSE"), + database=os.environ.get("SNOW_DATABASE"), + schema=os.environ.get("SNOW_SCHEMA"), + ) + execution_time = datetime.datetime.now() + # sections.execute_account(conn, execution_time) + # sections.execute_acm(conn, execution_time) + # sections.execute_apigateway(conn, execution_time) + # sections.execute_awsconfig(conn, execution_time) + # sections.execute_cloudfront(conn, execution_time) + # sections.execute_cloudtrail(conn, execution_time) + # sections.execute_codebuild(conn, execution_time) + sections.execute_dynamodb(conn, execution_time) + print("Finished running doundational security policy") + +def create_views(args): + pass + +def main(): + parser = argparse.ArgumentParser( + prog='aws-foundational-snowflake', + description='Foundational security policy with Snowflake SQL') + subparsers = parser.add_subparsers(help='sub-command help', required=True) + parser_run_policy = subparsers.add_parser('run-policy', help='run policy') + parser_run_policy.set_defaults(func=run_policy) + parser_create_views = subparsers.add_parser('create-view', help='create all required views') + parser_create_views.set_defaults(func=run_policy) + args = parser.parse_args(sys.argv[1:]) + args.func(args) + + +if __name__ == '__main__': + main() diff --git a/aws/foundational_security/snowflake/queries/__init__.py b/aws/foundational_security/snowflake/queries/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/aws/foundational_security/snowflake/queries/account.py b/aws/foundational_security/snowflake/queries/account.py new file mode 100644 index 000000000..0ab88919c --- /dev/null +++ b/aws/foundational_security/snowflake/queries/account.py @@ -0,0 +1,24 @@ + + + +SECURITY_ACCOUNT_INFORMATION_PROVIDED = """ +INSERT INTO aws_policy_results +SELECT + %s as execution_time, + %s as framework, + %s as check_id, + 'Security contact information should be provided for an AWS account' AS "title", + 'aws_iam_accounts.account_id' as "account_id", + 'aws_iam_accounts.account_id' as "resource_id", + CASE WHEN + 'alternate_contact_type' IS NULL + THEN 'fail' + ELSE 'pass' + END AS "status" +FROM aws_iam_accounts +LEFT JOIN ( + SELECT * FROM aws_account_alternate_contacts + WHERE 'alternate_contact_type' = 'SECURITY' +) AS account_security_contacts +ON 'aws_iam_accounts.account_id' = 'account_security_contacts.account_id' +""" diff --git a/aws/foundational_security/snowflake/queries/acm.py b/aws/foundational_security/snowflake/queries/acm.py new file mode 100644 index 000000000..75e3f52ac --- /dev/null +++ b/aws/foundational_security/snowflake/queries/acm.py @@ -0,0 +1,19 @@ +import datetime +from snowflake.connector import SnowflakeConnection + +CERTIFICATES_SHOULD_BE_RENEWED = """ +insert into aws_policy_results +select + %s as execution_time, + %s as framework, + %s as check_id, + 'certificate has less than 30 days to be renewed' as title, + account_id, + arn AS resource_id, + case when + not_after < DATEADD('day', 30, CURRENT_TIMESTAMP()::timestamp_ntz) + then 'fail' + else 'pass' + end as status +FROM aws_acm_certificates +""" diff --git a/aws/foundational_security/snowflake/queries/apigateway.py b/aws/foundational_security/snowflake/queries/apigateway.py new file mode 100644 index 000000000..e2ca517d0 --- /dev/null +++ b/aws/foundational_security/snowflake/queries/apigateway.py @@ -0,0 +1,39 @@ + +API_GW_EXECUTION_LOGGING_ENABLED = """ +insert into aws_policy_results +(select distinct + %s as execution_time, + %s as framework, + %s as check_id, + 'API Gateway REST and WebSocket API logging should be enabled' as title, + r.account_id, + 'arn:' || 'aws' || ':apigateway:' || r.region || ':/restapis/' || r.id as resource_id, + case + when s.logging_level not in ('"ERROR"', '"INFO"') then 'fail' + else 'pass' + end as status +from + view_aws_apigateway_method_settings s +left join + aws_apigateway_rest_apis r on s.rest_api_arn = r.arn +) + +union + +(select distinct + %s as execution_time, + %s as framework, + %s as check_id, + 'API Gateway REST and WebSocket API logging should be enabled' as title, + a.account_id, + 'arn:' || 'aws' || ':apigateway:' || a.region || ':/apis/' || a.id as resource_id, + case + WHEN s.default_route_settings:LoggingLevel IN (NULL, 'OFF') THEN 'fail' + else 'pass' + end as status +from + aws_apigatewayv2_api_stages s +left join + aws_apigatewayv2_apis a on s.api_arn = a.arn +) +""" \ No newline at end of file diff --git a/aws/foundational_security/snowflake/queries/awsconfig.py b/aws/foundational_security/snowflake/queries/awsconfig.py new file mode 100644 index 000000000..d9251a107 --- /dev/null +++ b/aws/foundational_security/snowflake/queries/awsconfig.py @@ -0,0 +1,18 @@ + +ENABLED_ALL_REGIONS = """ +insert into aws_policy_results +select + %s as execution_time, + %s as framework, + %s as check_id, + 'AWS Config should be enabled' as title, + account_id, + arn as resource_id, + CASE + WHEN ((recording_group:IncludeGlobalResourceTypes::BOOLEAN != TRUE) OR (recording_group:AllSupported::BOOLEAN != TRUE) OR (status_recording != TRUE OR status_last_status != 'SUCCESS')) + THEN 'fail' + ELSE 'pass' + END AS status +FROM + aws_config_configuration_recorders +""" \ No newline at end of file diff --git a/aws/foundational_security/snowflake/queries/cloudfront.py b/aws/foundational_security/snowflake/queries/cloudfront.py new file mode 100644 index 000000000..dc22a5e1d --- /dev/null +++ b/aws/foundational_security/snowflake/queries/cloudfront.py @@ -0,0 +1,119 @@ + +DEFAULT_ROOT_OBJECT_CONFIGURED = """ +insert into aws_policy_results +select + %s as execution_time, + %s as framework, + %s as check_id, + 'CloudFront distributions should have a default root object configured' as title, + account_id, + arn as resource_id, + CASE + WHEN distribution_config:DefaultRootObject::STRING = '' THEN 'fail' + ELSE 'pass' + END AS status +from aws_cloudfront_distributions +""" + +ORIGIN_ACCESS_IDENTITY_ENABLED = """ +insert into aws_policy_results +select + %s as execution_time, + %s as framework, + %s as check_id, + 'CloudFront distributions should have origin access identity enabled' as title, + account_id, + arn as resource_id, + CASE + WHEN o.value:DomainName::STRING LIKE '%%s3.amazonaws.com' AND o.value:S3OriginConfig:OriginAccessIdentity::STRING = '' THEN 'fail' + ELSE 'pass' + END AS status +from aws_cloudfront_distributions, LATERAL FLATTEN(input => distribution_config:Origins:Items) o +""" + +VIEWER_POLICY_HTTPS = """ +insert into aws_policy_results +WITH cachebeviors AS ( + -- Handle all non-defaults as well as when there is only a default route + SELECT DISTINCT arn, account_id + FROM ( + SELECT arn, account_id, d.value AS CacheBehavior + FROM aws_cloudfront_distributions, + LATERAL FLATTEN(input => distribution_config:CacheBehaviors:Items) AS d + WHERE distribution_config:CacheBehaviors:Items IS NOT NULL + UNION + -- Handle default Cachebehaviors + SELECT arn, account_id, distribution_config:DefaultCacheBehavior AS CacheBehavior + FROM aws_cloudfront_distributions + ) AS cachebeviors + WHERE CacheBehavior:ViewerProtocolPolicy::STRING = 'allow-all' +) +select + %s as execution_time, + %s as framework, + %s as check_id, + 'CloudFront distributions should require encryption in transit' as title, + account_id, + arn as resource_id, + 'fail' as status +from cachebeviors +""" + +ORIGIN_FAILOVER_ENABLED = """ +insert into aws_policy_results +with origin_groups as ( select acd.arn, distribution_config:OriginGroups:Items as ogs from aws_cloudfront_distributions acd), + oids as ( +select distinct + account_id, + acd.arn as resource_id, + case + when o.ogs = 'null' or + o.ogs:Members:Items = 'null' or + ARRAY_SIZE(o.ogs:Members:Items) = 0 then 'fail' + else 'pass' + end as status +from aws_cloudfront_distributions acd + left join origin_groups o on o.arn = acd.arn +) +select + %s as execution_time, + %s as framework, + %s as check_id, + 'CloudFront distributions should have origin failover configured' as title, + account_id, + resource_id, + status +from oids +""" + +ACCESS_LOGS_ENABLED = """ +insert into aws_policy_results +select + %s as execution_time, + %s as framework, + %s as check_id, + 'CloudFront distributions should have logging enabled' as title, + account_id, + arn as resource_id, + case + when (distribution_config:Logging:Enabled)::boolean is distinct from true then 'fail' + else 'pass' + end as status +from aws_cloudfront_distributions +""" + +ASSOCIATED_WITH_WAF = """ +insert into aws_policy_results +select + %s as execution_time, + %s as framework, + %s as check_id, + 'API Gateway should be associated with an AWS WAF web ACL' as title, + account_id, + arn as resource_id, + case + when distribution_config:WebACLId = '' then 'fail' + else 'pass' + end as status +from aws_cloudfront_distributions +""" \ No newline at end of file diff --git a/aws/foundational_security/snowflake/queries/cloudtrail.py b/aws/foundational_security/snowflake/queries/cloudtrail.py new file mode 100644 index 000000000..20168d5ad --- /dev/null +++ b/aws/foundational_security/snowflake/queries/cloudtrail.py @@ -0,0 +1,74 @@ + +ENABLED_ALL_REGIONS = """ +insert into aws_policy_results +select + %s as execution_time, + %s as framework, + %s as check_id, + 'Ensure CloudTrail is enabled in all regions' as title, + aws_cloudtrail_trails.account_id, + arn as resource_id, + case + when is_multi_region_trail = FALSE or ( + is_multi_region_trail = TRUE and ( + read_write_type != 'All' or include_management_events = FALSE + )) then 'fail' + else 'pass' + end as status +from aws_cloudtrail_trails +inner join + aws_cloudtrail_trail_event_selectors on + aws_cloudtrail_trails.arn = aws_cloudtrail_trail_event_selectors.trail_arn + and aws_cloudtrail_trails.region = aws_cloudtrail_trail_event_selectors.region + and aws_cloudtrail_trails.account_id = aws_cloudtrail_trail_event_selectors.account_id +""" + +LOGS_ENCRYPTED = """ +insert into aws_policy_results +select + %s as execution_time, + %s as framework, + %s as check_id, + 'CloudTrail should have encryption at rest enabled' as title, + account_id, + arn as resource_id, + case + when kms_key_id is NULL then 'fail' + else 'pass' + end as status +FROM aws_cloudtrail_trails +""" + +LOGS_FILE_VALIDATION_ENABLED = """ +insert into aws_policy_results +select + %s as execution_time, + %s as framework, + %s as check_id, + 'Ensure CloudTrail log file validation is enabled' as title, + account_id, + arn as resource_id, + case + when log_file_validation_enabled = false then 'fail' + else 'pass' + end as status +from aws_cloudtrail_trails +""" + +INTEGRATED_WITH_CLOUDWATCH_LOGS = """ +INSERT INTO aws_policy_results +SELECT + %s as execution_time, + %s as framework, + %s as check_id, + 'CloudTrail trails should be integrated with CloudWatch Logs' as title, + account_id, + arn as resource_id, + CASE + WHEN cloud_watch_logs_log_group_arn IS NULL + OR TO_TIMESTAMP(status:LatestCloudWatchLogsDeliveryTime) < DATEADD('day', -1, CURRENT_TIMESTAMP()) + THEN 'fail' + ELSE 'pass' + END as status +FROM aws_cloudtrail_trails +""" \ No newline at end of file diff --git a/aws/foundational_security/snowflake/queries/codebuild.py b/aws/foundational_security/snowflake/queries/codebuild.py new file mode 100644 index 000000000..c7b0d722d --- /dev/null +++ b/aws/foundational_security/snowflake/queries/codebuild.py @@ -0,0 +1,45 @@ + +CHECK_OAUTH_USAGE_FOR_SOURCES = """ +INSERT INTO aws_policy_results +SELECT DISTINCT + %s as execution_time, + %s as framework, + %s as check_id, + 'CodeBuild project environment variables should not contain clear text credentials' as title, + account_id, + arn as resource_id, + CASE WHEN + e.VALUE:Type::STRING = 'PLAINTEXT' + AND ( + UPPER(e.VALUE:Name::STRING) LIKE '%%ACCESS_KEY%%' + OR UPPER(e.VALUE:Name::STRING) LIKE '%%SECRET%%' + OR UPPER(e.VALUE:Name::STRING) LIKE '%%PASSWORD%%' + ) + THEN 'fail' + ELSE 'pass' + END as status +FROM aws_codebuild_projects, +LATERAL FLATTEN(input => environment:EnvironmentVariables) as e +""" + +CHECK_ENVIRONMENT_VARIABLES = """ +insert into aws_policy_results +select distinct + %s as execution_time, + %s as framework, + %s as check_id, + 'CodeBuild project environment variables should not contain clear text credentials' as title, + account_id, + arn as resource_id, + case when + e.Value:Type = 'PLAINTEXT' + and ( + UPPER(e.Value:Name) like '%%ACCESS_KEY%%' or + UPPER(e.Value:Name) like '%%SECRET%%' or + UPPER(e.Value:Name) like '%%PASSWORD%%' + ) + then 'fail' + else 'pass' + end as status +from aws_codebuild_projects, LATERAL FLATTEN(input => environment:EnvironmentVariables) as e +""" diff --git a/aws/foundational_security/snowflake/queries/dms.py b/aws/foundational_security/snowflake/queries/dms.py new file mode 100644 index 000000000..95c907646 --- /dev/null +++ b/aws/foundational_security/snowflake/queries/dms.py @@ -0,0 +1,17 @@ + +REPLICATION_NOT_PUBLIC = """ +insert into aws_policy_results +select + %s as execution_time, + %s as framework, + %s as check_id, + 'AWS Database Migration Service replication instances should not be public' as title, + account_id, + arn as resource_id, + case when + publicly_accessible is true + then 'fail' + else 'pass' + end as status +from aws_dms_replication_instances +""" \ No newline at end of file diff --git a/aws/foundational_security/snowflake/queries/dynamodb.py b/aws/foundational_security/snowflake/queries/dynamodb.py new file mode 100644 index 000000000..82c9fa0f0 --- /dev/null +++ b/aws/foundational_security/snowflake/queries/dynamodb.py @@ -0,0 +1,66 @@ + +AUTOSCALE_OR_ONDEMAND = """ +INSERT INTO aws_policy_results +SELECT + %s as execution_time, + %s as framework, + %s as check_id, + 'DynamoDB tables should automatically scale capacity with demand' as title, + t.account_id, + pr.arn as resource_id, + CASE WHEN + t.billing_mode_summary:BillingMode IS DISTINCT FROM 'PAY_PER_REQUEST' + AND ( + (s.replica_provisioned_read_capacity_auto_scaling_settings:AutoScalingDisabled::BOOLEAN IS DISTINCT FROM FALSE) + OR (s.replica_provisioned_write_capacity_auto_scaling_settings:AutoScalingDisabled::BOOLEAN IS DISTINCT FROM FALSE) + ) + AND (pr._cq_id IS NULL OR pw._cq_id IS NULL) + then 'fail' + else 'pass' + end as status +FROM aws_dynamodb_tables t + LEFT JOIN aws_dynamodb_table_replica_auto_scalings s ON s.table_arn = t.arn + LEFT JOIN aws_applicationautoscaling_policies pr ON (pr.service_namespace = 'dynamodb' + AND pr.resource_id = CONCAT('table/', t.table_name) + AND pr.policy_type = 'TargetTrackingScaling' + AND pr.scalable_dimension = 'dynamodb:table:ReadCapacityUnits') + LEFT JOIN aws_applicationautoscaling_policies pw ON (pw.service_namespace = 'dynamodb' + AND pw.resource_id = CONCAT('table/', t.table_name) + AND pw.policy_type = 'TargetTrackingScaling' + AND pw.scalable_dimension = 'dynamodb:table:WriteCapacityUnits'); +""" + +POINT_IN_TIME_RECOVERY = """ +insert into aws_policy_results +select + %s as execution_time, + %s as framework, + %s as check_id, + 'DynamoDB tables should have point-in-time recovery enabled' as title, + t.account_id, + t.arn as resource_id, + case when + b.point_in_time_recovery_description:PointInTimeRecoveryStatus is distinct from 'ENABLED' + then 'fail' + else 'pass' + end as status +FROM aws_dynamodb_tables t + LEFT JOIN aws_dynamodb_table_continuous_backups b ON b.table_arn = t.arn +""" + +DAX_ENCRYPTED_AT_REST = """ +insert into aws_policy_results +select + %s as execution_time, + %s as framework, + %s as check_id, + 'DynamoDB Accelerator (DAX) clusters should be encrypted at rest' as title, + account_id, + arn as resource_id, + case when + sse_description:Status is distinct from 'ENABLED' + then 'fail' + else 'pass' + end as status +from aws_dax_clusters +""" \ No newline at end of file diff --git a/aws/foundational_security/snowflake/queries/iam.py b/aws/foundational_security/snowflake/queries/iam.py new file mode 100644 index 000000000..e69de29bb diff --git a/aws/foundational_security/snowflake/requirements.txt b/aws/foundational_security/snowflake/requirements.txt new file mode 100644 index 000000000..9ff5f6504 --- /dev/null +++ b/aws/foundational_security/snowflake/requirements.txt @@ -0,0 +1,20 @@ +asn1crypto==1.5.1 +certifi==2023.5.7 +cffi==1.15.1 +charset-normalizer==3.2.0 +cryptography==40.0.2 +filelock==3.12.2 +idna==3.4 +oscrypto==1.3.0 +packaging==23.1 +pycparser==2.21 +pycryptodomex==3.18.0 +PyJWT==2.8.0 +pyOpenSSL==23.2.0 +python-dotenv==1.0.0 +pytz==2023.3 +requests==2.31.0 +snowflake-connector-python==3.0.4 +sortedcontainers==2.4.0 +typing_extensions==4.7.1 +urllib3==1.26.16 diff --git a/aws/foundational_security/snowflake/sections.py b/aws/foundational_security/snowflake/sections.py new file mode 100644 index 000000000..19327d8d4 --- /dev/null +++ b/aws/foundational_security/snowflake/sections.py @@ -0,0 +1,75 @@ + +import datetime +from queries import account, acm, apigateway, awsconfig, cloudfront, cloudtrail, codebuild, dms, dynamodb +from snowflake.connector import SnowflakeConnection + +FRAMEWORK = 'Foundational Security Policy' + +def execute_account(conn: SnowflakeConnection, execution_time: datetime.datetime): + print("Running section: account") + print("Running check: account.1") + conn.cursor().execute(account.SECURITY_ACCOUNT_INFORMATION_PROVIDED, (execution_time, FRAMEWORK, 'account.1')) + +def execute_acm(conn: SnowflakeConnection, execution_time: datetime.datetime): + print("Running section: acm") + print("Running check: acm.1") + conn.cursor().execute(acm.CERTIFICATES_SHOULD_BE_RENEWED, (execution_time, FRAMEWORK, 'acm.1')) + +def execute_apigateway(conn: SnowflakeConnection, execution_time: datetime.datetime): + print("Running section: apigateway") + print("Running check: apigateway.1") + conn.cursor().execute(apigateway.API_GW_EXECUTION_LOGGING_ENABLED, (execution_time, FRAMEWORK, 'apigateway.1', execution_time, FRAMEWORK, 'apigateway.1')) + +def execute_awsconfig(conn: SnowflakeConnection, execution_time: datetime.datetime): + print("Running section: AWS Config") + print("Running check: aws_config.1") + conn.cursor().execute(awsconfig.ENABLED_ALL_REGIONS, (execution_time, FRAMEWORK, 'awsconfig.1')) + +def execute_cloudfront(conn: SnowflakeConnection, execution_time: datetime.datetime): + print("Running section: Cloudfront") + print("Running check: cloudfront.1") + conn.cursor().execute(cloudfront.DEFAULT_ROOT_OBJECT_CONFIGURED, (execution_time, FRAMEWORK, 'cloudfront.1')) + print("Running check: cloudfront.2") + conn.cursor().execute(cloudfront.ORIGIN_ACCESS_IDENTITY_ENABLED, (execution_time, FRAMEWORK, 'cloudfront.2')) + print("Running check: cloudfront.3") + conn.cursor().execute(cloudfront.VIEWER_POLICY_HTTPS, (execution_time, FRAMEWORK, 'cloudfront.3')) + print("Running check: cloudfront.4") + conn.cursor().execute(cloudfront.ORIGIN_FAILOVER_ENABLED, (execution_time, FRAMEWORK, 'cloudfront.4')) + print("Running check: cloudfront.5") + conn.cursor().execute(cloudfront.ACCESS_LOGS_ENABLED, (execution_time, FRAMEWORK, 'cloudfront.5')) + print("Running check: cloudfront.6") + conn.cursor().execute(cloudfront.ASSOCIATED_WITH_WAF, (execution_time, FRAMEWORK, 'cloudfront.6')) + +def execute_cloudtrail(conn: SnowflakeConnection, execution_time: datetime.datetime): + print("Running section: Cloudtrail") + print("Running check: cloudtrail.1") + conn.cursor().execute(cloudtrail.ENABLED_ALL_REGIONS, (execution_time, FRAMEWORK, 'cloudtrail.1')) + print("Running check: cloudtrail.2") + conn.cursor().execute(cloudtrail.LOGS_ENCRYPTED, (execution_time, FRAMEWORK, 'cloudtrail.2')) + print("Running check: cloudtrail.3") + conn.cursor().execute(cloudtrail.LOGS_FILE_VALIDATION_ENABLED, (execution_time, FRAMEWORK, 'cloudtrail.3')) + print("Running check: cloudtrail.4") + conn.cursor().execute(cloudtrail.LOGS_FILE_VALIDATION_ENABLED, (execution_time, FRAMEWORK, 'cloudtrail.4')) + print("Running check: cloudtrail.5") + conn.cursor().execute(cloudtrail.INTEGRATED_WITH_CLOUDWATCH_LOGS, (execution_time, FRAMEWORK, 'cloudtrail.5')) + +def execute_codebuild(conn: SnowflakeConnection, execution_time: datetime.datetime): + print("Running section: Codebuild") + print("Running check: codebuild.1") + conn.cursor().execute(codebuild.CHECK_OAUTH_USAGE_FOR_SOURCES, (execution_time, FRAMEWORK, 'codebuild.1')) + print("Running check: codebuild.2") + conn.cursor().execute(codebuild.CHECK_ENVIRONMENT_VARIABLES, (execution_time, FRAMEWORK, 'codebuild.2')) + +def execute_dms(conn: SnowflakeConnection, execution_time: datetime.datetime): + print("Running section: DMS") + print("Running check: dms.1") + conn.cursor().execute(dms.REPLICATION_NOT_PUBLIC, (execution_time, FRAMEWORK, 'dms.1')) + +def execute_dynamodb(conn: SnowflakeConnection, execution_time: datetime.datetime): + print("Running section: DynamoDB") + print("Running check: dynamodb.1") + conn.cursor().execute(dynamodb.AUTOSCALE_OR_ONDEMAND, (execution_time, FRAMEWORK, 'dynamodb.1')) + print("Running check: dynamodb.2") + conn.cursor().execute(dynamodb.POINT_IN_TIME_RECOVERY, (execution_time, FRAMEWORK, 'dynamodb.2')) + print("Running check: dynamodb.3") + conn.cursor().execute(dynamodb.DAX_ENCRYPTED_AT_REST, (execution_time, FRAMEWORK, 'dynamodb.3')) \ No newline at end of file