From f7afd7d1d66bd80867a81468f715c001c59173b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Mart=C3=ADn?= Date: Mon, 19 Feb 2024 12:33:59 +0100 Subject: [PATCH] feat(azure): Add new checks related to PostgreSQL service (#3409) --- poetry.lock | 27 ++- .../azure/services/postgresql/__init__.py | 0 .../services/postgresql/postgresql_client.py | 4 + .../__init__.py | 0 ...low_access_services_disabled.metadata.json | 30 +++ ...e_server_allow_access_services_disabled.py | 29 +++ .../__init__.py | 0 ...ver_connection_throttling_on.metadata.json | 30 +++ ...lexible_server_connection_throttling_on.py | 26 +++ .../__init__.py | 0 ...e_server_enforce_ssl_enabled.metadata.json | 30 +++ ...sql_flexible_server_enforce_ssl_enabled.py | 26 +++ .../__init__.py | 0 ...le_server_log_checkpoints_on.metadata.json | 30 +++ ...esql_flexible_server_log_checkpoints_on.py | 26 +++ .../__init__.py | 0 ...le_server_log_connections_on.metadata.json | 30 +++ ...esql_flexible_server_log_connections_on.py | 26 +++ .../__init__.py | 0 ...server_log_disconnections_on.metadata.json | 30 +++ ...l_flexible_server_log_disconnections_on.py | 26 +++ .../__init__.py | 0 ...log_retention_days_greater_3.metadata.json | 30 +++ ...ble_server_log_retention_days_greater_3.py | 30 +++ .../services/postgresql/postgresql_service.py | 153 ++++++++++++++ tests/lib/check/check_test.py | 82 ++------ ...ver_allow_access_services_disabled_test.py | 121 +++++++++++ ...le_server_connection_throttling_on_test.py | 106 ++++++++++ ...lexible_server_enforce_ssl_enabled_test.py | 106 ++++++++++ ...flexible_server_log_checkpoints_on_test.py | 106 ++++++++++ ...flexible_server_log_connections_on_test.py | 106 ++++++++++ ...xible_server_log_disconnections_on_test.py | 106 ++++++++++ ...erver_log_retention_days_greater_3_test.py | 191 ++++++++++++++++++ .../postgresql/postgresql_service_test.py | 122 +++++++++++ 34 files changed, 1551 insertions(+), 78 deletions(-) create mode 100644 prowler/providers/azure/services/postgresql/__init__.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_client.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/__init__.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled.metadata.json create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/__init__.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on.metadata.json create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/__init__.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled.metadata.json create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/__init__.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on.metadata.json create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/__init__.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on.metadata.json create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_disconnections_on/__init__.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_disconnections_on/postgresql_flexible_server_log_disconnections_on.metadata.json create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_disconnections_on/postgresql_flexible_server_log_disconnections_on.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/__init__.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/postgresql_flexible_server_log_retention_days_greater_3.metadata.json create mode 100644 prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/postgresql_flexible_server_log_retention_days_greater_3.py create mode 100644 prowler/providers/azure/services/postgresql/postgresql_service.py create mode 100644 tests/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled_test.py create mode 100644 tests/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on_test.py create mode 100644 tests/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled_test.py create mode 100644 tests/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on_test.py create mode 100644 tests/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on_test.py create mode 100644 tests/providers/azure/services/postgresql/postgresql_flexible_server_log_disconnections_on/postgresql_flexible_server_log_disconnections_on_test.py create mode 100644 tests/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/postgresql_flexible_server_log_retention_days_greater_3_test.py create mode 100644 tests/providers/azure/services/postgresql/postgresql_service_test.py diff --git a/poetry.lock b/poetry.lock index e6bb064e..b0340c23 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "about-time" @@ -2935,8 +2935,8 @@ astroid = ">=3.0.1,<=3.1.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ {version = ">=0.2", markers = "python_version < \"3.11\""}, - {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, ] isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" @@ -3145,6 +3145,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -3152,8 +3153,16 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -3170,6 +3179,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -3177,6 +3187,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -3566,24 +3577,24 @@ python-versions = ">=3.6" files = [ {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:d92f81886165cb14d7b067ef37e142256f1c6a90a65cd156b063a43da1708cfd"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:b5edda50e5e9e15e54a6a8a0070302b00c518a9d32accc2346ad6c984aacd279"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:7048c338b6c86627afb27faecf418768acb6331fc24cfa56c93e8c9780f815fa"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"}, @@ -3591,7 +3602,7 @@ files = [ {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3fcc54cb0c8b811ff66082de1680b4b14cf8a81dce0d4fbf665c2265a81e07a1"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"}, @@ -3599,7 +3610,7 @@ files = [ {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:665f58bfd29b167039f714c6998178d27ccd83984084c286110ef26b230f259f"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"}, @@ -3607,7 +3618,7 @@ files = [ {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:9eb5dee2772b0f704ca2e45b1713e4e5198c18f515b52743576d196348f374d3"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"}, diff --git a/prowler/providers/azure/services/postgresql/__init__.py b/prowler/providers/azure/services/postgresql/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/prowler/providers/azure/services/postgresql/postgresql_client.py b/prowler/providers/azure/services/postgresql/postgresql_client.py new file mode 100644 index 00000000..2c945821 --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_client.py @@ -0,0 +1,4 @@ +from prowler.providers.azure.lib.audit_info.audit_info import azure_audit_info +from prowler.providers.azure.services.postgresql.postgresql_service import PostgreSQL + +postgresql_client = PostgreSQL(azure_audit_info) diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/__init__.py b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled.metadata.json b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled.metadata.json new file mode 100644 index 00000000..5e085028 --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled.metadata.json @@ -0,0 +1,30 @@ +{ + "Provider": "azure", + "CheckID": "postgresql_flexible_server_allow_access_services_disabled", + "CheckTitle": "Ensure 'Allow access to Azure services' for PostgreSQL Database Server is disabled", + "CheckType": [], + "ServiceName": "postgresql", + "SubServiceName": "", + "ResourceIdTemplate": "", + "Severity": "medium", + "ResourceType": "PostgreSQL", + "Description": "Disable access from Azure services to PostgreSQL Database Server.", + "Risk": "If access from Azure services is enabled, the server's firewall will accept connections from all Azure resources, including resources not in your subscription. This is usually not a desired configuration. Instead, set up firewall rules to allow access from specific network ranges or VNET rules to allow access from specific virtual networks.", + "RelatedUrl": "https://docs.microsoft.com/en-us/azure/postgresql/concepts-firewall-rules", + "Remediation": { + "Code": { + "CLI": "az postgres server firewall-rule delete --name AllowAllWindowsAzureIps --resource-group --server-name ", + "NativeIaC": "", + "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/PostgreSQL/disable-all-services-access.html#", + "Terraform": "https://docs.bridgecrew.io/docs/ensure-allow-access-to-azure-services-for-postgresql-database-server-is-disabled#terraform" + }, + "Recommendation": { + "Text": "From Azure Portal 1. Login to Azure Portal using https://portal.azure.com. 2. Go to Azure Database for PostgreSQL servers. 3. For each database, click on Connection security. 4. Under Firewall rules, set Allow access to Azure services to No. 5. Click Save. From Azure CLI Use the below command to delete the AllowAllWindowsAzureIps rule for PostgreSQL Database. az postgres server firewall-rule delete --name AllowAllWindowsAzureIps -- resource-group --server-name ", + "Url": "https://learn.microsoft.com/en-us/azure/postgresql/single-server/quickstart-create-server-database-azure-cli#configure-a-server-based-firewall-rule" + } + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "" +} diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled.py b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled.py new file mode 100644 index 00000000..8c0aa09a --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled.py @@ -0,0 +1,29 @@ +from prowler.lib.check.models import Check, Check_Report_Azure +from prowler.providers.azure.services.postgresql.postgresql_client import ( + postgresql_client, +) + + +class postgresql_flexible_server_allow_access_services_disabled(Check): + def execute(self) -> Check_Report_Azure: + findings = [] + for ( + subscription, + flexible_servers, + ) in postgresql_client.flexible_servers.items(): + for server in flexible_servers: + report = Check_Report_Azure(self.metadata()) + report.subscription = subscription + report.resource_name = server.name + report.resource_id = server.id + report.status = "FAIL" + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has allow public access from any Azure service enabled" + if not any( + rule.start_ip == "0.0.0.0" and rule.end_ip == "0.0.0.0" + for rule in server.firewall + ): + report.status = "PASS" + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has allow public access from any Azure service disabled" + findings.append(report) + + return findings diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/__init__.py b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on.metadata.json b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on.metadata.json new file mode 100644 index 00000000..445dbf59 --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on.metadata.json @@ -0,0 +1,30 @@ +{ + "Provider": "azure", + "CheckID": "postgresql_flexible_server_connection_throttling_on", + "CheckTitle": "Ensure server parameter 'connection_throttling' is set to 'ON' for PostgreSQL Database Server", + "CheckType": [], + "ServiceName": "postgresql", + "SubServiceName": "", + "ResourceIdTemplate": "", + "Severity": "medium", + "ResourceType": "PostgreSQL", + "Description": "Enable connection_throttling on PostgreSQL Servers.", + "Risk": "Enabling connection_throttling helps the PostgreSQL Database to Set the verbosity of logged messages. This in turn generates query and error logs with respect to concurrent connections that could lead to a successful Denial of Service (DoS) attack by exhausting connection resources. A system can also fail or be degraded by an overload of legitimate users. Query and error logs can be used to identify, troubleshoot, and repair configuration errors and sub-optimal performance.", + "RelatedUrl": " https://docs.microsoft.com/en-us/rest/api/postgresql/configurations/listbyserver", + "Remediation": { + "Code": { + "CLI": "az postgres server configuration set --resource-group --server-name --name connection_throttling --value on", + "NativeIaC": "", + "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/PostgreSQL/connection-throttling.html", + "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_13#terraform" + }, + "Recommendation": { + "Text": "From Azure Portal 1. Login to Azure Portal using https://portal.azure.com. 2. Go to Azure Database for PostgreSQL servers. 3. For each database, click on Server parameters. 4. Search for connection_throttling. 5. Click ON and save. From Azure CLI Use the below command to update connection_throttling configuration. az postgres server configuration set --resource-group -- server-name --name connection_throttling --value on From PowerShell Use the below command to update connection_throttling configuration. Update-AzPostgreSqlConfiguration -ResourceGroupName - ServerName -Name connection_throttling -Value on", + "Url": "https://learn.microsoft.com/en-us/azure/postgresql/single-server/how-to-configure-server-parameters-using-portal" + } + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "" +} diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on.py b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on.py new file mode 100644 index 00000000..c1855d6c --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on.py @@ -0,0 +1,26 @@ +from prowler.lib.check.models import Check, Check_Report_Azure +from prowler.providers.azure.services.postgresql.postgresql_client import ( + postgresql_client, +) + + +class postgresql_flexible_server_connection_throttling_on(Check): + def execute(self) -> Check_Report_Azure: + findings = [] + for ( + subscription, + flexible_servers, + ) in postgresql_client.flexible_servers.items(): + for server in flexible_servers: + report = Check_Report_Azure(self.metadata()) + report.subscription = subscription + report.resource_name = server.name + report.resource_id = server.id + report.status = "FAIL" + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has connection_throttling disabled" + if server.connection_throttling == "ON": + report.status = "PASS" + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has connection_throttling enabled" + findings.append(report) + + return findings diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/__init__.py b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled.metadata.json b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled.metadata.json new file mode 100644 index 00000000..14ceef52 --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled.metadata.json @@ -0,0 +1,30 @@ +{ + "Provider": "azure", + "CheckID": "postgresql_flexible_server_enforce_ssl_enabled", + "CheckTitle": "Ensure 'Enforce SSL connection' is set to 'ENABLED' for PostgreSQL Database Server", + "CheckType": [], + "ServiceName": "postgresql", + "SubServiceName": "", + "ResourceIdTemplate": "", + "Severity": "medium", + "ResourceType": "PostgreSQL", + "Description": "Enable SSL connection on PostgreSQL Servers.", + "Risk": "SSL connectivity helps to provide a new layer of security by connecting database server to client applications using Secure Sockets Layer (SSL). Enforcing SSL connections between database server and client applications helps protect against 'man in the middle' attacks by encrypting the data stream between the server and application.", + "RelatedUrl": "https://learn.microsoft.com/en-us/azure/postgresql/single-server/concepts-ssl-connection-security", + "Remediation": { + "Code": { + "CLI": "az postgres server update --resource-group --name --ssl-enforcement Enabled", + "NativeIaC": "", + "Other": "https://docs.bridgecrew.io/docs/bc_azr_networking_10", + "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_10#terraform" + }, + "Recommendation": { + "Text": "From Azure Portal 1. Login to Azure Portal using https://portal.azure.com 2. Go to Azure Database for PostgreSQL server 3. For each database, click on Connection security 4. In SSL settings, click on ENABLED to enforce SSL connections 5. Click Save From Azure CLI Use the below command to enforce ssl connection for PostgreSQL Database. az postgres server update --resource-group --name --ssl-enforcement Enabled From PowerShell Update-AzPostgreSqlServer -ResourceGroupName -ServerName -SslEnforcement Enabled", + "Url": "https://learn.microsoft.com/en-us/azure/postgresql/single-server/concepts-ssl-connection-security" + } + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "." +} diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled.py b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled.py new file mode 100644 index 00000000..9feaa6b9 --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled.py @@ -0,0 +1,26 @@ +from prowler.lib.check.models import Check, Check_Report_Azure +from prowler.providers.azure.services.postgresql.postgresql_client import ( + postgresql_client, +) + + +class postgresql_flexible_server_enforce_ssl_enabled(Check): + def execute(self) -> Check_Report_Azure: + findings = [] + for ( + subscription, + flexible_servers, + ) in postgresql_client.flexible_servers.items(): + for server in flexible_servers: + report = Check_Report_Azure(self.metadata()) + report.subscription = subscription + report.resource_name = server.name + report.resource_id = server.id + report.status = "FAIL" + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has enforce ssl disabled" + if server.require_secure_transport == "ON": + report.status = "PASS" + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has enforce ssl enabled" + findings.append(report) + + return findings diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/__init__.py b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on.metadata.json b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on.metadata.json new file mode 100644 index 00000000..e506a7f1 --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on.metadata.json @@ -0,0 +1,30 @@ +{ + "Provider": "azure", + "CheckID": "postgresql_flexible_server_log_checkpoints_on", + "CheckTitle": "Ensure Server Parameter 'log_checkpoints' is set to 'ON' for PostgreSQL Database Server", + "CheckType": [], + "ServiceName": "postgresql", + "SubServiceName": "", + "ResourceIdTemplate": "", + "Severity": "medium", + "ResourceType": "PostgreSQL", + "Description": "Enable log_checkpoints on PostgreSQL Servers.", + "Risk": "Enabling log_checkpoints helps the PostgreSQL Database to Log each checkpoint in turn generates query and error logs. However, access to transaction logs is not supported. Query and error logs can be used to identify, troubleshoot, and repair configuration errors and sub-optimal performance.", + "RelatedUrl": " https://docs.microsoft.com/en-us/rest/api/postgresql/singleserver/configurations/list-by-server", + "Remediation": { + "Code": { + "CLI": "az postgres server configuration set --resource-group --server-name --name log_checkpoints --value on", + "NativeIaC": "", + "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/PostgreSQL/log-checkpoints.html#", + "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_11#terraform" + }, + "Recommendation": { + "Text": "From Azure Portal 1. From Azure Home select the Portal Menu. 2. Go to Azure Database for PostgreSQL servers. 3. For each database, click on Server parameters. 4. Search for log_checkpoints. 5. Click ON and save. From Azure CLI Use the below command to update log_checkpoints configuration. az postgres server configuration set --resource-group -- server-name --name log_checkpoints --value on From PowerShell Update-AzPostgreSqlConfiguration -ResourceGroupName - ServerName -Name log_checkpoints -Value on", + "Url": "https://docs.microsoft.com/en-us/azure/postgresql/howto-configure-server-parameters-using-portal" + } + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "" +} diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on.py b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on.py new file mode 100644 index 00000000..3bfcda42 --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on.py @@ -0,0 +1,26 @@ +from prowler.lib.check.models import Check, Check_Report_Azure +from prowler.providers.azure.services.postgresql.postgresql_client import ( + postgresql_client, +) + + +class postgresql_flexible_server_log_checkpoints_on(Check): + def execute(self) -> Check_Report_Azure: + findings = [] + for ( + subscription, + flexible_servers, + ) in postgresql_client.flexible_servers.items(): + for server in flexible_servers: + report = Check_Report_Azure(self.metadata()) + report.subscription = subscription + report.resource_name = server.name + report.resource_id = server.id + report.status = "FAIL" + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has log_checkpoints disabled" + if server.log_checkpoints == "ON": + report.status = "PASS" + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has log_checkpoints enabled" + findings.append(report) + + return findings diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/__init__.py b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on.metadata.json b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on.metadata.json new file mode 100644 index 00000000..1382dd28 --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on.metadata.json @@ -0,0 +1,30 @@ +{ + "Provider": "azure", + "CheckID": "postgresql_flexible_server_log_connections_on", + "CheckTitle": "Ensure server parameter 'log_connections' is set to 'ON' for PostgreSQL Database Server", + "CheckType": [], + "ServiceName": "postgresql", + "SubServiceName": "", + "ResourceIdTemplate": "", + "Severity": "medium", + "ResourceType": "PostgreSQL", + "Description": "Enable log_connections on PostgreSQL Servers.", + "Risk": "Enabling log_connections helps PostgreSQL Database to log attempted connection to the server, as well as successful completion of client authentication. Log data can be used to identify, troubleshoot, and repair configuration errors and suboptimal performance.", + "RelatedUrl": "https://docs.microsoft.com/en-us/rest/api/postgresql/configurations/listbyserver", + "Remediation": { + "Code": { + "CLI": "az postgres server configuration set --resource-group --server-name --name log_connections --value on", + "NativeIaC": "", + "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/PostgreSQL/log-connections.html", + "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_12#terraform" + }, + "Recommendation": { + "Text": "From Azure Portal 1. Login to Azure Portal using https://portal.azure.com. 2. Go to Azure Database for PostgreSQL servers. 3. For each database, click on Server parameters. 4. Search for log_connections. 5. Click ON and save. From Azure CLI Use the below command to update log_connections configuration. az postgres server configuration set --resource-group -- server-name --name log_connections --value on From PowerShell Use the below command to update log_connections configuration. Update-AzPostgreSqlConfiguration -ResourceGroupName - ServerName -Name log_connections -Value on", + "Url": "https://learn.microsoft.com/en-us/azure/postgresql/single-server/how-to-configure-server-parameters-using-portal" + } + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "" +} diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on.py b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on.py new file mode 100644 index 00000000..0ae39b71 --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on.py @@ -0,0 +1,26 @@ +from prowler.lib.check.models import Check, Check_Report_Azure +from prowler.providers.azure.services.postgresql.postgresql_client import ( + postgresql_client, +) + + +class postgresql_flexible_server_log_connections_on(Check): + def execute(self) -> Check_Report_Azure: + findings = [] + for ( + subscription, + flexible_servers, + ) in postgresql_client.flexible_servers.items(): + for server in flexible_servers: + report = Check_Report_Azure(self.metadata()) + report.subscription = subscription + report.resource_name = server.name + report.resource_id = server.id + report.status = "FAIL" + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has log_connections disabled" + if server.log_connections == "ON": + report.status = "PASS" + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has log_connections enabled" + findings.append(report) + + return findings diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_disconnections_on/__init__.py b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_disconnections_on/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_disconnections_on/postgresql_flexible_server_log_disconnections_on.metadata.json b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_disconnections_on/postgresql_flexible_server_log_disconnections_on.metadata.json new file mode 100644 index 00000000..1f75ad5d --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_disconnections_on/postgresql_flexible_server_log_disconnections_on.metadata.json @@ -0,0 +1,30 @@ +{ + "Provider": "azure", + "CheckID": "postgresql_flexible_server_log_disconnections_on", + "CheckTitle": "Ensure server parameter 'log_disconnections' is set to 'ON' for PostgreSQL Database Server", + "CheckType": [], + "ServiceName": "postgresql", + "SubServiceName": "", + "ResourceIdTemplate": "", + "Severity": "medium", + "ResourceType": "PostgreSQL", + "Description": "Enable log_disconnections on PostgreSQL Servers.", + "Risk": "Enabling log_disconnections helps PostgreSQL Database to Logs end of a session, including duration, which in turn generates query and error logs. Query and error logs can be used to identify, troubleshoot, and repair configuration errors and sub-optimal performance.", + "RelatedUrl": "https://docs.microsoft.com/en-us/rest/api/postgresql/singleserver/configurations/list-by-server", + "Remediation": { + "Code": { + "CLI": "az postgres server configuration set --resource-group --server-name --name log_disconnections --value on", + "NativeIaC": "", + "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/PostgreSQL/log-disconnections.html", + "Terraform": "" + }, + "Recommendation": { + "Text": "From Azure Portal 1. From Azure Home select the Portal Menu 2. Go to Azure Database for PostgreSQL servers 3. For each database, click on Server parameters 4. Search for log_disconnections. 5. Click ON and save. From Azure CLI Use the below command to update log_disconnections configuration. az postgres server configuration set --resource-group -- server-name --name log_disconnections --value on From PowerShell Use the below command to update log_disconnections configuration. Update-AzPostgreSqlConfiguration -ResourceGroupName Check_Report_Azure: + findings = [] + for ( + subscription, + flexible_servers, + ) in postgresql_client.flexible_servers.items(): + for server in flexible_servers: + report = Check_Report_Azure(self.metadata()) + report.subscription = subscription + report.resource_name = server.name + report.resource_id = server.id + report.status = "FAIL" + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has log_disconnections disabled" + if server.log_disconnections == "ON": + report.status = "PASS" + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has log_disconnections enabled" + findings.append(report) + + return findings diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/__init__.py b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/postgresql_flexible_server_log_retention_days_greater_3.metadata.json b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/postgresql_flexible_server_log_retention_days_greater_3.metadata.json new file mode 100644 index 00000000..c346f52b --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/postgresql_flexible_server_log_retention_days_greater_3.metadata.json @@ -0,0 +1,30 @@ +{ + "Provider": "azure", + "CheckID": "postgresql_flexible_server_log_retention_days_greater_3", + "CheckTitle": "Ensure Server Parameter 'log_retention_days' is greater than 3 days for PostgreSQL Database Server", + "CheckType": [], + "ServiceName": "postgresql", + "SubServiceName": "", + "ResourceIdTemplate": "", + "Severity": "medium", + "ResourceType": "PostgreSQL", + "Description": "Ensure log_retention_days on PostgreSQL Servers is set to an appropriate value.", + "Risk": "Configuring log_retention_days determines the duration in days that Azure Database for PostgreSQL retains log files. Query and error logs can be used to identify, troubleshoot, and repair configuration errors and sub-optimal performance.", + "RelatedUrl": "https://docs.microsoft.com/en-us/azure/postgresql/howto-configure-server-parameters-using-portal", + "Remediation": { + "Code": { + "CLI": "az postgres server configuration set --resource-group --server-name --name log_retention_days --value <4-7>", + "NativeIaC": "", + "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/PostgreSQL/log-retention-days.html", + "Terraform": "" + }, + "Recommendation": { + "Text": "From Azure Portal 1. From Azure Home select the Portal Menu. 2. Go to Azure Database for PostgreSQL servers. 3. For each database, click on Server parameters. 4. Search for log_retention_days. 5. Input a value between 4 and 7 (inclusive) and click Save. From Azure CLI Use the below command to update log_retention_days configuration. az postgres server configuration set --resource-group -- server-name --name log_retention_days --value <4-7> From Powershell Use the below command to update log_retention_days configuration. Update-AzPostgreSqlConfiguration -ResourceGroupName - ServerName -Name log_retention_days -Value <4-7>", + "Url": "https://learn.microsoft.com/en-us/rest/api/postgresql/singleserver/configurations/list-by-server?view=rest-postgresql-singleserver-2017-12-01&tabs=HTTP" + } + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "Configuring this setting will result in logs being retained for the specified number of days. If this is configured on a high traffic server, the log may grow quickly to occupy a large amount of disk space. In this case you may want to set this to a lower number." +} diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/postgresql_flexible_server_log_retention_days_greater_3.py b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/postgresql_flexible_server_log_retention_days_greater_3.py new file mode 100644 index 00000000..6880c455 --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/postgresql_flexible_server_log_retention_days_greater_3.py @@ -0,0 +1,30 @@ +from prowler.lib.check.models import Check, Check_Report_Azure +from prowler.providers.azure.services.postgresql.postgresql_client import ( + postgresql_client, +) + + +class postgresql_flexible_server_log_retention_days_greater_3(Check): + def execute(self) -> Check_Report_Azure: + findings = [] + for ( + subscription, + flexible_servers, + ) in postgresql_client.flexible_servers.items(): + for server in flexible_servers: + report = Check_Report_Azure(self.metadata()) + report.subscription = subscription + report.resource_name = server.name + report.resource_id = server.id + report.status = "FAIL" + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has log_retention disabled" + if server.log_retention_days: + report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription} has log_retention set to {server.log_retention_days}" + if ( + int(server.log_retention_days) > 3 + and int(server.log_retention_days) < 8 + ): + report.status = "PASS" + findings.append(report) + + return findings diff --git a/prowler/providers/azure/services/postgresql/postgresql_service.py b/prowler/providers/azure/services/postgresql/postgresql_service.py new file mode 100644 index 00000000..7a93e0e3 --- /dev/null +++ b/prowler/providers/azure/services/postgresql/postgresql_service.py @@ -0,0 +1,153 @@ +from dataclasses import dataclass + +from azure.mgmt.rdbms.postgresql_flexibleservers import PostgreSQLManagementClient + +from prowler.lib.logger import logger +from prowler.providers.azure.lib.service.service import AzureService + + +class PostgreSQL(AzureService): + def __init__(self, audit_info): + super().__init__(PostgreSQLManagementClient, audit_info) + self.flexible_servers = self.__get_flexible_servers__() + + def __get_flexible_servers__(self): + logger.info("PostgreSQL - Getting PostgreSQL servers...") + flexible_servers = {} + for subscription, client in self.clients.items(): + try: + flexible_servers.update({subscription: []}) + flexible_servers_list = client.servers.list() + for postgresql_server in flexible_servers_list: + resource_group = self.__get_resource_group__(postgresql_server.id) + require_secure_transport = self.__get_require_secure_transport__( + subscription, resource_group, postgresql_server.name + ) + log_checkpoints = self.__get_log_checkpoints__( + subscription, resource_group, postgresql_server.name + ) + log_disconnections = self.__get_log_disconnections__( + subscription, resource_group, postgresql_server.name + ) + log_connections = self.__get_log_connections__( + subscription, resource_group, postgresql_server.name + ) + connection_throttling = self.__get_connection_throttling__( + subscription, resource_group, postgresql_server.name + ) + log_retention_days = self.__get_log_retention_days__( + subscription, resource_group, postgresql_server.name + ) + firewall = self.__get_firewall__( + subscription, resource_group, postgresql_server.name + ) + flexible_servers[subscription].append( + Server( + id=postgresql_server.id, + name=postgresql_server.name, + resource_group=resource_group, + require_secure_transport=require_secure_transport, + log_checkpoints=log_checkpoints, + log_connections=log_connections, + log_disconnections=log_disconnections, + connection_throttling=connection_throttling, + log_retention_days=log_retention_days, + firewall=firewall, + ) + ) + except Exception as error: + logger.error( + f"Subscription name: {subscription} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return flexible_servers + + def __get_resource_group__(self, id): + resource_group = id.split("/")[4] + return resource_group + + def __get_require_secure_transport__( + self, subscription, resouce_group_name, server_name + ): + client = self.clients[subscription] + require_secure_transport = client.configurations.get( + resouce_group_name, server_name, "require_secure_transport" + ) + return require_secure_transport.value.upper() + + def __get_log_checkpoints__(self, subscription, resouce_group_name, server_name): + client = self.clients[subscription] + log_checkpoints = client.configurations.get( + resouce_group_name, server_name, "log_checkpoints" + ) + return log_checkpoints.value.upper() + + def __get_log_connections__(self, subscription, resouce_group_name, server_name): + client = self.clients[subscription] + log_connections = client.configurations.get( + resouce_group_name, server_name, "log_connections" + ) + return log_connections.value.upper() + + def __get_log_disconnections__(self, subscription, resouce_group_name, server_name): + client = self.clients[subscription] + log_disconnections = client.configurations.get( + resouce_group_name, server_name, "log_disconnections" + ) + return log_disconnections.value.upper() + + def __get_connection_throttling__( + self, subscription, resouce_group_name, server_name + ): + client = self.clients[subscription] + connection_throttling = client.configurations.get( + resouce_group_name, server_name, "connection_throttle.enable" + ) + return connection_throttling.value.upper() + + def __get_log_retention_days__(self, subscription, resouce_group_name, server_name): + client = self.clients[subscription] + try: + log_retention_days = client.configurations.get( + resouce_group_name, server_name, "log_retention_days" + ) + log_retention_days = log_retention_days.value + except Exception: + log_retention_days = None + return log_retention_days + + def __get_firewall__(self, subscription, resource_group, server_name): + client = self.clients[subscription] + firewall = client.firewall_rules.list_by_server(resource_group, server_name) + firewall_list = [] + for rule in firewall: + firewall_list.append( + Firewall( + id=rule.id, + name=rule.name, + start_ip=rule.start_ip_address, + end_ip=rule.end_ip_address, + ) + ) + return firewall_list + + +@dataclass +class Firewall: + id: str + name: str + start_ip: str + end_ip: str + + +@dataclass +class Server: + id: str + name: str + resource_group: str + require_secure_transport: str + log_checkpoints: str + log_connections: str + log_disconnections: str + connection_throttling: str + log_retention_days: str + firewall: list[Firewall] diff --git a/tests/lib/check/check_test.py b/tests/lib/check/check_test.py index a1eb2c1d..8ccc6d13 100644 --- a/tests/lib/check/check_test.py +++ b/tests/lib/check/check_test.py @@ -172,39 +172,17 @@ expected_packages = [ ispkg=False, ), ModuleInfo( - module_finder=FileFinder("/root_dir/prowler/providers/azure/services/cosmosdb"), - name="prowler.providers.azure.services.cosmosdb.cosmosdb_account_firewall_use_selected_networks", + module_finder=FileFinder( + "/root_dir/prowler/providers/azure/services/postgresql" + ), + name="prowler.providers.azure.services.postgresql.postgresql_flexible_server_enforce_ssl_enabled", ispkg=True, ), ModuleInfo( module_finder=FileFinder( - "/root_dir/prowler/providers/azure/services/cosmosdb/cosmosdb_account_firewall_use_selected_networks" + "/root_dir/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled" ), - name="prowler.providers.azure.services.cosmosdb.cosmosdb_account_firewall_use_selected_networks.cosmosdb_account_firewall_use_selected_networks", - ispkg=False, - ), - ModuleInfo( - module_finder=FileFinder("/root_dir/prowler/providers/azure/services/cosmosdb"), - name="prowler.providers.azure.services.cosmosdb.cosmosdb_account_use_private_endpoints", - ispkg=True, - ), - ModuleInfo( - module_finder=FileFinder( - "/root_dir/prowler/providers/azure/services/cosmosdb/cosmosdb_account_use_private_endpoints" - ), - name="prowler.providers.azure.services.cosmosdb.cosmosdb_account_use_private_endpoints.cosmosdb_account_use_private_endpoints", - ispkg=False, - ), - ModuleInfo( - module_finder=FileFinder("/root_dir/prowler/providers/azure/services/cosmosdb"), - name="prowler.providers.azure.services.cosmosdb.cosmosdb_account_use_aad_and_rbac", - ispkg=True, - ), - ModuleInfo( - module_finder=FileFinder( - "/root_dir/prowler/providers/azure/services/cosmosdb/cosmosdb_account_use_aad_and_rbac" - ), - name="prowler.providers.azure.services.cosmosdb.cosmosdb_account_use_aad_and_rbac.cosmosdb_account_use_aad_and_rbac", + name="prowler.providers.azure.services.postgresql.postgresql_flexible_server_enforce_ssl_enabled.postgresql_flexible_server_enforce_ssl_enabled", ispkg=False, ), ] @@ -358,44 +336,16 @@ def mock_list_modules(*_): ), ModuleInfo( module_finder=FileFinder( - "/root_dir/prowler/providers/azure/services/cosmosdb" + "/root_dir/prowler/providers/azure/services/postgresql" ), - name="prowler.providers.azure.services.cosmosdb.cosmosdb_account_firewall_use_selected_networks", + name="prowler.providers.azure.services.postgresql.postgresql_flexible_server_enforce_ssl_enabled", ispkg=True, ), ModuleInfo( module_finder=FileFinder( - "/root_dir/prowler/providers/azure/services/cosmosdb/cosmosdb_account_firewall_use_selected_networks" + "/root_dir/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled" ), - name="prowler.providers.azure.services.cosmosdb.cosmosdb_account_firewall_use_selected_networks.cosmosdb_account_firewall_use_selected_networks", - ispkg=False, - ), - ModuleInfo( - module_finder=FileFinder( - "/root_dir/prowler/providers/azure/services/cosmosdb" - ), - name="prowler.providers.azure.services.cosmosdb.cosmosdb_account_use_private_endpoints", - ispkg=True, - ), - ModuleInfo( - module_finder=FileFinder( - "/root_dir/prowler/providers/azure/services/cosmosdb/cosmosdb_account_use_private_endpoints" - ), - name="prowler.providers.azure.services.cosmosdb.cosmosdb_account_use_private_endpoints.cosmosdb_account_use_private_endpoints", - ispkg=False, - ), - ModuleInfo( - module_finder=FileFinder( - "/root_dir/prowler/providers/azure/services/cosmosdb" - ), - name="prowler.providers.azure.services.cosmosdb.cosmosdb_account_use_aad_and_rbac", - ispkg=True, - ), - ModuleInfo( - module_finder=FileFinder( - "/root_dir/prowler/providers/azure/services/cosmosdb/cosmosdb_account_use_aad_and_rbac" - ), - name="prowler.providers.azure.services.cosmosdb.cosmosdb_account_use_aad_and_rbac.cosmosdb_account_use_aad_and_rbac", + name="prowler.providers.azure.services.postgresql.postgresql_flexible_server_enforce_ssl_enabled.postgresql_flexible_server_enforce_ssl_enabled", ispkg=False, ), ] @@ -808,16 +758,8 @@ class Test_Check: "/root_dir/prowler/providers/azure/services/sqlserver/sqlserver_va_emails_notifications_admins_enabled", ), ( - "cosmosdb_account_firewall_use_selected_networks", - "/root_dir/prowler/providers/azure/services/cosmosdb/cosmosdb_account_firewall_use_selected_networks", - ), - ( - "cosmosdb_account_use_private_endpoints", - "/root_dir/prowler/providers/azure/services/cosmosdb/cosmosdb_account_use_private_endpoints", - ), - ( - "cosmosdb_account_use_aad_and_rbac", - "/root_dir/prowler/providers/azure/services/cosmosdb/cosmosdb_account_use_aad_and_rbac", + "postgresql_flexible_server_enforce_ssl_enabled", + "/root_dir/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled", ), ] returned_checks = recover_checks_from_provider(provider, service) diff --git a/tests/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled_test.py b/tests/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled_test.py new file mode 100644 index 00000000..28a0a997 --- /dev/null +++ b/tests/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled_test.py @@ -0,0 +1,121 @@ +from unittest import mock +from uuid import uuid4 + +from prowler.providers.azure.services.postgresql.postgresql_service import ( + Firewall, + Server, +) + +AZURE_SUBSCRIPTION = str(uuid4()) + + +class Test_postgresql_flexible_server_allow_access_services_disabled: + def test_no_postgresql_flexible_servers(self): + postgresql_client = mock.MagicMock + postgresql_client.flexible_servers = {} + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_allow_access_services_disabled.postgresql_flexible_server_allow_access_services_disabled.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_allow_access_services_disabled.postgresql_flexible_server_allow_access_services_disabled import ( + postgresql_flexible_server_allow_access_services_disabled, + ) + + check = postgresql_flexible_server_allow_access_services_disabled() + result = check.execute() + assert len(result) == 0 + + def test_flexible_servers_allow_public_access(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + firewall = Firewall( + id=str(uuid4()), + name="firewall_name", + start_ip="0.0.0.0", + end_ip="0.0.0.0", + ) + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="OFF", + log_checkpoints="OFF", + log_connections="OFF", + log_disconnections="OFF", + connection_throttling="OFF", + log_retention_days="3", + firewall=[firewall], + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_allow_access_services_disabled.postgresql_flexible_server_allow_access_services_disabled.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_allow_access_services_disabled.postgresql_flexible_server_allow_access_services_disabled import ( + postgresql_flexible_server_allow_access_services_disabled, + ) + + check = postgresql_flexible_server_allow_access_services_disabled() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has allow public access from any Azure service enabled" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id + + def test_flexible_servers_dont_allow_public_access(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + firewall = Firewall( + id=str(uuid4()), + name="firewall_name", + start_ip="1.1.1.1", + end_ip="1.1.1.1", + ) + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="OFF", + log_checkpoints="OFF", + log_connections="OFF", + log_disconnections="OFF", + connection_throttling="OFF", + log_retention_days="3", + firewall=[firewall], + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_allow_access_services_disabled.postgresql_flexible_server_allow_access_services_disabled.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_allow_access_services_disabled.postgresql_flexible_server_allow_access_services_disabled import ( + postgresql_flexible_server_allow_access_services_disabled, + ) + + check = postgresql_flexible_server_allow_access_services_disabled() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has allow public access from any Azure service disabled" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id diff --git a/tests/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on_test.py b/tests/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on_test.py new file mode 100644 index 00000000..de6a4a88 --- /dev/null +++ b/tests/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on_test.py @@ -0,0 +1,106 @@ +from unittest import mock +from uuid import uuid4 + +from prowler.providers.azure.services.postgresql.postgresql_service import Server + +AZURE_SUBSCRIPTION = str(uuid4()) + + +class Test_postgresql_flexible_server_connection_throttling_on: + def test_no_postgresql_flexible_servers(self): + postgresql_client = mock.MagicMock + postgresql_client.flexible_servers = {} + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_connection_throttling_on.postgresql_flexible_server_connection_throttling_on.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_connection_throttling_on.postgresql_flexible_server_connection_throttling_on import ( + postgresql_flexible_server_connection_throttling_on, + ) + + check = postgresql_flexible_server_connection_throttling_on() + result = check.execute() + assert len(result) == 0 + + def test_flexible_servers_connection_throttling_off(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="OFF", + log_checkpoints="OFF", + log_connections="OFF", + log_disconnections="OFF", + connection_throttling="OFF", + log_retention_days="3", + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_connection_throttling_on.postgresql_flexible_server_connection_throttling_on.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_connection_throttling_on.postgresql_flexible_server_connection_throttling_on import ( + postgresql_flexible_server_connection_throttling_on, + ) + + check = postgresql_flexible_server_connection_throttling_on() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has connection_throttling disabled" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id + + def test_flexible_servers_connection_throttling_on(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="OFF", + log_checkpoints="ON", + log_connections="ON", + log_disconnections="ON", + connection_throttling="ON", + log_retention_days="3", + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_connection_throttling_on.postgresql_flexible_server_connection_throttling_on.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_connection_throttling_on.postgresql_flexible_server_connection_throttling_on import ( + postgresql_flexible_server_connection_throttling_on, + ) + + check = postgresql_flexible_server_connection_throttling_on() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has connection_throttling enabled" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id diff --git a/tests/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled_test.py b/tests/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled_test.py new file mode 100644 index 00000000..11cf6f26 --- /dev/null +++ b/tests/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled_test.py @@ -0,0 +1,106 @@ +from unittest import mock +from uuid import uuid4 + +from prowler.providers.azure.services.postgresql.postgresql_service import Server + +AZURE_SUBSCRIPTION = str(uuid4()) + + +class Test_postgresql_flexible_server_enforce_ssl_enabled: + def test_no_postgresql_flexible_servers(self): + postgresql_client = mock.MagicMock + postgresql_client.flexible_servers = {} + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_enforce_ssl_enabled.postgresql_flexible_server_enforce_ssl_enabled.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_enforce_ssl_enabled.postgresql_flexible_server_enforce_ssl_enabled import ( + postgresql_flexible_server_enforce_ssl_enabled, + ) + + check = postgresql_flexible_server_enforce_ssl_enabled() + result = check.execute() + assert len(result) == 0 + + def test_flexible_servers_require_secure_transport_off(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="OFF", + log_checkpoints="ON", + log_connections="ON", + log_disconnections="ON", + connection_throttling="ON", + log_retention_days="3", + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_enforce_ssl_enabled.postgresql_flexible_server_enforce_ssl_enabled.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_enforce_ssl_enabled.postgresql_flexible_server_enforce_ssl_enabled import ( + postgresql_flexible_server_enforce_ssl_enabled, + ) + + check = postgresql_flexible_server_enforce_ssl_enabled() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has enforce ssl disabled" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id + + def test_flexible_servers_require_secure_transport_on(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="ON", + log_checkpoints="ON", + log_connections="ON", + log_disconnections="ON", + connection_throttling="ON", + log_retention_days="3", + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_enforce_ssl_enabled.postgresql_flexible_server_enforce_ssl_enabled.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_enforce_ssl_enabled.postgresql_flexible_server_enforce_ssl_enabled import ( + postgresql_flexible_server_enforce_ssl_enabled, + ) + + check = postgresql_flexible_server_enforce_ssl_enabled() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has enforce ssl enabled" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id diff --git a/tests/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on_test.py b/tests/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on_test.py new file mode 100644 index 00000000..9e04dea9 --- /dev/null +++ b/tests/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on_test.py @@ -0,0 +1,106 @@ +from unittest import mock +from uuid import uuid4 + +from prowler.providers.azure.services.postgresql.postgresql_service import Server + +AZURE_SUBSCRIPTION = str(uuid4()) + + +class Test_postgresql_flexible_server_log_checkpoints_on: + def test_no_postgresql_flexible_servers(self): + postgresql_client = mock.MagicMock + postgresql_client.flexible_servers = {} + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_checkpoints_on.postgresql_flexible_server_log_checkpoints_on.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_checkpoints_on.postgresql_flexible_server_log_checkpoints_on import ( + postgresql_flexible_server_log_checkpoints_on, + ) + + check = postgresql_flexible_server_log_checkpoints_on() + result = check.execute() + assert len(result) == 0 + + def test_flexible_servers_log_checkpoints_off(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="ON", + log_checkpoints="OFF", + log_connections="ON", + log_disconnections="ON", + connection_throttling="ON", + log_retention_days="3", + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_checkpoints_on.postgresql_flexible_server_log_checkpoints_on.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_checkpoints_on.postgresql_flexible_server_log_checkpoints_on import ( + postgresql_flexible_server_log_checkpoints_on, + ) + + check = postgresql_flexible_server_log_checkpoints_on() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has log_checkpoints disabled" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id + + def test_flexible_servers_log_checkpoints_on(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="ON", + log_checkpoints="ON", + log_connections="ON", + log_disconnections="ON", + connection_throttling="ON", + log_retention_days="3", + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_checkpoints_on.postgresql_flexible_server_log_checkpoints_on.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_checkpoints_on.postgresql_flexible_server_log_checkpoints_on import ( + postgresql_flexible_server_log_checkpoints_on, + ) + + check = postgresql_flexible_server_log_checkpoints_on() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has log_checkpoints enabled" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id diff --git a/tests/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on_test.py b/tests/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on_test.py new file mode 100644 index 00000000..56e1f169 --- /dev/null +++ b/tests/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on_test.py @@ -0,0 +1,106 @@ +from unittest import mock +from uuid import uuid4 + +from prowler.providers.azure.services.postgresql.postgresql_service import Server + +AZURE_SUBSCRIPTION = str(uuid4()) + + +class Test_postgresql_flexible_server_log_connections_on: + def test_no_postgresql_flexible_servers(self): + postgresql_client = mock.MagicMock + postgresql_client.flexible_servers = {} + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_connections_on.postgresql_flexible_server_log_connections_on.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_connections_on.postgresql_flexible_server_log_connections_on import ( + postgresql_flexible_server_log_connections_on, + ) + + check = postgresql_flexible_server_log_connections_on() + result = check.execute() + assert len(result) == 0 + + def test_flexible_servers_log_connections_off(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="OFF", + log_checkpoints="OFF", + log_connections="OFF", + log_disconnections="OFF", + connection_throttling="ON", + log_retention_days="3", + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_connections_on.postgresql_flexible_server_log_connections_on.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_connections_on.postgresql_flexible_server_log_connections_on import ( + postgresql_flexible_server_log_connections_on, + ) + + check = postgresql_flexible_server_log_connections_on() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has log_connections disabled" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id + + def test_flexible_servers_log_connections_on(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="OFF", + log_checkpoints="ON", + log_connections="ON", + log_disconnections="ON", + connection_throttling="ON", + log_retention_days="3", + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_connections_on.postgresql_flexible_server_log_connections_on.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_connections_on.postgresql_flexible_server_log_connections_on import ( + postgresql_flexible_server_log_connections_on, + ) + + check = postgresql_flexible_server_log_connections_on() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has log_connections enabled" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id diff --git a/tests/providers/azure/services/postgresql/postgresql_flexible_server_log_disconnections_on/postgresql_flexible_server_log_disconnections_on_test.py b/tests/providers/azure/services/postgresql/postgresql_flexible_server_log_disconnections_on/postgresql_flexible_server_log_disconnections_on_test.py new file mode 100644 index 00000000..bd360868 --- /dev/null +++ b/tests/providers/azure/services/postgresql/postgresql_flexible_server_log_disconnections_on/postgresql_flexible_server_log_disconnections_on_test.py @@ -0,0 +1,106 @@ +from unittest import mock +from uuid import uuid4 + +from prowler.providers.azure.services.postgresql.postgresql_service import Server + +AZURE_SUBSCRIPTION = str(uuid4()) + + +class Test_postgresql_flexible_server_log_disconnections_on: + def test_no_postgresql_flexible_servers(self): + postgresql_client = mock.MagicMock + postgresql_client.flexible_servers = {} + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_disconnections_on.postgresql_flexible_server_log_disconnections_on.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_disconnections_on.postgresql_flexible_server_log_disconnections_on import ( + postgresql_flexible_server_log_disconnections_on, + ) + + check = postgresql_flexible_server_log_disconnections_on() + result = check.execute() + assert len(result) == 0 + + def test_flexible_servers_log_connections_off(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="OFF", + log_checkpoints="OFF", + log_connections="OFF", + log_disconnections="OFF", + connection_throttling="OFF", + log_retention_days="3", + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_disconnections_on.postgresql_flexible_server_log_disconnections_on.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_disconnections_on.postgresql_flexible_server_log_disconnections_on import ( + postgresql_flexible_server_log_disconnections_on, + ) + + check = postgresql_flexible_server_log_disconnections_on() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has log_disconnections disabled" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id + + def test_flexible_servers_log_connections_on(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="OFF", + log_checkpoints="ON", + log_connections="ON", + log_disconnections="ON", + connection_throttling="ON", + log_retention_days="3", + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_disconnections_on.postgresql_flexible_server_log_disconnections_on.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_disconnections_on.postgresql_flexible_server_log_disconnections_on import ( + postgresql_flexible_server_log_disconnections_on, + ) + + check = postgresql_flexible_server_log_disconnections_on() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has log_disconnections enabled" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id diff --git a/tests/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/postgresql_flexible_server_log_retention_days_greater_3_test.py b/tests/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/postgresql_flexible_server_log_retention_days_greater_3_test.py new file mode 100644 index 00000000..f3f650db --- /dev/null +++ b/tests/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/postgresql_flexible_server_log_retention_days_greater_3_test.py @@ -0,0 +1,191 @@ +from unittest import mock +from uuid import uuid4 + +from prowler.providers.azure.services.postgresql.postgresql_service import Server + +AZURE_SUBSCRIPTION = str(uuid4()) + + +class Test_postgresql_flexible_server_log_retention_days_greater_3: + def test_no_postgresql_flexible_servers(self): + postgresql_client = mock.MagicMock + postgresql_client.flexible_servers = {} + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_retention_days_greater_3.postgresql_flexible_server_log_retention_days_greater_3.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_retention_days_greater_3.postgresql_flexible_server_log_retention_days_greater_3 import ( + postgresql_flexible_server_log_retention_days_greater_3, + ) + + check = postgresql_flexible_server_log_retention_days_greater_3() + result = check.execute() + assert len(result) == 0 + + def test_flexible_servers_no_log_retention_days(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="OFF", + log_checkpoints="OFF", + log_connections="OFF", + log_disconnections="OFF", + connection_throttling="OFF", + log_retention_days=None, + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_retention_days_greater_3.postgresql_flexible_server_log_retention_days_greater_3.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_retention_days_greater_3.postgresql_flexible_server_log_retention_days_greater_3 import ( + postgresql_flexible_server_log_retention_days_greater_3, + ) + + check = postgresql_flexible_server_log_retention_days_greater_3() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has log_retention disabled" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id + + def test_flexible_servers_log_retention_days_3(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + log_retention_days = "3" + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="OFF", + log_checkpoints="OFF", + log_connections="OFF", + log_disconnections="OFF", + connection_throttling="OFF", + log_retention_days=log_retention_days, + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_retention_days_greater_3.postgresql_flexible_server_log_retention_days_greater_3.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_retention_days_greater_3.postgresql_flexible_server_log_retention_days_greater_3 import ( + postgresql_flexible_server_log_retention_days_greater_3, + ) + + check = postgresql_flexible_server_log_retention_days_greater_3() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has log_retention set to {log_retention_days}" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id + + def test_flexible_servers_log_retention_days_4(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + log_retention_days = "4" + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="OFF", + log_checkpoints="OFF", + log_connections="OFF", + log_disconnections="OFF", + connection_throttling="OFF", + log_retention_days=log_retention_days, + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_retention_days_greater_3.postgresql_flexible_server_log_retention_days_greater_3.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_retention_days_greater_3.postgresql_flexible_server_log_retention_days_greater_3 import ( + postgresql_flexible_server_log_retention_days_greater_3, + ) + + check = postgresql_flexible_server_log_retention_days_greater_3() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has log_retention set to {log_retention_days}" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id + + def test_flexible_servers_log_retention_days_8(self): + postgresql_client = mock.MagicMock + postgresql_server_name = "Postgres Flexible Server Name" + postgresql_server_id = str(uuid4()) + log_retention_days = "8" + postgresql_client.flexible_servers = { + AZURE_SUBSCRIPTION: [ + Server( + id=postgresql_server_id, + name=postgresql_server_name, + resource_group="resource_group", + require_secure_transport="OFF", + log_checkpoints="OFF", + log_connections="OFF", + log_disconnections="OFF", + connection_throttling="OFF", + log_retention_days=log_retention_days, + firewall=None, + ) + ] + } + + with mock.patch( + "prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_retention_days_greater_3.postgresql_flexible_server_log_retention_days_greater_3.postgresql_client", + new=postgresql_client, + ): + from prowler.providers.azure.services.postgresql.postgresql_flexible_server_log_retention_days_greater_3.postgresql_flexible_server_log_retention_days_greater_3 import ( + postgresql_flexible_server_log_retention_days_greater_3, + ) + + check = postgresql_flexible_server_log_retention_days_greater_3() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"Flexible Postgresql server {postgresql_server_name} from subscription {AZURE_SUBSCRIPTION} has log_retention set to {log_retention_days}" + ) + assert result[0].subscription == AZURE_SUBSCRIPTION + assert result[0].resource_name == postgresql_server_name + assert result[0].resource_id == postgresql_server_id diff --git a/tests/providers/azure/services/postgresql/postgresql_service_test.py b/tests/providers/azure/services/postgresql/postgresql_service_test.py new file mode 100644 index 00000000..cdc479c6 --- /dev/null +++ b/tests/providers/azure/services/postgresql/postgresql_service_test.py @@ -0,0 +1,122 @@ +from unittest.mock import patch + +from prowler.providers.azure.services.postgresql.postgresql_service import ( + Firewall, + PostgreSQL, + Server, +) +from tests.providers.azure.azure_fixtures import ( + AZURE_SUBSCRIPTION, + set_mocked_azure_audit_info, +) + + +def mock_sqlserver_get_postgresql_flexible_servers(_): + firewall = Firewall( + id="id", + name="name", + start_ip="start_ip", + end_ip="end_ip", + ) + return { + AZURE_SUBSCRIPTION: [ + Server( + id="id", + name="name", + resource_group="resource_group", + require_secure_transport="ON", + log_checkpoints="ON", + log_connections="ON", + log_disconnections="ON", + connection_throttling="ON", + log_retention_days="3", + firewall=[firewall], + ) + ] + } + + +@patch( + "prowler.providers.azure.services.postgresql.postgresql_service.PostgreSQL.__get_flexible_servers__", + new=mock_sqlserver_get_postgresql_flexible_servers, +) +class Test_SqlServer_Service: + def test__get_client__(self): + postgresql = PostgreSQL(set_mocked_azure_audit_info()) + assert ( + postgresql.clients[AZURE_SUBSCRIPTION].__class__.__name__ + == "PostgreSQLManagementClient" + ) + + def test__get_sql_servers__(self): + postgesql = PostgreSQL(set_mocked_azure_audit_info()) + assert ( + postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].__class__.__name__ + == "Server" + ) + assert postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].id == "id" + assert postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].name == "name" + assert ( + postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].resource_group + == "resource_group" + ) + + def test__get_resource_group__(self): + id = "/subscriptions/subscription/resourceGroups/resource_group/providers/Microsoft.DBforPostgreSQL/flexibleServers/server" + postgresql = PostgreSQL(set_mocked_azure_audit_info()) + assert postgresql.__get_resource_group__(id) == "resource_group" + + def test__get_require_secure_transport__(self): + postgesql = PostgreSQL(set_mocked_azure_audit_info()) + assert ( + postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].require_secure_transport + == "ON" + ) + + def test__get_log_checkpoints__(self): + postgesql = PostgreSQL(set_mocked_azure_audit_info()) + assert postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].log_checkpoints == "ON" + + def test__get_log_connections__(self): + postgesql = PostgreSQL(set_mocked_azure_audit_info()) + assert postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].log_connections == "ON" + + def test__get_log_disconnections__(self): + postgesql = PostgreSQL(set_mocked_azure_audit_info()) + assert ( + postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].log_disconnections == "ON" + ) + + def test__get_connection_throttling__(self): + postgesql = PostgreSQL(set_mocked_azure_audit_info()) + assert ( + postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].connection_throttling + == "ON" + ) + + def test__get_log_retention_days__(self): + postgesql = PostgreSQL(set_mocked_azure_audit_info()) + assert ( + postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].log_retention_days == "3" + ) + + def test__get_firewall__(self): + postgesql = PostgreSQL(set_mocked_azure_audit_info()) + assert ( + postgesql.flexible_servers[AZURE_SUBSCRIPTION][0] + .firewall[0] + .__class__.__name__ + == "Firewall" + ) + assert postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].firewall[0].id == "id" + assert ( + postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].firewall[0].name == "name" + ) + assert ( + postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].firewall[0].start_ip + == "start_ip" + ) + assert ( + postgesql.flexible_servers[AZURE_SUBSCRIPTION][0].firewall[0].end_ip + == "end_ip" + )