From e6e5a6e6258fdc8f73329088d4404f288050fe03 Mon Sep 17 00:00:00 2001 From: Olaf Heimburger Date: Mon, 5 Feb 2024 10:04:02 +0100 Subject: [PATCH 1/2] Updates for 240130. --- .../README.md | 53 +- .../README.md | 84 ++- .../README.txt | 40 +- .../requirements.txt | 3 +- .../scripts/cis_reports/cis_reports.py | 477 ++++++++++++++---- .../standard.sh | 4 +- .../resources/cis_html_summary_report.html | 422 ++++++++++++++++ 7 files changed, 916 insertions(+), 167 deletions(-) create mode 100644 security/security-design/shared-assets/oci-security-health-check-standard/files/resources/cis_html_summary_report.html diff --git a/security/security-design/shared-assets/oci-security-health-check-standard/README.md b/security/security-design/shared-assets/oci-security-health-check-standard/README.md index d4b69ba91..c270ef586 100644 --- a/security/security-design/shared-assets/oci-security-health-check-standard/README.md +++ b/security/security-design/shared-assets/oci-security-health-check-standard/README.md @@ -2,7 +2,7 @@ Owner: Olaf Heimburger -Version: 230922 +Version: 240130 Reviewed: 01.02.2024 @@ -67,28 +67,37 @@ For recurring usage, setting up a group for auditing is recommended. For setting Using an auditor group is the recommended way to run the assessment script. To create a group for auditing do the following steps: - - Log into OCI Console as OCI administrator - - Create a group `grp-auditors` - - Create a policy `pcy-auditing` with these statements: + - Log into OCI Console as OCI administrator. + - In your Default domain create a group `grp-auditors` + - Create a policy `pcy-auditing` with these statements (if your tenancy does not have Domains, replace `'Default'/'grp-auditors'` with `grp-auditors`): ``` - allow group grp-auditors to inspect all-resources in tenancy - allow group grp-auditors to read instances in tenancy - allow group grp-auditors to read load-balancers in tenancy - allow group grp-auditors to read buckets in tenancy - allow group grp-auditors to read nat-gateways in tenancy - allow group grp-auditors to read public-ips in tenancy - allow group grp-auditors to read file-family in tenancy - allow group grp-auditors to read instance-configurations in tenancy - allow group grp-auditors to read network-security-groups in tenancy - allow group grp-auditors to read resource-availability in tenancy - allow group grp-auditors to read audit-events in tenancy - allow group grp-auditors to read users in tenancy - allow group grp-auditors to read vss-family in tenancy - allow group grp-auditors to read dns in tenancy - allow group grp-auditors to use cloud-shell in tenancy - ``` - - Assign a user to the `grp-auditors` group - - Log out of the OCI Console + allow group 'Default'/'grp-auditors' to inspect all-resources in tenancy + allow group 'Default'/'grp-auditors' to read instances in tenancy + allow group 'Default'/'grp-auditors' to read load-balancers in tenancy + allow group 'Default'/'grp-auditors' to read buckets in tenancy + allow group 'Default'/'grp-auditors' to read nat-gateways in tenancy + allow group 'Default'/'grp-auditors' to read public-ips in tenancy + allow group 'Default'/'grp-auditors' to read file-family in tenancy + allow group 'Default'/'grp-auditors' to read instance-configurations in tenancy + allow group 'Default'/'grp-auditors' to read network-security-groups in tenancy + allow group 'Default'/'grp-auditors' to read resource-availability in tenancy + allow group 'Default'/'grp-auditors' to read audit-events in tenancy + allow group 'Default'/'grp-auditors' to read users in tenancy + allow group 'Default'/'grp-auditors' to read vss-family in tenancy + allow group 'Default'/'grp-auditors' to read dns in tenancy + allow group 'Default'/'grp-auditors' to use cloud-shell in tenancy ``` + - Assign a user to the `grp-auditors` group. + - Log out of the OCI Console. + +## Run the OCI Security Health Check in OCI Cloud Shell + +For a detailed description go to [Run the OCI Security Health Check in OCI Cloud Shell](https://github.com/oracle-devrel/technology-engineering/blob/main/security/security-design/oci-security-health-check-standard/files/oci-security-health-check-standard/README.md#run-the-oci-security-health-check-in-cloud-shell) + +## Sample Output + +After a completed run you will find a directory with a name starting with your tenancy name followed by a timestamp in your working directory (like `tenancy_name_YYYYMMDDHHmmss_standard`). A zip archive for easier download using the same name will be created, too. Both hold data files for your review. + +To start with reviewing the results, open the file named [cis_html_summary_report.html](files/resources/cis_html_summary_report.html)(sample report). # Credits diff --git a/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/README.md b/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/README.md index 2da017a1c..aba650567 100644 --- a/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/README.md +++ b/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/README.md @@ -2,7 +2,7 @@ Owner: Olaf Heimburger -Version: 230922 +Version: 240130 ## When to use this asset? @@ -14,25 +14,25 @@ The *OCI Security Health Check - Standard Edition* checks an OCI tenancy for CIS Before running the *OCI Security Health Check - Standard Edition* you should download and verify it. - - Download the latest distribution [oci-security-health-check-standard-230922.zip](https://github.com/oracle-devrel/technology-engineering/releases/download/oci-security-health-check-std-230922/oci-security-health-check-standard-230922.zip). - - Download the respective checksum file [oci-security-health-check-standard-230922.sha512256](https://github.com/oracle-devrel/technology-engineering/releases/download/oci-security-health-check-std-230922/oci-security-health-check-standard-230922.sha512256). + - Download the latest distribution [oci-security-health-check-standard-240130.zip](https://github.com/oracle-devrel/technology-engineering/releases/download/oci-security-health-check-std-240130/oci-security-health-check-standard-240130.zip). + - Download the respective checksum file [oci-security-health-check-standard-240130.sha512256](https://github.com/oracle-devrel/technology-engineering/releases/download/oci-security-health-check-std-240130/oci-security-health-check-standard-240130.sha512256). - Verify the integrity of the distribution. Both files must be in the same directory (for example, in your downloads directory). On MacOS: ``` $ cd - $ shasum -a 512256 -c oci-security-health-check-standard-230922.sha512256 - oci-security-health-check-standard-230922.zip: OK + $ shasum -a 512256 -c oci-security-health-check-standard-240130.sha512256 + oci-security-health-check-standard-240130.zip: OK ``` On Linux (including Cloud Shell): ``` $ cd - $ sha512sum -c oci-security-health-check-standard-230922.sha512 - oci-security-health-check-standard-230922.zip: OK + $ sha512sum -c oci-security-health-check-standard-240130.sha512 + oci-security-health-check-standard-240130.zip: OK ``` -**Reject the downloaded file if the check fails!** +**Reject the downloaded file when the check fails!** ### Prepare the OCI Tenancy @@ -51,26 +51,48 @@ steps for setting this up are described in the next chapter. Using an auditor group is the recommended way to run the assessment script. To create a group for auditing do the following steps: - - Log into OCI Console as OCI administrator + - Check whether your tenancy is still not migrated to Identity Domains: + - Login to OCI Console as OCI administrator + - Select "Identity & Security" + - If "Domains" are listed you are migrated to Identity Domains - Create a group `grp-auditors` - Create a policy `pcy-auditing` with these statements: - ``` - allow group grp-auditors to inspect all-resources in tenancy - allow group grp-auditors to read instances in tenancy - allow group grp-auditors to read load-balancers in tenancy - allow group grp-auditors to read buckets in tenancy - allow group grp-auditors to read nat-gateways in tenancy - allow group grp-auditors to read public-ips in tenancy - allow group grp-auditors to read file-family in tenancy - allow group grp-auditors to read instance-configurations in tenancy - allow group grp-auditors to read network-security-groups in tenancy - allow group grp-auditors to read resource-availability in tenancy - allow group grp-auditors to read audit-events in tenancy - allow group grp-auditors to read users in tenancy - allow group grp-auditors to read vss-family in tenancy - allow group grp-auditors to read dns in tenancy - allow group grp-auditors to use cloud-shell in tenancy - ``` + - For tenancies **without** Identity Domains use + ``` + allow group grp-auditors to inspect all-resources in tenancy + allow group grp-auditors to read instances in tenancy + allow group grp-auditors to read load-balancers in tenancy + allow group grp-auditors to read buckets in tenancy + allow group grp-auditors to read nat-gateways in tenancy + allow group grp-auditors to read public-ips in tenancy + allow group grp-auditors to read file-family in tenancy + allow group grp-auditors to read instance-configurations in tenancy + allow group grp-auditors to read network-security-groups in tenancy + allow group grp-auditors to read resource-availability in tenancy + allow group grp-auditors to read audit-events in tenancy + allow group grp-auditors to read users in tenancy + allow group grp-auditors to read vss-family in tenancy + allow group grp-auditors to read dns in tenancy + allow group grp-auditors to use cloud-shell in tenancy + ``` + - For tenancies **with** Identity Domains use + ``` + allow group 'Default'/'grp-auditors' to inspect all-resources in tenancy + allow group 'Default'/'grp-auditors' to read instances in tenancy + allow group 'Default'/'grp-auditors' to read load-balancers in tenancy + allow group 'Default'/'grp-auditors' to read buckets in tenancy + allow group 'Default'/'grp-auditors' to read nat-gateways in tenancy + allow group 'Default'/'grp-auditors' to read public-ips in tenancy + allow group 'Default'/'grp-auditors' to read file-family in tenancy + allow group 'Default'/'grp-auditors' to read instance-configurations in tenancy + allow group 'Default'/'grp-auditors' to read network-security-groups in tenancy + allow group 'Default'/'grp-auditors' to read resource-availability in tenancy + allow group 'Default'/'grp-auditors' to read audit-events in tenancy + allow group 'Default'/'grp-auditors' to read users in tenancy + allow group 'Default'/'grp-auditors' to read vss-family in tenancy + allow group 'Default'/'grp-auditors' to read dns in tenancy + allow group 'Default'/'grp-auditors' to use cloud-shell in tenancy + ``` - Assign a user to the `grp-auditors` group - Log out of the OCI Console @@ -128,6 +150,12 @@ The report results are summarized in two files: - *cis_html_summary_report.html* – The report in HTML that displays the all recommendations and their compliance status, respectively. - *Consolidated_Report.xslx* – An XSLX workbook with a summary and sheets for the non-compliant recommendations. +### Known Issues + +#### Wrong urllib3 version + +There is a known dependency between Python urllib3 version 2 and the OS installed version of OpenSSL. The script tries to handle this automatically using a working version of urllib3. If the handling does not work let us know. + ## Credits The *OCI Security Health Check - Standard Edition* streamlines the usage of the bundled [Compliance Checking Script](https://github.com/oracle-quickstart/oci-cis-landingzone-quickstart/blob/main/compliance-script.md) provided by the [CIS OCI Landing Zone Quick Start Template](https://github.com/oracle-quickstart/oci-cis-landingzone-quickstart). @@ -140,8 +168,8 @@ The Compliance Checking Script is certified by the [CIS Center of Internet Secur # License -Copyright (c) 2022-2023 Oracle and/or its affiliates. +Copyright (c) 2022-2024 Oracle and/or its affiliates. Licensed under the Universal Permissive License (UPL), Version 1.0. -See [LICENSE](https://github.com/oracle-devrel/technology-engineering/blob/folder-structure/LICENSE) for more details. +See [LICENSE](https://github.com/oracle-devrel/technology-engineering/blob/main/LICENSE) for more details. diff --git a/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/README.txt b/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/README.txt index a2755f005..4bd8e40bb 100644 --- a/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/README.txt +++ b/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/README.txt @@ -2,7 +2,7 @@ OCI Security Health Check - Standard Edition ============================================ Owner: Olaf Heimburger -Version: 230922 +Version: 240130 When to use this asset? @@ -23,12 +23,13 @@ Usage steps for setting this up are described in the next chapter. 1.1 Setup an Auditor group and policy - Using an auditor group is the recommended way to run the assessment script. - To create a group for auditing do the following steps: - - - Log into OCI Console as OCI administrator + - Check whether your tenancy is still not migrated to Identity Domains: + - Login to OCI Console as OCI Administrator + - Select "Identity & Security" + - If "Domains" are listed you are migrated to Identity Domains - Create a group grp-auditors - Create a policy pcy-auditing with these statements: +- For tenancies without Identity Domains use allow group grp-auditors to inspect all-resources in tenancy allow group grp-auditors to read instances in tenancy allow group grp-auditors to read load-balancers in tenancy @@ -44,6 +45,22 @@ Usage allow group grp-auditors to read vss-family in tenancy allow group grp-auditors to read dns in tenancy allow group grp-auditors to use cloud-shell in tenancy +- For tenancies *with* Identity Domains use + allow group 'Default'/'grp-auditors' to inspect all-resources in tenancy + allow group 'Default'/'grp-auditors' to read instances in tenancy + allow group 'Default'/'grp-auditors' to read load-balancers in tenancy + allow group 'Default'/'grp-auditors' to read buckets in tenancy + allow group 'Default'/'grp-auditors' to read nat-gateways in tenancy + allow group 'Default'/'grp-auditors' to read public-ips in tenancy + allow group 'Default'/'grp-auditors' to read file-family in tenancy + allow group 'Default'/'grp-auditors' to read instance-configurations in tenancy + allow group 'Default'/'grp-auditors' to read network-security-groups in tenancy + allow group 'Default'/'grp-auditors' to read resource-availability in tenancy + allow group 'Default'/'grp-auditors' to read audit-events in tenancy + allow group 'Default'/'grp-auditors' to read users in tenancy + allow group 'Default'/'grp-auditors' to read vss-family in tenancy + allow group 'Default'/'grp-auditors' to read dns in tenancy + allow group 'Default'/'grp-auditors' to use cloud-shell in tenancy - Assign a user to the grp-auditors group - Log out of OCI Console @@ -72,20 +89,25 @@ Usage compressed in a single ZIP file and the resulting ZIP file will be moved to the home directory of the account running the script. +4 Known Issues + +4.1 Wrong urllib3 version + +There is a known dependency between Python urllib3 version 2 and the OS installed version of OpenSSL. The script tries to handle this automatically using a working version of urllib3. If the handling does not work let us know. -4 Credits +5 Credits The OCI Security Health Check - Standard Edition streamlines the usage of the bundled Compliance Checking Script (https://github.com/oracle-quickstart/oci-cis-landingzone-quickstart/blob/main/compliance-script.md) provided by the CIS OCI Landing Zone Quick Start Template (https://github.com/oracle-quickstart/oci-cis-landingzone-quickstart). The OCI Security Health Check - Standard Edition would not be possible without the great work of the CIS OCI Landing Zone Quick Start Template Team (https://github.com/oracle-quickstart/oci-cis-landingzone-quickstart/graphs/contributors). -5 Certification +6 Certification The Compliance Checking Script is certified by the CIS Center of Internet Security for the OCI Oracle Cloud Foundation Benchmark v1.2.O, Level 1 and 2 (https://www.cisecurity.org/partner/oracle). -6 License +7 License -Copyright (c) 2022-2023 Oracle and/or its affiliates. +Copyright (c) 2022-2024 Oracle and/or its affiliates. Licensed under the Universal Permissive License (UPL), Version 1.0. diff --git a/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/requirements.txt b/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/requirements.txt index f0406d5b5..45cf3706b 100644 --- a/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/requirements.txt +++ b/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/requirements.txt @@ -1,5 +1,6 @@ +urllib3==1.26.17 xlsxwriter>=3.0.3 pandas>=1.5.2 openpyxl>=3.0.10 pyyaml>=6.0 -oci>=2.110 +oci>=2.119.0 diff --git a/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/scripts/cis_reports/cis_reports.py b/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/scripts/cis_reports/cis_reports.py index 27adc74a4..d46f1edd5 100644 --- a/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/scripts/cis_reports/cis_reports.py +++ b/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/scripts/cis_reports/cis_reports.py @@ -1,5 +1,5 @@ ########################################################################## -# Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. # This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license. # # cis_reports.py @@ -26,6 +26,7 @@ import hashlib import re import requests +import pickle try: from xlsxwriter.workbook import Workbook @@ -34,9 +35,9 @@ except Exception: OUTPUT_TO_XLSX = False -RELEASE_VERSION = "2.6.4" -PYTHON_SDK_VERSION = "2.110.0" -UPDATED_DATE = "September 18, 2023" +RELEASE_VERSION = "2.7.1" +PYTHON_SDK_VERSION = "2.118.0" +UPDATED_DATE = "January 05, 2024" ########################################################################## @@ -65,11 +66,12 @@ def show_version(verbose=False): script_version = f'CIS Reports - Release {RELEASE_VERSION}' script_updated = f'Version {RELEASE_VERSION} Updated on {UPDATED_DATE}' if verbose: - print_header('Running ' + script_version) + print_header(f'Running {script_version}') print(script_updated) print('Please use --help for more info') - print('\nTested oci-python-sdk version: ' + PYTHON_SDK_VERSION) - print('Installed oci-python-sdk version: ' + str(oci.__version__)) + print(f'\nTested oci-python-sdk version: {PYTHON_SDK_VERSION}') + print(f'Installed oci-python-sdk version: {str(oci.__version__)}') + print(f'The command line arguments are: {str(sys.argv)}') else: print(script_updated) @@ -134,7 +136,7 @@ class CIS_Report: str_kms_key_time_max_datetime = kms_key_time_max_datetime.strftime(__iso_time_format) kms_key_time_max_datetime = datetime.datetime.strptime(str_kms_key_time_max_datetime, __iso_time_format) - def __init__(self, config, signer, proxy, output_bucket, report_directory, print_to_screen, regions_to_run_in, raw_data, obp, redact_output, debug=False): + def __init__(self, config, signer, proxy, output_bucket, report_directory, print_to_screen, regions_to_run_in, raw_data, obp, redact_output, debug=False, all_resources=True): # CIS Foundation benchmark 1.2 self.cis_foundations_benchmark_1_2 = { @@ -199,104 +201,119 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "", "Remediation": "Refer to the policy syntax document and create new policies if the audit results indicate that the required policies are missing.", "Recommendation": "", - "Observation": "custom IAM policy that grants tenancy administrative access."}, + "Observation": "custom IAM policy that grants tenancy administrative access." + }, "1.2": { "Description": "There is a built-in OCI IAM policy enabling the Administrators group to perform any action within a tenancy. In the OCI IAM console, this policy reads:

\nAllow group Administrators to manage all-resources in tenancy\n


Administrators create more users, groups, and policies to provide appropriate access to other groups.

Administrators should not allow any-other-group full access to the tenancy by writing a policy like this:

\nAllow group any-other-group to manage all-resources in tenancy\n


The access should be narrowed down to ensure the least-privileged principle is applied.", "Rationale": "Permission to manage all resources in a tenancy should be limited to a small number of users in the 'Administrators' group for break-glass situations and to set up users/groups/policies when a tenancy is created.

No group other than 'Administrators' in a tenancy should need access to all resources in a tenancy, as this violates the enforcement of the least privilege principle.", "Impact": "", "Remediation": "Remove any policy statement that allows any group other than Administrators or any service access to manage all resources in the tenancy.", "Recommendation": "Evaluate if tenancy-wide administrative access is needed for the identified policy and update it to be more restrictive.", - "Observation": "custom IAM policy that grants tenancy administrative access."}, + "Observation": "custom IAM policy that grants tenancy administrative access." + }, "1.3": { "Description": "Tenancy administrators can create more users, groups, and policies to provide other service administrators access to OCI resources.

For example, an IAM administrator will need to have access to manage\n resources like compartments, users, groups, dynamic-groups, policies, identity-providers, tenancy tag-namespaces, tag-definitions in the tenancy.

The policy that gives IAM-Administrators or any other group full access to 'groups' resources should not allow access to the tenancy 'Administrators' group.

The policy statements would look like:

\nAllow group IAMAdmins to inspect users in tenancy\nAllow group IAMAdmins to use users in tenancy where target.group.name != 'Administrators'\nAllow group IAMAdmins to inspect groups in tenancy\nAllow group IAMAdmins to use groups in tenancy where target.group.name != 'Administrators'\n


Note: You must include separate statements for 'inspect' access, because the target.group.name variable is not used by the ListUsers and ListGroups operations", "Rationale": "These policy statements ensure that no other group can manage tenancy administrator users or the membership to the 'Administrators' group thereby gain or remove tenancy administrator access.", "Impact": "", "Remediation": "Verify the results to ensure that the policy statements that grant access to use or manage users or groups in the tenancy have a condition that excludes access to Administrators group or to users in the Administrators group.", "Recommendation": "Evaluate if tenancy-wide administrative access is needed for the identified policy and update it to be more restrictive.", - "Observation": "custom IAM policy that grants tenancy administrative access."}, + "Observation": "custom IAM policy that grants tenancy administrative access." + }, "1.4": { "Description": "Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are at least a certain length and are composed of certain characters.

It is recommended the password policy require a minimum password length 14 characters and contain 1 non-alphabetic\ncharacter (Number or 'Special Character').", "Rationale": "In keeping with the overall goal of having users create a password that is not overly weak, an eight-character minimum password length is recommended for an MFA account, and 14 characters for a password only account. In addition, maximum password length should be made as long as possible based on system/software capabilities and not restricted by policy.

In general, it is true that longer passwords are better (harder to crack), but it is also true that forced password length requirements can cause user behavior that is predictable and undesirable. For example, requiring users to have a minimum 16-character password may cause them to choose repeating patterns like fourfourfourfour or passwordpassword that meet the requirement but aren't hard to guess. Additionally, length requirements increase the chances that users will adopt other insecure practices, like writing them down, re-using them or storing them unencrypted in their documents.

Password composition requirements are a poor defense against guessing attacks. Forcing users to choose some combination of upper-case, lower-case, numbers, and special characters has a negative impact. It places an extra burden on users and many\nwill use predictable patterns (for example, a capital letter in the first position, followed by lowercase letters, then one or two numbers, and a “special character” at the end). Attackers know this, so dictionary attacks will often contain these common patterns and use the most common substitutions like, $ for s, @ for a, 1 for l, 0 for o.

Passwords that are too complex in nature make it harder for users to remember, leading to bad practices. In addition, composition requirements provide no defense against common attack types such as social engineering or insecure storage of passwords.", "Impact": "", "Remediation": "Update the password policy such as minimum length to 14, password must contain expected special characters and numeric characters.", "Recommendation": "It is recommended the password policy require a minimum password length 14 characters and contain 1 non-alphabetic character (Number or 'Special Character').", - "Observation": "password policy/policies that do not enforce sufficient password complexity requirements."}, + "Observation": "password policy/policies that do not enforce sufficient password complexity requirements." + }, "1.5": { "Description": "IAM password policies can require passwords to be rotated or expired after a given number of days. It is recommended that the password policy expire passwords after 365 and are changed immediately based on events.", - "Rationale": "Excessive password expiration requirements do more harm than good, because these requirements make users select predictable passwords, composed of sequential words and numbers that are closely related to each other.10 In these cases, the next password can be predicted based on the previous one (incrementing a number used in the password for example). Also, password expiration requirements offer no containment benefits because attackers will often use credentials as soon as they compromise them. Instead, immediate password changes should be based on key events including, but not\nlimited to:

1. Indication of compromise\n1. Change of user roles\n1. When a user leaves the organization.

Not only does changing passwords every few weeks or months frustrate the user, it's been suggested that it does more harm than good, because it could lead to bad practices by the user such as adding a character to the end of their existing password.

In addition, we also recommend a yearly password change. This is primarily because for all their good intentions users will share credentials across accounts. Therefore, even if a breach is publicly identified, the user may not see this notification, or forget they have an account on that site. This could leave a shared credential vulnerable indefinitely. Having an organizational policy of a 1-year (annual) password expiration is a reasonable compromise to mitigate this with minimal user burden.", + "Rationale": "Excessive password expiration requirements do more harm than good, because these requirements make users select predictable passwords, composed of sequential words and numbers that are closely related to each other. In these cases, the next password can be predicted based on the previous one (incrementing a number used in the password for example). Also, password expiration requirements offer no containment benefits because attackers will often use credentials as soon as they compromise them. Instead, immediate password changes should be based on key events including, but not limited to:

1. Indication of compromise
2. Change of user roles
3. When a user leaves the organization.

Not only does changing passwords every few weeks or months frustrate the user, it's been suggested that it does more harm than good, because it could lead to bad practices by the user such as adding a character to the end of their existing password.

In addition, we also recommend a yearly password change. This is primarily because for all their good intentions users will share credentials across accounts. Therefore, even if a breach is publicly identified, the user may not see this notification, or forget they have an account on that site. This could leave a shared credential vulnerable indefinitely. Having an organizational policy of a 1-year (annual) password expiration is a reasonable compromise to mitigate this with minimal user burden.", "Impact": "", "Remediation": "Update the password policy by setting number of days configured in Expires after to 365.", "Recommendation": "Evaluate password rotation policies are inline with your organizational standard.", - "Observation": "password policy/policies that do not require rotation."}, + "Observation": "password policy/policies that do require rotation." + }, "1.6": { "Description": "IAM password policies can prevent the reuse of a given password by the same user. It is recommended the password policy prevent the reuse of passwords.", "Rationale": "Enforcing password history ensures that passwords are not reused in for a certain period of time by the same user. If a user is not allowed to use last 24 passwords, that window of time is greater. This helps maintain the effectiveness of password security.", "Impact": "", "Remediation": "Update the number of remembered passwords in previous passwords remembered setting to 24 in the password policy.", "Recommendation": "Evaluate password reuse policies are inline with your organizational standard.", - "Observation": "password policy/policies that do not prevent reuse."}, + "Observation": "password policy/policies that do prevent reuse." + }, "1.7": { "Description": "Multi-factor authentication is a method of authentication that requires the use of more than one factor to verify a user's identity.

With MFA enabled in the IAM service, when a user signs in to Oracle Cloud Infrastructure, they are prompted for their user name and password, which is the first factor (something that they know). The user is then prompted to provide a second verification code from a registered MFA device, which is the second factor (something that they have). The two factors work together, requiring an extra layer of security to verify the user's identity and complete the sign-in process.

OCI IAM supports two-factor authentication using a password (first factor) and a device that can generate a time-based one-time password (TOTP) (second factor).

See [OCI documentation](https://docs.cloud.oracle.com/en-us/iaas/Content/Identity/Tasks/usingmfa.htm) for more details.", "Rationale": "Multi factor authentication adds an extra layer of security during the login process and makes it harder for unauthorized users to gain access to OCI resources.", "Impact": "", "Remediation": "Each user must enable MFA for themselves using a device they will have access to every time they sign in. An administrator cannot enable MFA for another user but can enforce MFA by identifying the list of non-complaint users, notifying them or disabling access by resetting password for non-complaint accounts.", "Recommendation": "Evaluate if local users are required. For Break Glass accounts ensure MFA is in place.", - "Observation": "users with Password access but not MFA."}, + "Observation": "users with Password access but not MFA." + }, "1.8": { "Description": "API keys are used by administrators, developers, services and scripts for accessing OCI APIs directly or via SDKs/OCI CLI to search, create, update or delete OCI resources.

The API key is an RSA key pair. The private key is used for signing the API requests and the public key is associated with a local or synchronized user's profile.", "Rationale": "It is important to secure and rotate an API key every 90 days or less as it provides the same level of access that a user it is associated with has.

In addition to a security engineering best practice, this is also a compliance requirement. For example, PCI-DSS Section 3.6.4 states, \"Verify that key-management procedures include a defined cryptoperiod for each key type in use and define a process for key changes at the end of the defined crypto period(s).\"", "Impact": "", "Remediation": "Delete any API Keys with a date of 90 days or older under the Created column of the API Key table.", "Recommendation": "Evaluate if APIs Keys are still used/required and rotate API Keys It is important to secure and rotate an API key every 90 days or less as it provides the same level of access that a user it is associated with has.", - "Observation": "user(s) with APIs that have not been rotated with 90 days."}, + "Observation": "user(s) with APIs that have not been rotated with 90 days." + }, "1.9": { "Description": "Object Storage provides an API to enable interoperability with Amazon S3. To use this Amazon S3 Compatibility API, you need to generate the signing key required to authenticate with Amazon S3.

This special signing key is an Access Key/Secret Key pair. Oracle generates the Customer Secret key to pair with the Access Key.", "Rationale": "It is important to secure and rotate an customer secret key every 90 days or less as it provides the same level of object storage access that a user is associated with has.", "Impact": "", "Remediation": "Delete any Access Keys with a date of 90 days or older under the Created column of the Customer Secret Keys.", "Recommendation": "Evaluate if Customer Secret Keys are still used/required and rotate the Keys accordingly.", - "Observation": "users with Customer Secret Keys that have not been rotated with 90 days."}, + "Observation": "users with Customer Secret Keys that have not been rotated with 90 days." + }, "1.10": { "Description": "Auth tokens are authentication tokens generated by Oracle. You use auth tokens to authenticate with APIs that do not support the Oracle Cloud Infrastructure signature-based authentication. If the service requires an auth token, the service-specific documentation instructs you to generate one and how to use it.", "Rationale": "It is important to secure and rotate an auth token every 90 days or less as it provides the same level of access to APIs that do not support the OCI signature-based authentication as the user associated to it.", "Impact": "", "Remediation": "Delete any auth token with a date of 90 days or older under the Created column of the Auth Tokens.", "Recommendation": "Evaluate if Auth Tokens are still used/required and rotate Auth tokens.", - "Observation": "user(s) with auth tokens that have not been rotated in 90 days."}, + "Observation": "user(s) with auth tokens that have not been rotated in 90 days." + }, "1.11": { "Description": "Tenancy administrator users have full access to the organization's OCI tenancy. API keys associated with user accounts are used for invoking the OCI APIs via custom programs or clients like CLI/SDKs. The clients are typically used for performing day-to-day operations and should never require full tenancy access. Service-level administrative users with API keys should be used instead.", "Rationale": "For performing day-to-day operations tenancy administrator access is not needed.\nService-level administrative users with API keys should be used to apply privileged security principle.", "Impact": "", "Remediation": "For each tenancy administrator user who has an API key,select API Keys from the menu and delete any associated keys from the API Keys table.", "Recommendation": "Evaluate if a user with API Keys requires Administrator access and use a least privilege approach.", - "Observation": "users with Administrator access and API Keys."}, + "Observation": "users with Administrator access and API Keys." + }, "1.12": { "Description": "All OCI IAM local user accounts have an email address field associated with the account. It is recommended to specify an email address that is valid and current.

If you have an email address in your user profile, you can use the Forgot Password link on the sign on page to have a temporary password sent to you.", "Rationale": "Having a valid and current email address associated with an OCI IAM local user account allows you to tie the account to identity in your organization. It also allows that user to reset their password if it is forgotten or lost.", "Impact": "", "Remediation": "Update the current email address in the email text box on exch non compliant user.", "Recommendation": "Add emails to users to allow them to use the 'Forgot Password' feature and uniquely identify the user. For service accounts it could be a mail alias.", - "Observation": "without an email."}, + "Observation": "user(s) without an email." + }, "1.13": { "Description": "OCI instances, OCI database and OCI functions can access other OCI resources either via an OCI API key associated to a user or by being including in a Dynamic Group that has an IAM policy granting it the required access. Access to OCI Resources refers to making API calls to another OCI resource like Object Storage, OCI Vaults, etc.", "Rationale": "Dynamic Groups reduces the risks related to hard coded credentials. Hard coded API keys can be shared and require rotation which can open them up to being compromised. Compromised credentials could allow access to OCI services outside of the expected radius.", "Impact": "For an OCI instance that contains embedded credential audit the scripts and environment variables to ensure that none of them contain OCI API Keys or credentials.", "Remediation": "Create Dynamic group and Enter Matching Rules to that includes the instances accessing your OCI resources. Refer:\"https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingdynamicgroups.htm\".", "Recommendation": "Evaluate how your instances, functions, and autonomous database interact with other OCI services.", - "Observation": "Dynamic Groups reduces the risks related to hard coded credentials. Hard coded API keys can be shared and require rotation which can open them up to being compromised. Compromised credentials could allow access to OCI services outside of the expected radius."}, + "Observation": "Dynamic Groups reduces the risks related to hard coded credentials. Hard coded API keys can be shared and require rotation which can open them up to being compromised. Compromised credentials could allow access to OCI services outside of the expected radius." + }, "1.14": { "Description": "To apply the separation of duties security principle, one can restrict service-level administrators from being able to delete resources they are managing. It means service-level administrators can only manage resources of a specific service but not delete resources for that specific service.

Example policies for global/tenant level for block volume service-administrators:\n
\nAllow group VolumeUsers to manage volumes in tenancy where request.permission!='VOLUME_DELETE'\nAllow group VolumeUsers to manage volume-backups in tenancy where request.permission!='VOLUME_BACKUP_DELETE'\n

Example policies for global/tenant level for file storage system service-administrators:
\nAllow group FileUsers to manage file-systems in tenancy where request.permission!='FILE_SYSTEM_DELETE'\nAllow group FileUsers to manage mount-targets in tenancy where request.permission!='MOUNT_TARGET_DELETE'\nAllow group FileUsers to manage export-sets in tenancy where request.permission!='EXPORT_SET_DELETE'\n


Example policies for global/tenant level for object storage system service-administrators:
\nAllow group BucketUsers to manage objects in tenancy where request.permission!='OBJECT_DELETE'\nAllow group BucketUsers to manage buckets in tenancy where request.permission!='BUCKET_DELETE'\n
", "Rationale": "Creating service-level administrators without the ability to delete the resource they are managing helps in tightly controlling access to Oracle Cloud Infrastructure (OCI) services by implementing the separation of duties security principle.", "Impact": "", "Remediation": "Add the appropriate where condition to any policy statement that allows the storage service-level to manage the storage service.", "Recommendation": "To apply a separation of duties security principle, it is recommended to restrict service-level administrators from being able to delete resources they are managing.", - "Observation": "IAM Policies that give service administrator the ability to delete service resources."}, + "Observation": "IAM Policies that give service administrator the ability to delete service resources." + }, "2.1": { "Description": "Security lists provide stateful or stateless filtering of ingress/egress network traffic to OCI resources on a subnet level. It is recommended that no security group allows unrestricted ingress access to port 22.", "Rationale": "Removing unfettered connectivity to remote console services, such as Secure Shell (SSH), reduces a server's exposure to risk.", "Impact": "For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.", "Remediation": "For each security list in the returned results, click the security list name. Either edit the ingress rule to be more restrictive, delete the ingress rule or click on the VCN and terminate the security list as appropriate.", "Recommendation": "Review the security lists. If they are not used(attached to a subnet) they should be deleted if possible or empty. For attached security lists it is recommended to restrict the CIDR block to only allow access to Port 22 from known networks.", - "Observation": "Security lists that allow internet access to port 22. (Note this does not necessarily mean external traffic can reach a compute instance)."}, + "Observation": "Security lists that allow internet access to port 22. (Note this does not necessarily mean external traffic can reach a compute instance)." + }, "2.2": { "Description": "Security lists provide stateful or stateless filtering of ingress/egress network traffic to OCI resources on a subnet level. It is recommended that no security group allows unrestricted ingress access to port 3389.", "Rationale": "Removing unfettered connectivity to remote console services, such as Remote Desktop Protocol (RDP), reduces a server's exposure to risk.", @@ -359,7 +376,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features but additional audit data will be retained.", "Remediation": "Go to the Tenancy Details page and edit Audit Retention Policy by setting AUDIT RETENTION PERIOD to 365.", "Recommendation": "", - "Observation": "" + "Observation": "Audit log retention is lower than 365 days." }, "3.2": { "Description": "Using default tags is a way to ensure all resources that support tags are tagged during creation. Tags can be based on static values or based on computed values. It is recommended to setup default tags early on to ensure all created resources will get tagged.\nTags are scoped to Compartments and are inherited by Child Compartments. The recommendation is to create default tags like “CreatedBy” at the Root Compartment level to ensure all resources get tagged.\nWhen using Tags it is important to ensure that Tag Namespaces are protected by IAM Policies otherwise this will allow users to change tags or tag values.\nDepending on the age of the OCI Tenancy there may already be Tag defaults setup at the Root Level and no need for further action to implement this action.", @@ -367,7 +384,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features", "Remediation": "Update the root compartments tag default link.In the Tag Defaults table verify that there is a Tag with a value of \"${iam.principal.names}\" and a Tag Key Status of Active. Also cretae a Tag key definition by providing a Tag Key, Description and selecting 'Static Value' for Tag Value Type.", "Recommendation": "", - "Observation": "" + "Observation": "default tags are used on resources." }, "3.3": { "Description": "Notifications provide a multi-channel messaging service that allow users and applications to be notified of events of interest occurring within OCI. Messages can be sent via eMail, HTTPs, PagerDuty, Slack or the OCI Function service. Some channels, such as eMail require confirmation of the subscription before it becomes active.", @@ -375,7 +392,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", "Remediation": "Create a Topic in the notifications service under the appropriate compartment and add the subscriptions with current email address and correct protocol.", "Recommendation": "", - "Observation": "" + "Observation": "notification topic and subscription for receiving monitoring alerts are configured." }, "3.4": { "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when Identity Providers are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments. It is recommended to create the Event rule at the root compartment level.", @@ -383,7 +400,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", "Remediation": "Create a Rule Condition in the Events services by selecting Identity in the Service Name Drop-down and selecting Identity Provider – Create, Identity Provider - Delete and Identity Provider – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.", "Recommendation": "", - "Observation": "" + "Observation": "notification has been configured for Identity Provider changes." }, "3.5": { "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when Identity Provider Group Mappings are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments. It is recommended to create the Event rule at the root compartment level", @@ -391,7 +408,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", "Remediation": "Find and click the Rule that handles Idp Group Mapping Changes. Click the Edit Rule button and verify that the RuleConditions section contains a condition for the Service Identity and Event Types: Idp Group Mapping – Create, Idp Group Mapping – Delete, and Idp Group Mapping – Update and confirm Action Type contains: Notifications and that a valid Topic is referenced.", "Recommendation": "", - "Observation": "" + "Observation": "notification has been configured for Identity Provider Group Mapping changes." }, "3.6": { "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when IAM Groups are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", @@ -399,7 +416,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", "Remediation": "Create a Rule Condition by selecting Identity in the Service Name Drop-down and selecting Group – Create, Group – Delete and Group – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.", "Recommendation": "", - "Observation": "" + "Observation": "notification has been configured for Identity Provider changes." }, "3.7": { "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when IAM Policies are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", @@ -407,7 +424,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", "Remediation": "Create a Rule Condition by selecting Identity in the Service Name Drop-down and selecting Policy – Change Compartment, Policy – Create, Policy - Delete and Policy – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.", "Recommendation": "", - "Observation": "" + "Observation": "notification has been configured for IAM Policy changes." }, "3.8": { "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when IAM Users are created, updated, deleted, capabilities updated, or state updated. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", @@ -415,7 +432,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", "Remediation": "Edit Rule that handles IAM User Changes and verify that the Rule Conditions section contains a condition for the Service Identity and Event Types: User – Create, User – Delete, User – Update, User Capabilities – Update, User State – Update.", "Recommendation": "", - "Observation": "" + "Observation": "notification has been configured for user changes." }, "3.9": { "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when Virtual Cloud Networks are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", @@ -423,7 +440,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", "Remediation": "Edit Rule that handles VCN Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: VCN – Create, VCN - Delete, and VCN – Update.", "Recommendation": "", - "Observation": "" + "Observation": "notification has been configured for VCN changes." }, "3.10": { "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when route tables are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", @@ -431,7 +448,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", "Remediation": "Edit Rule that handles Route Table Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Route Table – Change Compartment, Route Table – Create, Route Table - Delete, and Route Table – Update.", "Recommendation": "", - "Observation": "" + "Observation": "notification has been configured for changes to route tables." }, "3.11": { "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when security lists are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", @@ -439,15 +456,15 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", "Remediation": "Edit Rule that handles Security List Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Security List – Change Compartment, Security List – Create, Security List - Delete, and Security List – Update.", "Recommendation": "", - "Observation": "" + "Observation": "notification has been configured for security list changes." }, "3.12": { "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when network security groups are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", "Rationale": "Network Security Groups control traffic flowing between Virtual Network Cards attached to Compute instances.\n Monitoring and alerting on changes to Network Security Groups will help in identifying changes these security controls.", "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", - "Remediation": "Edit Rule that handles Network Security Group Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Network Security Group – Change Compartment, Network Security Group – Create, Network Security Group - Delete, and Network Security Group – Update.", + "Remediation": "Edit Rule that handles Network Security Group changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Network Security Group – Change Compartment, Network Security Group – Create, Network Security Group - Delete, and Network Security Group – Update.", "Recommendation": "", - "Observation": "" + "Observation": "notification has been configured for changes on Network Service Groups." }, "3.13": { "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when Network Gateways are created, updated, deleted, attached, detached, or moved. This recommendation includes Internet Gateways, Dynamic Routing Gateways, Service Gateways, Local Peering Gateways, and NAT Gateways. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", @@ -455,7 +472,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", "Remediation": "Edit Rule that handles Network Gateways Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: DRG – Create, DRG - Delete, DRG - Update, DRG Attachment – Create, DRG Attachment – Delete, DRG Attachment - Update, Internet Gateway – Create, Internet Gateway – Delete, Internet Gateway - Update, Internet Gateway – Change Compartment, Local Peering Gateway – Create, Local Peering Gateway – Delete End, Local Peering Gateway - Update, Local Peering Gateway – Change Compartment, NAT Gateway – Create, NAT Gateway – Delete, NAT Gateway - Update, NAT Gateway – Change Compartment,Compartment, Service Gateway – Create, Service Gateway – Delete Begin, Service Gateway – Delete End, Service Gateway – Update, Service Gateway – Attach Service, Service Gateway – Detach Service, Service Gateway – Change Compartment.", "Recommendation": "", - "Observation": "" + "Observation": "notification has been configured for changes on network gateways." }, "3.14": { "Description": "VCN flow logs record details about traffic that has been accepted or rejected based on the security list rule.", @@ -463,7 +480,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "Enabling VCN flow logs will not affect the performance of your virtual network but it will generate additional use of object storage that should be controlled via object lifecycle management.

By default, VCN flow logs are stored for 30 days in object storage. Users can specify a longer retention period.", "Remediation": "Enable Flow Logs (all records) on Virtual Cloud Networks (subnets) under the relevant resource compartment. Before hand create Log group if not exist in the Log services.", "Recommendation": "", - "Observation": "" + "Observation": "VCNs have no flow logging configured." }, "3.15": { "Description": "Cloud Guard detects misconfigured resources and insecure activity within a tenancy and provides security administrators with the visibility to resolve these issues. Upon detection, Cloud Guard can suggest, assist, or take corrective actions to mitigate these issues. Cloud Guard should be enabled in the root compartment of your tenancy with the default configuration, activity detectors and responders.", @@ -471,7 +488,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features, but additional IAM policies will be required.", "Remediation": "Enable the cloud guard by selecting the services in the menu and provide appropriate reporting region and other configurations.", "Recommendation": "", - "Observation": "" + "Observation": "Cloud Guard has not been configured in the root compartment of the tenancy." }, "3.16": { "Description": "Oracle Cloud Infrastructure Vault securely stores master encryption keys that protect your encrypted data. You can use the Vault service to rotate keys to generate new cryptographic material. Periodically rotating keys limits the amount of data encrypted by one key version.", @@ -479,7 +496,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "", "Remediation": "Select the security service and select vault. Ensure the date of each Master Encryption Key under the Created column of the Master Encryption key is no more than 365 days old.", "Recommendation": "", - "Observation": "" + "Observation": "customer-managed keys are older than one year." }, "3.17": { "Description": "Object Storage write logs will log all write requests made to objects in a bucket.", @@ -487,7 +504,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "There is no performance impact when enabling the above described features, but will generate additional use of object storage that should be controlled via object lifecycle management.

By default, Object Storage logs are stored for 30 days in object storage. Users can specify a longer retention period.", "Remediation": "To the relevant bucket enable log by providing Write Access Events from the Log Category. Beforehand create log group if required.", "Recommendation": "", - "Observation": "" + "Observation": "object stores have no write level logging enabled." }, "4.1.1": { "Description": "A bucket is a logical container for storing objects. It is associated with a single compartment that has policies that determine what action a user can perform on a bucket and on all the objects in the bucket. It is recommended that no bucket be publicly accessible.", @@ -495,7 +512,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "For updating an existing bucket, care should be taken to ensure objects in the bucket can be accessed through either IAM policies or pre-authenticated requests.", "Remediation": "Edit the visibility into 'private' for each Bucket.", "Recommendation": "", - "Observation": "" + "Observation": "object storage buckets are publicly visible." }, "4.1.2": { "Description": "Oracle Object Storage buckets support encryption with a Customer Managed Key (CMK). By default, Object Storage buckets are encrypted with an Oracle managed key.", @@ -503,7 +520,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize Object Storage service to use keys on your behalf.

Required Policy:\n
\nAllow service objectstorage-<region_name>, to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'

", "Remediation": "Assign Master encryption key to Encryption key in every Object storage under Bucket name by clicking assign and select vault.", "Recommendation": "", - "Observation": "" + "Observation": "object store buckets do not use Customer-Managed Keys (CMK)." }, "4.1.3": { "Description": "A bucket is a logical container for storing objects. Object versioning is enabled at the bucket level and is disabled by default upon creation. Versioning directs Object Storage to automatically create an object version each time a new object is uploaded, an existing object is overwritten, or when an object is deleted. You can enable object versioning at bucket creation time or later.", @@ -511,7 +528,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "", "Remediation": "Enable Versioning by clicking on every bucket by editing the bucket configuration.", "Recommendation": "", - "Observation": "" + "Observation": "object store buckets have no versioning enabled." }, "4.2.1": { "Description": "Oracle Cloud Infrastructure Block Volume service lets you dynamically provision and manage block storage volumes. By default, the Oracle service manages the keys that encrypt this block volume. Block Volumes can also be encrypted using a customer managed key.", @@ -519,7 +536,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize the Block Volume service to use the keys you create.\nRequired IAM Policy:\n
\nAllow service blockstorage to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'\n
", "Remediation": "For each block volumes from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.", "Recommendation": "", - "Observation": "" + "Observation": "block volumes are not encrypted with a Customer-Managed Key." }, "4.2.2": { "Description": "When you launch a virtual machine (VM) or bare metal instance based on a platform image or custom image, a new boot volume for the instance is created in the same compartment. That boot volume is associated with that instance until you terminate the instance. By default, the Oracle service manages the keys that encrypt this boot volume. Boot Volumes can also be encrypted using a customer managed key.", @@ -527,7 +544,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize the Boot Volume service to use the keys you create.\nRequired IAM Policy:\n
\nAllow service Bootstorage to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'\n
", "Remediation": "For each boot volumes from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.", "Recommendation": "", - "Observation": "" + "Observation": "boot volumes are not encrypted with a Customer-Managed Key." }, "4.3.1": { "Description": "Oracle Cloud Infrastructure File Storage service (FSS) provides a durable, scalable, secure, enterprise-grade network file system. By default, the Oracle service manages the keys that encrypt FSS file systems. FSS file systems can also be encrypted using a customer managed key.", @@ -535,7 +552,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize the File Storage service to use the keys you create.\nRequired IAM Policy:\n
\nAllow service FssOc1Prod to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'\n
", "Remediation": "For each file storage system from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.", "Recommendation": "", - "Observation": "" + "Observation": "file storage services (FSS) are not encrypted with a Customer-Managed Key." }, "5.1": { "Description": "When you sign up for Oracle Cloud Infrastructure, Oracle creates your tenancy, which is the root compartment that holds all your cloud resources. You then create additional compartments within the tenancy (root compartment) and corresponding policies to control access to the resources in each compartment.

Compartments allow you to organize and control access to your cloud resources. A compartment is a collection of related resources (such as instances, databases, virtual cloud networks, block volumes) that can be accessed only by certain groups that have been given permission by an administrator.", @@ -543,15 +560,15 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print "Impact": "Once the compartment is created an OCI IAM policy must be created to allow a group to resources in the compartment otherwise only group with tenancy access will have access.", "Remediation": "Create the new compartment under the root compartment.", "Recommendation": "", - "Observation": "" + "Observation": "Only the root compartment is used in the tenancy." }, "5.2": { "Description": "When you create a cloud resource such as an instance, block volume, or cloud network, you must specify to which compartment you want the resource to belong. Placing resources in the root compartment makes it difficult to organize and isolate those resources.", "Rationale": "Placing resources into a compartment will allow you to organize and have more granular access controls to your cloud resources.", "Impact": "Placing a resource in a compartment will impact how you write policies to manage access and organize that resource.", - "Remediation": "For each item in the returned results,select Move Resource or More Actions then Move Resource and select compartment except root and choose new then move resources.", + "Remediation": "For each item in the returned results, select Move Resource or More Actions then Move Resource and select compartment except root and choose new then move resources.", "Recommendation": "", - "Observation": "" + "Observation": "resources are created in the root compartment." } } @@ -564,7 +581,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print 'SIEM_Write_Bucket_Logs': {'Status': None, 'Findings': [], 'OBP': [], "Documentation": "https://docs.oracle.com/en/solutions/oci-aggregate-logs-siem/index.html"}, 'SIEM_Read_Bucket_Logs': {'Status': None, 'Findings': [], 'OBP': [], "Documentation": "https://docs.oracle.com/en/solutions/oci-aggregate-logs-siem/index.html"}, 'Networking_Connectivity': {'Status': True, 'Findings': [], 'OBP': [], "Documentation": "https://docs.oracle.com/en-us/iaas/Content/Network/Troubleshoot/drgredundancy.htm"}, - 'Cloud_Guard_Config': {'Status': None, 'Findings': [], 'OBP': [], "Documentation": ""}, + 'Cloud_Guard_Config': {'Status': None, 'Findings': [], 'OBP': [], "Documentation": "https://www.ateam-oracle.com/post/tuning-oracle-cloud-guard"}, } # MAP Regional Data self.__obp_regional_checks = {} @@ -774,6 +791,10 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print # Error Data self.__errors = [] + # All Resources + self.__all_resources_json = {} + + # Setting list of regions to run in # Start print time info @@ -900,12 +921,20 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print # Determining if CSV report OCIDs will be redacted self.__redact_output = redact_output + # Determine if All resource from Search service should be queried + self.__all_resources = all_resources + if all_resources: + self.__all_resources = all_resources + self.__obp_checks = True + self.__output_raw_data = True + ########################################################################## # Create regional config, signers adds appends them to self.__regions object ########################################################################## def __create_regional_signers(self, proxy): print("Creating regional signers and configs...") for region_key, region_values in self.__regions.items(): + debug("processing __create_regional_signers") # Creating regional configs and signers region_signer = self.__signer region_signer.region_name = region_key @@ -914,6 +943,7 @@ def __create_regional_signers(self, proxy): try: identity = oci.identity.IdentityClient(region_config, signer=region_signer) + debug("__create_regional_signers: reading config data " + str(self.__config)) if proxy: identity.base_client.session.proxies = {'https': proxy} region_values['identity_client'] = identity @@ -993,7 +1023,15 @@ def __create_regional_signers(self, proxy): sch.base_client.session.proxies = {'https': proxy} region_values['sch_client'] = sch + topology = oci.core.VirtualNetworkClient(region_config, signer=region_signer) + if proxy: + topology.base_client.session.proxies = {'https': proxy} + topology.base_client.endpoint = f"https://vnca-api.{region_key}.oci.oraclecloud.com" + region_values['topology_client'] = topology + except Exception as e: + debug("__create_regional_signers: error reading" + str(self.__config)) + self.__errors.append({"id" : "__create_regional_signers", "error" : str(e)}) raise RuntimeError("Failed to create regional clients for data collection: " + str(e)) ########################################################################## @@ -1017,6 +1055,7 @@ def __set_managed_paas_compartment(self): def __identity_read_compartments(self): print("\nProcessing Compartments...") try: + debug("__identity_read_compartments: Processing Compartments:") self.__compartments = oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['identity_client'].list_compartments, compartment_id=self.__tenancy.id, @@ -1026,6 +1065,7 @@ def __identity_read_compartments(self): # Need to convert for raw output for compartment in self.__compartments: + debug("__identity_read_compartments: Getting Compartments: " + compartment.name) deep_link = self.__oci_compartment_uri + compartment.id record = { 'id': compartment.id, @@ -1070,6 +1110,8 @@ def __identity_read_compartments(self): return self.__compartments except Exception as e: + debug("__identity_read_compartments: Error Getting Compartments: " + compartment.name) + self.__errors.append({"id" : "__identity_read_compartments", "error" : str(e)}) raise RuntimeError( "Error in identity_read_compartments: " + str(e.args)) @@ -1082,7 +1124,7 @@ def __identity_read_domains(self): # Finding all Identity Domains in the tenancy for compartment in self.__compartments: try: - debug("__identity_read_domains: Getting Identity Domains for Compartment :" + str(compartment.name)) + debug("__identity_read_domains: Getting Identity Domains for Compartment: " + str(compartment.name)) raw_identity_domains += oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['identity_client'].list_domains, @@ -1093,7 +1135,7 @@ def __identity_read_domains(self): self.__identity_domains_enabled = True except Exception as e: - debug("__identity_read_domains: Exception collecting Identity Domains \n" + str(e)) + debug("__identity_read_domains: Exception collecting Identity Domains\n" + str(e)) # If this fails the tenancy likely doesn't have identity domains or the permissions are off break @@ -1103,7 +1145,7 @@ def __identity_read_domains(self): return self.__identity_domains_enabled for domain in raw_identity_domains: - debug("__identity_read_domains: Getting passowrd policy for domain: " + domain.display_name) + debug("__identity_read_domains: Getting password policy for domain: " + domain.display_name) domain_dict = oci.util.to_dict(domain) try: debug("__identity_read_domains: Getting Identity Domain Password Policy") @@ -1135,12 +1177,14 @@ def __identity_read_domains(self): def __identity_read_groups_and_membership(self): try: # Getting all Groups in the Tenancy + debug("processing __identity_read_groups_and_membership") groups_data = oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['identity_client'].list_groups, compartment_id=self.__tenancy.id ).data # For each group in the tenacy getting the group's membership for grp in groups_data: + debug("__identity_read_groups_and_membership: reading group data " + str(grp.name)) membership = oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['identity_client'].list_user_group_memberships, compartment_id=self.__tenancy.id, @@ -1162,6 +1206,7 @@ def __identity_read_groups_and_membership(self): self.__groups_to_users.append(group_record) # For groups with members print one record per user per group for member in membership: + debug("__identity_read_groups_and_membership: reading members data in group " + str(grp.name)) user_deep_link = self.__oci_users_uri + member.user_id group_record = { "id": grp.id, @@ -1177,6 +1222,8 @@ def __identity_read_groups_and_membership(self): self.__groups_to_users.append(group_record) return self.__groups_to_users except Exception as e: + self.__errors.append({"id" : "__identity_read_groups_and_membership", "error" : str(e)}) + debug("__identity_read_groups_and_membership: error reading " + str(e)) RuntimeError( "Error in __identity_read_groups_and_membership" + str(e.args)) @@ -1343,6 +1390,7 @@ def __identity_read_user_customer_secret_key(self, user_ocid): ########################################################################## def __identity_read_tenancy_policies(self): try: + debug("__identity_read_tenancy_policies: Getting Tenancy policies: ") policies_data = oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( @@ -1350,6 +1398,7 @@ def __identity_read_tenancy_policies(self): ).data for policy in policies_data: + debug("__identity_read_tenancy_policies: Reading Tenancy policies: " + policy.display_name) deep_link = self.__oci_policies_uri + policy.identifier record = { "id": policy.identifier, @@ -1365,6 +1414,8 @@ def __identity_read_tenancy_policies(self): return self.__policies except Exception as e: + debug("__identity_read_tenancy_policies: Exception reading Tenancy policies: " + policy.display_name) + self.__errors.append({"id" : "__identity_read_tenancy_policies", "error" : str(e)}) raise RuntimeError("Error in __identity_read_tenancy_policies: " + str(e.args)) ############################################ @@ -1372,12 +1423,14 @@ def __identity_read_tenancy_policies(self): ############################################ def __identity_read_dynamic_groups(self): try: + debug("processing __identity_read_dynamic_groups") dynamic_groups_data = oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['identity_client'].list_dynamic_groups, compartment_id=self.__tenancy.id).data for dynamic_group in dynamic_groups_data: deep_link = self.__oci_dynamic_groups_uri + dynamic_group.id # try: + debug("__identity_read_dynamic_groups: reading dynamic groups " + str(dynamic_group.name)) record = { "id": dynamic_group.id, "name": dynamic_group.name, @@ -1412,6 +1465,8 @@ def __identity_read_dynamic_groups(self): print("\tProcessed " + str(len(self.__dynamic_groups)) + " Dynamic Groups") return self.__dynamic_groups except Exception as e: + self.__errors.append({"id" : "__identity_read_dynamic_groups", "error" : str(e)}) + debug("__identity_read_dynamic_groups: error reading" + str(e)) raise RuntimeError("Error in __identity_read_dynamic_groups: " + str(e.args)) pass @@ -1420,7 +1475,9 @@ def __identity_read_dynamic_groups(self): ############################################ def __identity_read_availability_domains(self): try: + debug("__identity_read_availability_domains: Getting Availability Domains for regions:") for region_key, region_values in self.__regions.items(): + debug("__identity_read_availability_domains: reading Availability Domains for regions: " +region_key) region_values['availability_domains'] = oci.pagination.list_call_get_all_results( region_values['identity_client'].list_availability_domains, compartment_id=self.__tenancy.id @@ -1428,6 +1485,8 @@ def __identity_read_availability_domains(self): print("\tProcessed " + str(len(region_values['availability_domains'])) + " Availability Domains in " + region_key) except Exception as e: + debug("__identity_read_availability_domains: reading availability domain " + str(region_key)) + self.__errors.append({"id": "__identity_read_availability_domains" + "_" + str(region_key), "error": str(e)}) raise RuntimeError( "Error in __identity_read_availability_domains: " + str(e.args)) @@ -2296,6 +2355,42 @@ def __network_read_ip_sec_connections(self): except Exception as e: raise RuntimeError( "Error in __network_read_ip_sec_connections " + str(e.args)) + + ############################################ + # Collect Network Topology Data + ############################################ + def __network_topology_dump(self): + debug("__network_topology_dump: Starting") + self.__network_topology_json = {} + + def api_function(region_key, region_values, tenancy_id): + try: + get_vcn_topology_response = region_values['topology_client'].get_networking_topology( + compartment_id=tenancy_id, + access_level="ACCESSIBLE", + query_compartment_subtree=True) + debug("__network_topology_dump: Successful queried network topology for region: " + region_key) + + except Exception as e: + if "(-1, null, false)" in e.message: + + return None #This error is benign. The API shows an error when there is no topology data to pull. + debug("__network_topology_dump: ERROR querying network topology for region: " + region_key) + self.__errors.append({"id" : region_key + "_network_topology_dump", "error" : str(e) }) + print(e) + else: + self.__network_topology_json[region_key]=get_vcn_topology_response.data + print(f"\tProcessed {region_key} Network Topology") + + # Parallelize API Calls. See https://github.com/oracle/oci-python-sdk/blob/master/examples/parallel_api_collection.py + + thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=10) + + for region_key, region_values in self.__regions.items(): + thread_pool.submit(api_function, region_key, region_values, self.__tenancy.id) + + thread_pool.shutdown(wait=True) + ############################################ # Load Autonomous Databases @@ -3014,6 +3109,7 @@ def __cloud_guard_read_cloud_guard_configuration(self): except Exception: self.__cloud_guard_config_status = 'DISABLED' + self.__errors.append({"id" : "__cloud_guard_read_cloud_guard_configuration", "error" : "*** Cloud Guard service requires a PayGo account ***"}) print("*** Cloud Guard service requires a PayGo account ***") ########################################################################## @@ -3278,13 +3374,17 @@ def __search_resources_in_root_compartment(self): for item in structured_search_all_resources: # ignoring global resources like IAM - if item.identifier.split('.')[3]: - record = { - "display_name": item.display_name, - "id": item.identifier, - "region": region_key - } - self.cis_foundations_benchmark_1_2['5.2']['Total'].append(item) + try: + if item.identifier.split('.')[3]: + record = { + "display_name": item.display_name, + "id": item.identifier, + "region": region_key + } + self.cis_foundations_benchmark_1_2['5.2']['Total'].append(item) + except: + self.__errors.append({"id": "search_resources_in_root_compartment Invalid OCID ", "error" : str(item)}) + debug(f'__search_resources_in_root_compartment: Invalid OCID: {str(item)}') except Exception as e: raise RuntimeError( @@ -3293,6 +3393,47 @@ def __search_resources_in_root_compartment(self): print("\tProcessed " + str(len(self.__resources_in_root_compartment)) + " resources in the root compartment") return self.__resources_in_root_compartment + ########################################################################## + # All Resources in Tenancy + ########################################################################## + def __search_resources_all_resources_in_tenancy(self): + + # This function runs gets a resource and it's additional fields + def search_query_resource_type(resource_type, search_client): + try: + query = f"query {resource_type} resources return allAdditionalFields" + results = oci.pagination.list_call_get_all_results( + search_client.search_resources, + search_details=oci.resource_search.models.StructuredSearchDetails( + query=query) + ).data + + return oci.util.to_dict(results) + except Exception as e: + return [] + + for region_key, region_values in self.__regions.items(): + self.__all_resources_json[region_key] = {} + try: + all_regional_resources = oci.pagination.list_call_get_all_results( + region_values['search_client'].list_resource_types).data + # self.__all_resources_json[region_key] = all_regional_resources + for item in all_regional_resources: + if not(item.name in self.__all_resources_json[region_key]): + self.__all_resources_json[region_key][item.name] = [] + + for type in self.__all_resources_json[region_key]: + self.__all_resources_json[region_key][type] += search_query_resource_type(type, region_values['search_client']) + + except Exception as e: + raise RuntimeError( + "Error in __search_resources_all_resources_in_tenancy " + str(e.args)) + + print("\tProcessed " + str(len(self.__all_resources_json)) + " resources in the tenancy") + # print(self.__all_resources_json) + return self.__all_resources_json + + ########################################################################## # Analyzes Tenancy Data for CIS Report ########################################################################## @@ -3518,17 +3659,17 @@ def __report_cis_analyze_tenancy_data(self): clean_where_clause = split_statement[1].upper().replace(" ", "").replace("'", "") if all(permission.upper() in clean_where_clause for permission in self.cis_iam_checks['1.14'][resource]) and \ not(all(permission.upper() in clean_where_clause for permission in self.cis_iam_checks['1.14-storage-admin'][resource])): - debug("__report_cis_analyze_tenancy_data no permissions to delete storage : " + str(policy['name'])) + debug("__report_cis_analyze_tenancy_data no permissions to delete storage: " + str(policy['name'])) pass # Checking if this is the Storage admin with allowed elif all(permission.upper() in clean_where_clause for permission in self.cis_iam_checks['1.14-storage-admin'][resource]) and \ not(all(permission.upper() in clean_where_clause for permission in self.cis_iam_checks['1.14'][resource])): - debug("__report_cis_analyze_tenancy_data storage admin policy is : " + str(policy['name'])) + debug("__report_cis_analyze_tenancy_data storage admin policy is: " + str(policy['name'])) pass else: self.cis_foundations_benchmark_1_2['1.14']['Findings'].append(policy) - debug("__report_cis_analyze_tenancy_data else policy is /n: " + str(policy['name'])) + debug("__report_cis_analyze_tenancy_data else policy is: " + str(policy['name'])) else: self.cis_foundations_benchmark_1_2['1.14']['Findings'].append(policy) @@ -4391,16 +4532,20 @@ def __report_generate_cis_report(self, level): # Generating Summary report CSV print_header("Writing CIS reports to CSV") + summary_files = [] summary_file_name = self.__print_to_csv_file( self.__report_directory, "cis", "summary_report", summary_report) + summary_files.append(summary_file_name) - self.__report_generate_html_summary_report( + summary_file_name = self.__report_generate_html_summary_report( self.__report_directory, "cis", "html_summary_report", summary_report) + summary_files.append(summary_file_name) - # Outputting to a bucket if I have one - if summary_file_name and self.__output_bucket: - self.__os_copy_report_to_object_storage( - self.__output_bucket, summary_file_name) + # Outputing to a bucket if I have one + if summary_files and self.__output_bucket: + for summary_file in summary_files: + self.__os_copy_report_to_object_storage( + self.__output_bucket, summary_file) for key, recommendation in self.cis_foundations_benchmark_1_2.items(): if recommendation['Level'] <= level: @@ -4420,8 +4565,7 @@ def __report_generate_html_summary_report(self, report_directory, header, file_s os.mkdir(report_directory) except Exception as e: - raise Exception( - "Error in creating report directory: " + str(e.args)) + raise Exception("Error in creating report directory: " + str(e.args)) try: # if no data @@ -4462,7 +4606,7 @@ def __report_generate_html_summary_report(self, report_directory, header, file_s with open(file_path, mode='w') as html_file: # Creating table header html_file.write('') - html_file.write('' + html_title + '') + html_file.write(f'{html_title}') html_file.write(""" @@ -4490,12 +4634,12 @@ def __report_generate_html_summary_report(self, report_directory, header, file_s .u30brandw1{display:flex;flex-direction:row;color:#fff;text-decoration:none;align-items:center} @media (max-width:1024px){.u30brand{padding:0 24px}} #u30skip2,#u30skip2content{transform:translateY(-100%);position:fixed} .rtl #u30{direction:rtl} #td_override { background: #fff; border-bottom: 1px solid rgba(122,115,110,0.2) !important }
""") - html_file.write('

' + html_title.replace('-', '–') + '

') - html_file.write('

Tenancy Name: ' + self.__tenancy.name + '

') + html_file.write(f'

{html_title.replace("-", "–")}

') + html_file.write(f'

Tenancy Name: {self.__tenancy.name}

') # Get the extract date r = result[0] extract_date = r['extract_date'].replace('T',' ') - html_file.write('
Extract Date: ' + extract_date + ' UTC
') + html_file.write(f'
Extract Date: {extract_date} UTC
') html_file.write("
") # Navigation html_file.write('
') @@ -4527,47 +4671,48 @@ def __report_generate_html_summary_report(self, report_directory, header, file_s column_width = '12%' else: column_width = '63%' - html_file.write('' + th + '') + html_file.write(f'{th}') html_file.write('') # Creating HTML Table of the summary report html_appendix = [] for row in result: compliant = row['Compliant'] text_color = 'green' - if compliant == 'No': + if compliant != 'Yes': continue # Print the row html_file.write("") v = row['Recommendation #'] if compliant == 'No': - html_file.write('' + v + '\n') + html_file.write(f'{v}\n') else: - html_file.write('' + v + '\n') + html_file.write(f'{v}\n') total = row['Total'] tmp = '' if total != ' ': - tmp = '

' + str(total) + ' item' + tmp = f'

{str(total)} item' if int(total) > 1: tmp += 's' - html_file.write('' + str(compliant) + '' + tmp + '\n') - html_file.write("" + str(row['Section']) + "\n") + html_file.write(f'{str(compliant)}{tmp}\n') + html_file.write(f"{str(row['Section'])}\n") # Details html_file.write('') - html_file.write('') + html_file.write(f'') html_file.write('') - html_file.write('') + html_file.write(f'') html_file.write('') html_file.write('') html_file.write('') html_file.write('') - html_file.write('') - html_file.write('') - html_file.write('') + html_file.write(f'') + cis_v8 = str(row["CIS v8"]).replace("[","").replace("]","").replace("'","") + html_file.write(f'') + html_file.write(f'') v = str(row['Filename']) if v == ' ': html_file.write('') else: - html_file.write('') + html_file.write(f'') html_file.write('
Title' + str(row['Title']) + '
{str(row["Title"])}
Remediation' + str(row['Remediation']) + '
{str(row["Remediation"])}
LevelCIS v8CCCS Guard RailFile
' + str(row['Level']) + '' + str(row['CIS v8']).replace('[','').replace(']','').replace("'",'') + '' + str(row['CCCS Guard Rail']) + '
{str(row["Level"])}{cis_v8}{str(row["CCCS Guard Rail"])} ' + v + '{v}
') html_file.write("") @@ -4595,7 +4740,7 @@ def __report_generate_html_summary_report(self, report_directory, header, file_s column_width = '12%' else: column_width = '63%' - html_file.write('' + th + '') + html_file.write(f'{th}') html_file.write('') # Creating HTML Table of the summary report html_appendix = [] @@ -4609,35 +4754,36 @@ def __report_generate_html_summary_report(self, report_directory, header, file_s html_file.write("") v = row['Recommendation #'] if compliant == 'No': - html_file.write('' + v + '\n') + html_file.write(f'{v}\n') else: - html_file.write('' + v + '\n') + html_file.write(f'{v}\n') f = row['Findings'] t = row['Total'] tmp = '' if t != ' ': - tmp = '

' + str(f) + ' of ' + str(t) + ' item' + tmp = f'

{str(f)} of {str(t)} item' if int(t) > 1: tmp += 's' - html_file.write('' + str(compliant) + '' + tmp + '\n') - html_file.write("" + str(row['Section']) + "\n") + html_file.write(f'{str(compliant)}{tmp}\n') + html_file.write(f'{str(row["Section"])}\n') # Details html_file.write('') - html_file.write('') + html_file.write(f'') html_file.write('') - html_file.write('') + html_file.write(f'') html_file.write('') html_file.write('') html_file.write('') html_file.write('') - html_file.write('') - html_file.write('') - html_file.write('') + html_file.write(f'') + cis_v8 = str(row["CIS v8"]).replace("[","").replace("]","").replace("'","") + html_file.write(f'') + html_file.write(f'') v = str(row['Filename']) if v == ' ': html_file.write('') else: - html_file.write('') + html_file.write(f'') html_file.write('
Title' + str(row['Title']) + '
{str(row["Title"])}
Remediation' + str(row['Remediation']) + '
{str(row["Remediation"])}
LevelCIS v8CCCS Guard RailFile
' + str(row['Level']) + '' + str(row['CIS v8']).replace('[','').replace(']','').replace("'",'') + '' + str(row['CCCS Guard Rail']) + '
{str(row["Level"])}{cis_v8}{str(row["CCCS Guard Rail"])} ' + v + '{v}
') html_file.write("") @@ -4653,7 +4799,16 @@ def __report_generate_html_summary_report(self, report_directory, header, file_s if item_value != "": html_file.write(f"
{item_key.title()}
") if item_key == 'Observation': - html_file.write(f"

{str(len(fing['Findings']))} of {str(len(fing['Total']))} {item_value}

\n") + if fing['Status'] == None: + pfx = 'Manually check for' + else: + num_findings = len(fing['Findings']) + num_total = len(fing['Total']) + if num_findings > 0 or num_total > 0: + pfx = f'{str(num_findings)} of {str(num_total)}' + else: + pfx = 'No' + html_file.write(f"

{pfx} {item_value}

\n") else: v = item_value.replace('
', '
')
                                 html_file.write(f"

{v}

\n") @@ -4815,17 +4970,27 @@ def __collect_tenancy_data(self): self.__network_read_drgs, self.__network_read_drg_attachments, self.__sch_read_service_connectors, + self.__network_topology_dump ] else: obp_functions = [] + # All OCI Resources via Search Service + + if self.__all_resources: + all_resources = [ + self.__search_resources_all_resources_in_tenancy, + ] + else: + all_resources = [] + def execute_function(func): func() with concurrent.futures.ThreadPoolExecutor(max_workers=6) as executor: # Submit each function to the executor futures = [] - for func in cis_regional_functions + obp_functions: + for func in cis_regional_functions + obp_functions + all_resources: futures.append(executor.submit(execute_function, func)) # Wait for all functions to complete @@ -4959,6 +5124,18 @@ def __report_generate_raw_data_output(self): self.__report_directory, "raw_data", "network_drg_attachments", list(itertools.chain.from_iterable(self.__network_drg_attachments.values()))) list_report_file_names.append(report_file_name) + report_file_name = self.__print_to_json_file( + self.__report_directory, "raw_data", "all_resources", self.__all_resources_json) + list_report_file_names.append(report_file_name) + + report_file_name = self.__print_to_json_file( + self.__report_directory, "raw_data", "oci_network_topologies", oci.util.to_dict(self.__network_topology_json)) + list_report_file_names.append(report_file_name) + + report_file_name = self.__print_to_pkl_file( + self.__report_directory, "raw_data", "oci_network_topologies", self.__network_topology_json) + list_report_file_names.append(report_file_name) + if self.__output_bucket: for raw_report in list_report_file_names: if raw_report: @@ -5050,6 +5227,94 @@ def __print_to_csv_file(self, report_directory, header, file_subject, data): except Exception as e: raise Exception("Error in print_to_csv_file: " + str(e.args)) + ########################################################################## + # Print to JSON + ########################################################################## + def __print_to_json_file(self, report_directory, header, file_subject, data): + try: + # Creating report directory + if not os.path.isdir(report_directory): + os.mkdir(report_directory) + + except Exception as e: + raise Exception( + "Error in creating report directory: " + str(e.args)) + + try: + # if no data + if len(data) == 0: + return None + + # get the file name of the CSV + + file_name = header + "_" + file_subject + file_name = (file_name.replace(" ", "_") + ).replace(".", "-").replace("_-_","_") + ".json" + file_path = os.path.join(report_directory, file_name) + + # Serializing JSON to string + json_object = json.dumps(data, indent=4) + + # If this flag is set all OCIDs are Hashed to redact them + if self.__redact_output: + items_to_redact = re.findall(self.__oci_ocid_pattern,json_object) + for redact_me in items_to_redact: + json_object = json_object.replace(redact_me,hashlib.sha256(str.encode(redact_me)).hexdigest() ) + + + # Writing to json file + with open(file_path, mode='w', newline='') as json_file: + json_file.write(json_object) + + print("JSON: " + file_subject.ljust(22) + " --> " + file_path) + + # Used by Upload + return file_path + + except Exception as e: + raise Exception("Error in print_to_json_file: " + str(e.args)) + + ########################################################################## + # Print to PKL + ########################################################################## + def __print_to_pkl_file(self, report_directory, header, file_subject, data): + try: + # Creating report directory + if not os.path.isdir(report_directory): + os.mkdir(report_directory) + + except Exception as e: + raise Exception( + "Error in creating report directory: " + str(e.args)) + + try: + # if no data + if len(data) == 0: + return None + + # get the file name of the CSV + + file_name = header + "_" + file_subject + file_name = (file_name.replace(" ", "_") + ).replace(".", "-").replace("_-_","_") + ".pkl" + file_path = os.path.join(report_directory, file_name) + + # Writing to json file + with open(file_path, 'wb') as pkl_file: + pickle.dump(data,pkl_file) + + + print("PKL: " + file_subject.ljust(22) + " --> " + file_path) + + # Used by Upload + return file_path + + + except Exception as e: + raise Exception("Error in __print_to_pkl_file: " + str(e.args)) + + + ########################################################################## # Orchestrates Data collection and reports ########################################################################## @@ -5278,8 +5543,10 @@ def execute_report(): help='Outputs all resource data into CSV files') parser.add_argument('--obp', action='store_true', default=False, help='Checks for OCI best practices') + parser.add_argument('--all-resources', action='store_true', default=False, + help='Uses Advanced Search Service to query all resources in the tenancy and outputs to a JSON. This also enables OCI Best Practice Checks (--obp) and All resource to csv (--raw) flags.') parser.add_argument('--redact_output', action='store_true', default=False, - help='Redacts OCIDs in output CSV files') + help='Redacts OCIDs in output CSV and JSON files') parser.add_argument('-ip', action='store_true', default=False, dest='is_instance_principals', help='Use Instance Principals for Authentication ') parser.add_argument('-dt', action='store_true', default=False, @@ -5299,7 +5566,7 @@ def execute_report(): config, signer = create_signer(cmd.file_location, cmd.config_profile, cmd.is_instance_principals, cmd.is_delegation_token, cmd.is_security_token) config['retry_strategy'] = oci.retry.DEFAULT_RETRY_STRATEGY report = CIS_Report(config, signer, cmd.proxy, cmd.output_bucket, cmd.report_directory, cmd.print_to_screen, \ - cmd.regions, cmd.raw, cmd.obp, cmd.redact_output, debug=cmd.debug) + cmd.regions, cmd.raw, cmd.obp, cmd.redact_output, debug=cmd.debug, all_resources=cmd.all_resources) csv_report_directory = report.generate_reports(int(cmd.level)) try: diff --git a/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/standard.sh b/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/standard.sh index c687d9b8c..1777d2617 100644 --- a/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/standard.sh +++ b/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/standard.sh @@ -1,13 +1,13 @@ #!/bin/bash ############################################################################### -# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. # This software is dual-licensed to you under the Universal Permissive License # (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl. ############################################################################### # # Author: Olaf Heimburger # -VERSION=230922 +VERSION=240130 ASSESS_DIR=`dirname $0` if [ ${ASSESS_DIR} == "." ]; then diff --git a/security/security-design/shared-assets/oci-security-health-check-standard/files/resources/cis_html_summary_report.html b/security/security-design/shared-assets/oci-security-health-check-standard/files/resources/cis_html_summary_report.html new file mode 100644 index 000000000..7f6570bac --- /dev/null +++ b/security/security-design/shared-assets/oci-security-health-check-standard/files/resources/cis_html_summary_report.html @@ -0,0 +1,422 @@ +CIS OCI Foundations Benchmark 1.2 - Compliance Report + + + + + + + + + + + + + + + + + + +
+ +

CIS OCI Foundations Benchmark 1.2 – Compliance Report

Tenancy Name: example

Extract Date: 2024-01-30 14:34:27 UTC

Compliant Recommendations

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Recommendation #CompliantSectionDetails
1.4YesIdentity and Access Management
TitleEnsure IAM password policy requires minimum length of 14 or greater
RemediationUpdate the password policy such as minimum length to 14, password must contain expected special characters and numeric characters.
LevelCIS v8CCCS Guard RailFile
14.1, 5.22,3
1.7Yes

6 items
Identity and Access Management
TitleEnsure MFA is enabled for all users with a console password
RemediationEach user must enable MFA for themselves using a device they will have access to every time they sign in. An administrator cannot enable MFA for another user but can enforce MFA by identifying the list of non-complaint users, notifying them or disabling access by resetting password for non-complaint accounts.
LevelCIS v8CCCS Guard RailFile
16.3, 6.51,2,3,4
1.9YesIdentity and Access Management
TitleEnsure user customer secret keys rotate within 90 days or less
RemediationDelete any Access Keys with a date of 90 days or older under the Created column of the Customer Secret Keys.
LevelCIS v8CCCS Guard RailFile
14.1, 5.26,7
1.11Yes

1 item
Identity and Access Management
TitleEnsure API keys are not created for tenancy administrator users
RemediationFor each tenancy administrator user who has an API key,select API Keys from the menu and delete any associated keys from the API Keys table.
LevelCIS v8CCCS Guard RailFile
15.46,7
1.13Yes

6 items
Identity and Access Management
TitleEnsure Dynamic Groups are used for OCI instances, OCI Cloud Databases and OCI Function to access OCI resources
RemediationCreate Dynamic group and Enter Matching Rules to that includes the instances accessing your OCI resources. Refer:"https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingdynamicgroups.htm".
LevelCIS v8CCCS Guard RailFile
16.86,7
2.2Yes

12 items
Networking
TitleEnsure no security lists allow ingress from 0.0.0.0/0 to port 3389.
RemediationFor each security list in the returned results, click the security list name. Either edit the ingress rule to be more restrictive, delete the ingress rule or click on the VCN and terminate the security list as appropriate.
LevelCIS v8CCCS Guard RailFile
14.4, 12.32,3,5,7,9
2.3Yes

3 items
Networking
TitleEnsure no network security groups allow ingress from 0.0.0.0/0 to port 22.
RemediationUsing the details returned from the audit procedure either Remove the security rules or Update the security rules.
LevelCIS v8CCCS Guard RailFile
14.4, 12.32,3,5,7,9
2.4Yes

3 items
Networking
TitleEnsure no network security groups allow ingress from 0.0.0.0/0 to port 3389.
RemediationUsing the details returned from the audit procedure either Remove the security rules or Update the security rules.
LevelCIS v8CCCS Guard RailFile
14.4, 12.32,3,5,7,9
2.6YesNetworking
TitleEnsure Oracle Integration Cloud (OIC) access is restricted to allowed sources.
RemediationFor each OIC instance in the returned results, select the OIC Instance name,edit the Network Access to be more restrictive.
LevelCIS v8CCCS Guard RailFile
14.4, 12.32,3,5,7,9
2.7YesNetworking
TitleEnsure Oracle Analytics Cloud (OAC) access is restricted to allowed sources or deployed within a Virtual Cloud Network.
RemediationFor each OAC instance in the returned results, select the OAC Instance name edit the Access Control Rules by clicking +Another Rule and add rules as required.
LevelCIS v8CCCS Guard RailFile
14.4, 12.32,3,5,7,9
3.5YesLogging and Monitoring
TitleEnsure a notification is configured for IdP group mapping changes.
RemediationFind and click the Rule that handles Idp Group Mapping Changes. Click the Edit Rule button and verify that the RuleConditions section contains a condition for the Service Identity and Event Types: Idp Group Mapping – Create, Idp Group Mapping – Delete, and Idp Group Mapping – Update and confirm Action Type contains: Notifications and that a valid Topic is referenced.
LevelCIS v8CCCS Guard RailFile
14.211
3.15YesLogging and Monitoring
TitleEnsure Cloud Guard is enabled in the root compartment of the tenancy.
RemediationEnable the cloud guard by selecting the services in the menu and provide appropriate reporting region and other configurations.
LevelCIS v8CCCS Guard RailFile
18.2, 8.5, 8.111,2,3
4.1.1Yes

3 items
Storage - Object Storage
TitleEnsure no Object Storage buckets are publicly visible.
RemediationEdit the visibility into 'private' for each Bucket.
LevelCIS v8CCCS Guard RailFile
13.3
4.2.1YesStorage - Block Volumes
TitleEnsure Block Volumes are encrypted with Customer-Managed Keys.
RemediationFor each block volumes from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.
LevelCIS v8CCCS Guard RailFile
23.11
5.1Yes

20 items
Asset Management
TitleCreate at least one compartment in your tenancy to store cloud resources.
RemediationCreate the new compartment under the root compartment.
LevelCIS v8CCCS Guard RailFile
13.12,3,8,12
5.2Yes

53 items
Asset Management
TitleEnsure no resources are created in the root compartment.
RemediationFor each item in the returned results, select Move Resource or More Actions then Move Resource and select compartment except root and choose new then move resources.
LevelCIS v8CCCS Guard RailFile
13.121,2,3
+

Non-compliant Recommendations

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Recommendation #CompliantSectionDetails
1.1No

2 of 37 items
Identity and Access Management
TitleEnsure service level admins are created to manage resources of particular service
RemediationRefer to the policy syntax document and create new policies if the audit results indicate that the required policies are missing.
LevelCIS v8CCCS Guard RailFile
15.4, 6.72,3cis_Identity_and_Access_Management_1-1.csv
1.2No

1 of 37 items
Identity and Access Management
TitleEnsure permissions on all resources are given only to the tenancy administrator group
RemediationRemove any policy statement that allows any group other than Administrators or any service access to manage all resources in the tenancy.
LevelCIS v8CCCS Guard RailFile
13.31,2,3cis_Identity_and_Access_Management_1-2.csv
1.3No

1 of 37 items
Identity and Access Management
TitleEnsure IAM administrators cannot update tenancy Administrators group
RemediationVerify the results to ensure that the policy statements that grant access to use or manage users or groups in the tenancy have a condition that excludes access to Administrators group or to users in the Administrators group.
LevelCIS v8CCCS Guard RailFile
13.3, 5.42,3cis_Identity_and_Access_Management_1-3.csv
1.5N/AIdentity and Access Management
TitleEnsure IAM password policy expires passwords within 365 days
RemediationUpdate the password policy by setting number of days configured in Expires after to 365.
LevelCIS v8CCCS Guard RailFile
14.1, 5.22,3
1.6N/AIdentity and Access Management
TitleEnsure IAM password policy prevents password reuse
RemediationUpdate the number of remembered passwords in previous passwords remembered setting to 24 in the password policy.
LevelCIS v8CCCS Guard RailFile
15.22,3
1.8No

2 of 3 items
Identity and Access Management
TitleEnsure user API keys rotate within 90 days or less
RemediationDelete any API Keys with a date of 90 days or older under the Created column of the API Key table.
LevelCIS v8CCCS Guard RailFile
14.1, 4.46,7cis_Identity_and_Access_Management_1-8.csv
1.10No

1 of 1 item
Identity and Access Management
TitleEnsure user auth tokens rotate within 90 days or less
RemediationDelete any auth token with a date of 90 days or older under the Created column of the Auth Tokens.
LevelCIS v8CCCS Guard RailFile
14.1, 5.26,7cis_Identity_and_Access_Management_1-10.csv
1.12No

1 of 6 items
Identity and Access Management
TitleEnsure all OCI IAM user accounts have a valid and current email address
RemediationUpdate the current email address in the email text box on exch non compliant user.
LevelCIS v8CCCS Guard RailFile
15.11,2,3cis_Identity_and_Access_Management_1-12.csv
1.14No

3 of 37 items
Identity and Access Management
TitleEnsure storage service-level admins cannot delete resources they manage
RemediationAdd the appropriate where condition to any policy statement that allows the storage service-level to manage the storage service.
LevelCIS v8CCCS Guard RailFile
25.4, 6.82,3cis_Identity_and_Access_Management_1-14.csv
2.1No

6 of 12 items
Networking
TitleEnsure no security lists allow ingress from 0.0.0.0/0 to port 22.
RemediationFor each security list in the returned results, click the security list name. Either edit the ingress rule to be more restrictive, delete the ingress rule or click on the VCN and terminate the security list as appropriate.
LevelCIS v8CCCS Guard RailFile
14.4, 12.32,3,5,7,9cis_Networking_2-1.csv
2.5No

6 of 6 items
Networking
TitleEnsure the default security list of every VCN restricts all traffic except ICMP.
RemediationSelect Default Security List for and Remove the Ingress Rule with Source 0.0.0.0/0, IP Protocol 22 and Destination Port Range 22.
LevelCIS v8CCCS Guard RailFile
112.32,3,5,7,9cis_Networking_2-5.csv
2.8No

1 of 1 item
Networking
TitleEnsure Oracle Autonomous Shared Database (ADB) access is restricted or deployed within a VCN.
RemediationFor each ADB-S database in the returned results, select the ADB-S database name edit the Access Control Rules by clicking +Another Rule and add rules as required.
LevelCIS v8CCCS Guard RailFile
14.4, 12.32,3,5,7,9cis_Networking_2-8.csv
3.1NoLogging and Monitoring
TitleEnsure audit log retention period is set to 365 days.
RemediationGo to the Tenancy Details page and edit Audit Retention Policy by setting AUDIT RETENTION PERIOD to 365.
LevelCIS v8CCCS Guard RailFile
18.1011
3.2NoLogging and Monitoring
TitleEnsure default tags are used on resources.
RemediationUpdate the root compartments tag default link.In the Tag Defaults table verify that there is a Tag with a value of "${iam.principal.names}" and a Tag Key Status of Active. Also cretae a Tag key definition by providing a Tag Key, Description and selecting 'Static Value' for Tag Value Type.
LevelCIS v8CCCS Guard RailFile
11.1
3.3NoLogging and Monitoring
TitleCreate at least one notification topic and subscription to receive monitoring alerts.
RemediationCreate a Topic in the notifications service under the appropriate compartment and add the subscriptions with current email address and correct protocol.
LevelCIS v8CCCS Guard RailFile
18.2, 8.1111
3.4NoLogging and Monitoring
TitleEnsure a notification is configured for Identity Provider changes.
RemediationCreate a Rule Condition in the Events services by selecting Identity in the Service Name Drop-down and selecting Identity Provider – Create, Identity Provider - Delete and Identity Provider – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.
LevelCIS v8CCCS Guard RailFile
14.211
3.6NoLogging and Monitoring
TitleEnsure a notification is configured for IAM group changes.
RemediationCreate a Rule Condition by selecting Identity in the Service Name Drop-down and selecting Group – Create, Group – Delete and Group – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.
LevelCIS v8CCCS Guard RailFile
14.211
3.7NoLogging and Monitoring
TitleEnsure a notification is configured for IAM policy changes.
RemediationCreate a Rule Condition by selecting Identity in the Service Name Drop-down and selecting Policy – Change Compartment, Policy – Create, Policy - Delete and Policy – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.
LevelCIS v8CCCS Guard RailFile
14.211
3.8NoLogging and Monitoring
TitleEnsure a notification is configured for user changes.
RemediationEdit Rule that handles IAM User Changes and verify that the Rule Conditions section contains a condition for the Service Identity and Event Types: User – Create, User – Delete, User – Update, User Capabilities – Update, User State – Update.
LevelCIS v8CCCS Guard RailFile
14.211
3.9NoLogging and Monitoring
TitleEnsure a notification is configured for VCN changes.
RemediationEdit Rule that handles VCN Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: VCN – Create, VCN - Delete, and VCN – Update.
LevelCIS v8CCCS Guard RailFile
14.211
3.10NoLogging and Monitoring
TitleEnsure a notification is configured for changes to route tables.
RemediationEdit Rule that handles Route Table Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Route Table – Change Compartment, Route Table – Create, Route Table - Delete, and Route Table – Update.
LevelCIS v8CCCS Guard RailFile
14.211
3.11NoLogging and Monitoring
TitleEnsure a notification is configured for security list changes.
RemediationEdit Rule that handles Security List Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Security List – Change Compartment, Security List – Create, Security List - Delete, and Security List – Update.
LevelCIS v8CCCS Guard RailFile
14.211
3.12NoLogging and Monitoring
TitleEnsure a notification is configured for network security group changes.
RemediationEdit Rule that handles Network Security Group changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Network Security Group – Change Compartment, Network Security Group – Create, Network Security Group - Delete, and Network Security Group – Update.
LevelCIS v8CCCS Guard RailFile
14.211
3.13NoLogging and Monitoring
TitleEnsure a notification is configured for changes to network gateways.
RemediationEdit Rule that handles Network Gateways Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: DRG – Create, DRG - Delete, DRG - Update, DRG Attachment – Create, DRG Attachment – Delete, DRG Attachment - Update, Internet Gateway – Create, Internet Gateway – Delete, Internet Gateway - Update, Internet Gateway – Change Compartment, Local Peering Gateway – Create, Local Peering Gateway – Delete End, Local Peering Gateway - Update, Local Peering Gateway – Change Compartment, NAT Gateway – Create, NAT Gateway – Delete, NAT Gateway - Update, NAT Gateway – Change Compartment,Compartment, Service Gateway – Create, Service Gateway – Delete Begin, Service Gateway – Delete End, Service Gateway – Update, Service Gateway – Attach Service, Service Gateway – Detach Service, Service Gateway – Change Compartment.
LevelCIS v8CCCS Guard RailFile
14.211
3.14No

12 of 13 items
Logging and Monitoring
TitleEnsure VCN flow logging is enabled for all subnets.
RemediationEnable Flow Logs (all records) on Virtual Cloud Networks (subnets) under the relevant resource compartment. Before hand create Log group if not exist in the Log services.
LevelCIS v8CCCS Guard RailFile
28.2, 8.5, 13.6cis_Logging_and_Monitoring_3-14.csv
3.16No

5 of 8 items
Logging and Monitoring
TitleEnsure customer created Customer Managed Key (CMK) is rotated at least annually.
RemediationSelect the security service and select vault. Ensure the date of each Master Encryption Key under the Created column of the Master Encryption key is no more than 365 days old.
LevelCIS v8CCCS Guard RailFile
16,7cis_Logging_and_Monitoring_3-16.csv
3.17No

3 of 3 items
Logging and Monitoring
TitleEnsure write level Object Storage logging is enabled for all buckets.
RemediationTo the relevant bucket enable log by providing Write Access Events from the Log Category. Beforehand create log group if required.
LevelCIS v8CCCS Guard RailFile
28.2cis_Logging_and_Monitoring_3-17.csv
4.1.2No

3 of 3 items
Storage - Object Storage
TitleEnsure Object Storage Buckets are encrypted with a Customer-Managed Key (CMK).
RemediationAssign Master encryption key to Encryption key in every Object storage under Bucket name by clicking assign and select vault.
LevelCIS v8CCCS Guard RailFile
23.11cis_Storage_Object_Storage_4-1-2.csv
4.1.3No

3 of 3 items
Storage - Object Storage
TitleEnsure Versioning is Enabled for Object Storage Buckets.
RemediationEnable Versioning by clicking on every bucket by editing the bucket configuration.
LevelCIS v8CCCS Guard RailFile
23.11cis_Storage_Object_Storage_4-1-3.csv
4.2.2No

2 of 2 items
Storage - Block Volumes
TitleEnsure Boot Volumes are encrypted with Customer-Managed Key.
RemediationFor each boot volumes from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.
LevelCIS v8CCCS Guard RailFile
23.11cis_Storage_Block_Volumes_4-2-2.csv
4.3.1No

1 of 1 item
Storage - File Storage Service
TitleEnsure File Storage Systems are encrypted with Customer-Managed Keys.
RemediationFor each file storage system from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.
LevelCIS v8CCCS Guard RailFile
23.11cis_Storage_File_Storage_Service_4-3-1.csv
+

Details for non-compliant Recommendations


1.1 – Ensure service level admins are created to manage resources of particular service

+
Description

To apply least-privilege security principle, one can create service-level administrators in corresponding groups and assigning specific users to each service-level administrative group in a tenancy. This limits administrative access in a tenancy.

It means service-level administrators can only manage resources of a specific service.

Example policies for global/tenant level service-administrators +

+Allow group VolumeAdmins to manage volume-family in tenancy
+Allow group ComputeAdmins to manage instance-family in tenancy
+Allow group NetworkAdmins to manage virtual-network-family in tenancy
+
+Organizations have various ways of defining service-administrators. Some may prefer creating service administrators at a tenant level and some per department or per project or even per application environment (dev/test/production etc.). Either approach works so long as the policies are written to limit access given to the service-administrators.

Example policies for compartment level service-administrators

Allow group NonProdComputeAdmins to manage instance-family in compartment dev
+Allow group ProdComputeAdmins to manage instance-family in compartment production
+Allow group A-Admins to manage instance-family in compartment Project-A
+Allow group A-Admins to manage volume-family in compartment Project-A
+

+
Rationale

Creating service-level administrators helps in tightly controlling access to Oracle Cloud Infrastructure (OCI) services to implement the least-privileged security principle.

+
Remediation

Refer to the policy syntax document and create new policies if the audit results indicate that the required policies are missing.

+
Observation

2 of 37 custom IAM policy that grants tenancy administrative access.

+

1.2 – Ensure permissions on all resources are given only to the tenancy administrator group

+
Description

There is a built-in OCI IAM policy enabling the Administrators group to perform any action within a tenancy. In the OCI IAM console, this policy reads:

+Allow group Administrators to manage all-resources in tenancy
+


Administrators create more users, groups, and policies to provide appropriate access to other groups.

Administrators should not allow any-other-group full access to the tenancy by writing a policy like this:

+Allow group any-other-group to manage all-resources in tenancy
+


The access should be narrowed down to ensure the least-privileged principle is applied.

+
Rationale

Permission to manage all resources in a tenancy should be limited to a small number of users in the 'Administrators' group for break-glass situations and to set up users/groups/policies when a tenancy is created.

No group other than 'Administrators' in a tenancy should need access to all resources in a tenancy, as this violates the enforcement of the least privilege principle.

+
Remediation

Remove any policy statement that allows any group other than Administrators or any service access to manage all resources in the tenancy.

+
Recommendation

Evaluate if tenancy-wide administrative access is needed for the identified policy and update it to be more restrictive.

+
Observation

1 of 37 custom IAM policy that grants tenancy administrative access.

+

1.3 – Ensure IAM administrators cannot update tenancy Administrators group

+
Description

Tenancy administrators can create more users, groups, and policies to provide other service administrators access to OCI resources.

For example, an IAM administrator will need to have access to manage + resources like compartments, users, groups, dynamic-groups, policies, identity-providers, tenancy tag-namespaces, tag-definitions in the tenancy.

The policy that gives IAM-Administrators or any other group full access to 'groups' resources should not allow access to the tenancy 'Administrators' group.

The policy statements would look like:

+Allow group IAMAdmins to inspect users in tenancy
+Allow group IAMAdmins to use users in tenancy where target.group.name != 'Administrators'
+Allow group IAMAdmins to inspect groups in tenancy
+Allow group IAMAdmins to use groups in tenancy where target.group.name != 'Administrators'
+


Note: You must include separate statements for 'inspect' access, because the target.group.name variable is not used by the ListUsers and ListGroups operations

+
Rationale

These policy statements ensure that no other group can manage tenancy administrator users or the membership to the 'Administrators' group thereby gain or remove tenancy administrator access.

+
Remediation

Verify the results to ensure that the policy statements that grant access to use or manage users or groups in the tenancy have a condition that excludes access to Administrators group or to users in the Administrators group.

+
Recommendation

Evaluate if tenancy-wide administrative access is needed for the identified policy and update it to be more restrictive.

+
Observation

1 of 37 custom IAM policy that grants tenancy administrative access.

+

1.5 – Ensure IAM password policy expires passwords within 365 days

+
Description

IAM password policies can require passwords to be rotated or expired after a given number of days. It is recommended that the password policy expire passwords after 365 and are changed immediately based on events.

+
Rationale

Excessive password expiration requirements do more harm than good, because these requirements make users select predictable passwords, composed of sequential words and numbers that are closely related to each other. In these cases, the next password can be predicted based on the previous one (incrementing a number used in the password for example). Also, password expiration requirements offer no containment benefits because attackers will often use credentials as soon as they compromise them. Instead, immediate password changes should be based on key events including, but not limited to:

1. Indication of compromise
2. Change of user roles
3. When a user leaves the organization.

Not only does changing passwords every few weeks or months frustrate the user, it's been suggested that it does more harm than good, because it could lead to bad practices by the user such as adding a character to the end of their existing password.

In addition, we also recommend a yearly password change. This is primarily because for all their good intentions users will share credentials across accounts. Therefore, even if a breach is publicly identified, the user may not see this notification, or forget they have an account on that site. This could leave a shared credential vulnerable indefinitely. Having an organizational policy of a 1-year (annual) password expiration is a reasonable compromise to mitigate this with minimal user burden.

+
Remediation

Update the password policy by setting number of days configured in Expires after to 365.

+
Recommendation

Evaluate password rotation policies are inline with your organizational standard.

+
Observation

Manually check for password policy/policies that do require rotation.

+

1.6 – Ensure IAM password policy prevents password reuse

+
Description

IAM password policies can prevent the reuse of a given password by the same user. It is recommended the password policy prevent the reuse of passwords.

+
Rationale

Enforcing password history ensures that passwords are not reused in for a certain period of time by the same user. If a user is not allowed to use last 24 passwords, that window of time is greater. This helps maintain the effectiveness of password security.

+
Remediation

Update the number of remembered passwords in previous passwords remembered setting to 24 in the password policy.

+
Recommendation

Evaluate password reuse policies are inline with your organizational standard.

+
Observation

Manually check for password policy/policies that do prevent reuse.

+

1.8 – Ensure user API keys rotate within 90 days or less

+
Description

API keys are used by administrators, developers, services and scripts for accessing OCI APIs directly or via SDKs/OCI CLI to search, create, update or delete OCI resources.

The API key is an RSA key pair. The private key is used for signing the API requests and the public key is associated with a local or synchronized user's profile.

+
Rationale

It is important to secure and rotate an API key every 90 days or less as it provides the same level of access that a user it is associated with has.

In addition to a security engineering best practice, this is also a compliance requirement. For example, PCI-DSS Section 3.6.4 states, "Verify that key-management procedures include a defined cryptoperiod for each key type in use and define a process for key changes at the end of the defined crypto period(s)."

+
Remediation

Delete any API Keys with a date of 90 days or older under the Created column of the API Key table.

+
Recommendation

Evaluate if APIs Keys are still used/required and rotate API Keys It is important to secure and rotate an API key every 90 days or less as it provides the same level of access that a user it is associated with has.

+
Observation

2 of 3 user(s) with APIs that have not been rotated with 90 days.

+

1.10 – Ensure user auth tokens rotate within 90 days or less

+
Description

Auth tokens are authentication tokens generated by Oracle. You use auth tokens to authenticate with APIs that do not support the Oracle Cloud Infrastructure signature-based authentication. If the service requires an auth token, the service-specific documentation instructs you to generate one and how to use it.

+
Rationale

It is important to secure and rotate an auth token every 90 days or less as it provides the same level of access to APIs that do not support the OCI signature-based authentication as the user associated to it.

+
Remediation

Delete any auth token with a date of 90 days or older under the Created column of the Auth Tokens.

+
Recommendation

Evaluate if Auth Tokens are still used/required and rotate Auth tokens.

+
Observation

1 of 1 user(s) with auth tokens that have not been rotated in 90 days.

+

1.12 – Ensure all OCI IAM user accounts have a valid and current email address

+
Description

All OCI IAM local user accounts have an email address field associated with the account. It is recommended to specify an email address that is valid and current.

If you have an email address in your user profile, you can use the Forgot Password link on the sign on page to have a temporary password sent to you.

+
Rationale

Having a valid and current email address associated with an OCI IAM local user account allows you to tie the account to identity in your organization. It also allows that user to reset their password if it is forgotten or lost.

+
Remediation

Update the current email address in the email text box on exch non compliant user.

+
Recommendation

Add emails to users to allow them to use the 'Forgot Password' feature and uniquely identify the user. For service accounts it could be a mail alias.

+
Observation

1 of 6 user(s) without an email.

+

1.14 – Ensure storage service-level admins cannot delete resources they manage

+
Description

To apply the separation of duties security principle, one can restrict service-level administrators from being able to delete resources they are managing. It means service-level administrators can only manage resources of a specific service but not delete resources for that specific service.

Example policies for global/tenant level for block volume service-administrators: +

+Allow group VolumeUsers to manage volumes in tenancy where request.permission!='VOLUME_DELETE'
+Allow group VolumeUsers to manage volume-backups in tenancy where request.permission!='VOLUME_BACKUP_DELETE'
+

Example policies for global/tenant level for file storage system service-administrators:
+Allow group FileUsers to manage file-systems in tenancy where request.permission!='FILE_SYSTEM_DELETE'
+Allow group FileUsers to manage mount-targets in tenancy where request.permission!='MOUNT_TARGET_DELETE'
+Allow group FileUsers to manage export-sets in tenancy where request.permission!='EXPORT_SET_DELETE'
+


Example policies for global/tenant level for object storage system service-administrators:
+Allow group BucketUsers to manage objects in tenancy where request.permission!='OBJECT_DELETE'
+Allow group BucketUsers to manage buckets in tenancy where request.permission!='BUCKET_DELETE'
+

+
Rationale

Creating service-level administrators without the ability to delete the resource they are managing helps in tightly controlling access to Oracle Cloud Infrastructure (OCI) services by implementing the separation of duties security principle.

+
Remediation

Add the appropriate where condition to any policy statement that allows the storage service-level to manage the storage service.

+
Recommendation

To apply a separation of duties security principle, it is recommended to restrict service-level administrators from being able to delete resources they are managing.

+
Observation

3 of 37 IAM Policies that give service administrator the ability to delete service resources.

+

2.1 – Ensure no security lists allow ingress from 0.0.0.0/0 to port 22.

+
Description

Security lists provide stateful or stateless filtering of ingress/egress network traffic to OCI resources on a subnet level. It is recommended that no security group allows unrestricted ingress access to port 22.

+
Rationale

Removing unfettered connectivity to remote console services, such as Secure Shell (SSH), reduces a server's exposure to risk.

+
Impact

For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.

+
Remediation

For each security list in the returned results, click the security list name. Either edit the ingress rule to be more restrictive, delete the ingress rule or click on the VCN and terminate the security list as appropriate.

+
Recommendation

Review the security lists. If they are not used(attached to a subnet) they should be deleted if possible or empty. For attached security lists it is recommended to restrict the CIDR block to only allow access to Port 22 from known networks.

+
Observation

6 of 12 Security lists that allow internet access to port 22. (Note this does not necessarily mean external traffic can reach a compute instance).

+

2.5 – Ensure the default security list of every VCN restricts all traffic except ICMP.

+
Description

A default security list is created when a Virtual Cloud Network (VCN) is created. Security lists provide stateful filtering of ingress and egress network traffic to OCI resources. It is recommended no security list allows unrestricted ingress access to Secure Shell (SSH) via port 22.

+
Rationale

Removing unfettered connectivity to remote console services, such as SSH on port 22, reduces a server's exposure to unauthorized access.

+
Impact

For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another security group.

+
Remediation

Select Default Security List for and Remove the Ingress Rule with Source 0.0.0.0/0, IP Protocol 22 and Destination Port Range 22.

+
Recommendation

Create specific custom security lists with workload specific rules and attach to subnets.

+
Observation

6 of 6 Default Security lists that allow more traffic then ICMP.

+

2.8 – Ensure Oracle Autonomous Shared Database (ADB) access is restricted or deployed within a VCN.

+
Description

Oracle Autonomous Database Shared (ADB-S) automates database tuning, security, backups, updates, and other routine management tasks traditionally performed by DBAs. ADB-S provide ingress filtering of network traffic or can be deployed within an existing Virtual Cloud Network (VCN). It is recommended that all new ADB-S databases be deployed within a VCN and that the Access Control Rules are restricted to your corporate IP Addresses or VCNs for existing ADB-S databases.

+
Rationale

Restricting connectivity to ADB-S Databases reduces an ADB-S database's exposure to risk.

+
Impact

When updating ingress filters for an existing environment, care should be taken to ensure that IP addresses and VCNs currently used by administrators, users, and services to access your ADB-S instances are included in the updated filters.

+
Remediation

For each ADB-S database in the returned results, select the ADB-S database name edit the Access Control Rules by clicking +Another Rule and add rules as required.

+
Recommendation

It is recommended that all new ADB-S databases be deployed within a VCN and that the Access Control Rules are restricted to your corporate IP Addresses or VCNs for existing ADB-S databases.

+
Observation

1 of 1 ADB-S Instances that allow unfiltered public ingress traffic (Authentication and authorization is still required).

+

3.1 – Ensure audit log retention period is set to 365 days.

+
Description

Ensuring audit logs are kept for 365 days.

+
Rationale

Log retention controls how long activity logs should be retained. Studies have shown that The Mean Time to Detect (MTTD) a cyber breach is anywhere from 30 days in some sectors to up to 206 days in others. Retaining logs for at least 365 days or more will provide the ability to respond to incidents.

+
Impact

There is no performance impact when enabling the above described features but additional audit data will be retained.

+
Remediation

Go to the Tenancy Details page and edit Audit Retention Policy by setting AUDIT RETENTION PERIOD to 365.

+
Observation

No Audit log retention is lower than 365 days.

+

3.2 – Ensure default tags are used on resources.

+
Description

Using default tags is a way to ensure all resources that support tags are tagged during creation. Tags can be based on static values or based on computed values. It is recommended to setup default tags early on to ensure all created resources will get tagged. +Tags are scoped to Compartments and are inherited by Child Compartments. The recommendation is to create default tags like “CreatedBy” at the Root Compartment level to ensure all resources get tagged. +When using Tags it is important to ensure that Tag Namespaces are protected by IAM Policies otherwise this will allow users to change tags or tag values. +Depending on the age of the OCI Tenancy there may already be Tag defaults setup at the Root Level and no need for further action to implement this action.

+
Rationale

In the case of an incident having default tags like “CreatedBy” applied will provide info on who created the resource without having to search the Audit logs.

+
Impact

There is no performance impact when enabling the above described features

+
Remediation

Update the root compartments tag default link.In the Tag Defaults table verify that there is a Tag with a value of "${iam.principal.names}" and a Tag Key Status of Active. Also cretae a Tag key definition by providing a Tag Key, Description and selecting 'Static Value' for Tag Value Type.

+
Observation

No default tags are used on resources.

+

3.3 – Create at least one notification topic and subscription to receive monitoring alerts.

+
Description

Notifications provide a multi-channel messaging service that allow users and applications to be notified of events of interest occurring within OCI. Messages can be sent via eMail, HTTPs, PagerDuty, Slack or the OCI Function service. Some channels, such as eMail require confirmation of the subscription before it becomes active.

+
Rationale

Creating one or more notification topics allow administrators to be notified of relevant changes made to OCI infrastructure.

+
Impact

There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.

+
Remediation

Create a Topic in the notifications service under the appropriate compartment and add the subscriptions with current email address and correct protocol.

+
Observation

No notification topic and subscription for receiving monitoring alerts are configured.

+

3.4 – Ensure a notification is configured for Identity Provider changes.

+
Description

It is recommended to setup an Event Rule and Notification that gets triggered when Identity Providers are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments. It is recommended to create the Event rule at the root compartment level.

+
Rationale

OCI Identity Providers allow management of User ID / passwords in external systems and use of those credentials to access OCI resources. Identity Providers allow users to single sign-on to OCI console and have other OCI credentials like API Keys. +Monitoring and alerting on changes to Identity Providers will help in identifying changes to the security posture.

+
Impact

There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.

+
Remediation

Create a Rule Condition in the Events services by selecting Identity in the Service Name Drop-down and selecting Identity Provider – Create, Identity Provider - Delete and Identity Provider – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.

+
Observation

No notification has been configured for Identity Provider changes.

+

3.6 – Ensure a notification is configured for IAM group changes.

+
Description

It is recommended to setup an Event Rule and Notification that gets triggered when IAM Groups are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.

+
Rationale

IAM Groups control access to all resources within an OCI Tenancy. + Monitoring and alerting on changes to IAM Groups will help in identifying changes to satisfy least privilege principle.

+
Impact

There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.

+
Remediation

Create a Rule Condition by selecting Identity in the Service Name Drop-down and selecting Group – Create, Group – Delete and Group – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.

+
Observation

No notification has been configured for Identity Provider changes.

+

3.7 – Ensure a notification is configured for IAM policy changes.

+
Description

It is recommended to setup an Event Rule and Notification that gets triggered when IAM Policies are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.

+
Rationale

IAM Policies govern access to all resources within an OCI Tenancy. + Monitoring and alerting on changes to IAM policies will help in identifying changes to the security posture.

+
Impact

There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.

+
Remediation

Create a Rule Condition by selecting Identity in the Service Name Drop-down and selecting Policy – Change Compartment, Policy – Create, Policy - Delete and Policy – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.

+
Observation

No notification has been configured for IAM Policy changes.

+

3.8 – Ensure a notification is configured for user changes.

+
Description

It is recommended to setup an Event Rule and Notification that gets triggered when IAM Users are created, updated, deleted, capabilities updated, or state updated. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.

+
Rationale

Users use or manage Oracle Cloud Infrastructure resources. + Monitoring and alerting on changes to Users will help in identifying changes to the security posture.

+
Impact

There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.

+
Remediation

Edit Rule that handles IAM User Changes and verify that the Rule Conditions section contains a condition for the Service Identity and Event Types: User – Create, User – Delete, User – Update, User Capabilities – Update, User State – Update.

+
Observation

No notification has been configured for user changes.

+

3.9 – Ensure a notification is configured for VCN changes.

+
Description

It is recommended to setup an Event Rule and Notification that gets triggered when Virtual Cloud Networks are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.

+
Rationale

Virtual Cloud Networks (VCNs) closely resembles a traditional network. + Monitoring and alerting on changes to VCNs will help in identifying changes to the security posture.

+
Impact

There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.

+
Remediation

Edit Rule that handles VCN Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: VCN – Create, VCN - Delete, and VCN – Update.

+
Observation

No notification has been configured for VCN changes.

+

3.10 – Ensure a notification is configured for changes to route tables.

+
Description

It is recommended to setup an Event Rule and Notification that gets triggered when route tables are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.

+
Rationale

Route tables control traffic flowing to or from Virtual Cloud Networks and Subnets. + Monitoring and alerting on changes to route tables will help in identifying changes these traffic flows.

+
Impact

There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.

+
Remediation

Edit Rule that handles Route Table Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Route Table – Change Compartment, Route Table – Create, Route Table - Delete, and Route Table – Update.

+
Observation

No notification has been configured for changes to route tables.

+

3.11 – Ensure a notification is configured for security list changes.

+
Description

It is recommended to setup an Event Rule and Notification that gets triggered when security lists are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.

+
Rationale

Security Lists control traffic flowing into and out of Subnets within a Virtual Cloud Network. + Monitoring and alerting on changes to Security Lists will help in identifying changes to these security controls.

+
Impact

There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.

+
Remediation

Edit Rule that handles Security List Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Security List – Change Compartment, Security List – Create, Security List - Delete, and Security List – Update.

+
Observation

No notification has been configured for security list changes.

+

3.12 – Ensure a notification is configured for network security group changes.

+
Description

It is recommended to setup an Event Rule and Notification that gets triggered when network security groups are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.

+
Rationale

Network Security Groups control traffic flowing between Virtual Network Cards attached to Compute instances. + Monitoring and alerting on changes to Network Security Groups will help in identifying changes these security controls.

+
Impact

There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.

+
Remediation

Edit Rule that handles Network Security Group changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Network Security Group – Change Compartment, Network Security Group – Create, Network Security Group - Delete, and Network Security Group – Update.

+
Observation

No notification has been configured for changes on Network Service Groups.

+

3.13 – Ensure a notification is configured for changes to network gateways.

+
Description

It is recommended to setup an Event Rule and Notification that gets triggered when Network Gateways are created, updated, deleted, attached, detached, or moved. This recommendation includes Internet Gateways, Dynamic Routing Gateways, Service Gateways, Local Peering Gateways, and NAT Gateways. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.

+
Rationale

Network Gateways act as routers between VCNs and the Internet, Oracle Services Networks, other VCNS, and on-premise networks. + Monitoring and alerting on changes to Network Gateways will help in identifying changes to the security posture.

+
Impact

There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.

+
Remediation

Edit Rule that handles Network Gateways Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: DRG – Create, DRG - Delete, DRG - Update, DRG Attachment – Create, DRG Attachment – Delete, DRG Attachment - Update, Internet Gateway – Create, Internet Gateway – Delete, Internet Gateway - Update, Internet Gateway – Change Compartment, Local Peering Gateway – Create, Local Peering Gateway – Delete End, Local Peering Gateway - Update, Local Peering Gateway – Change Compartment, NAT Gateway – Create, NAT Gateway – Delete, NAT Gateway - Update, NAT Gateway – Change Compartment,Compartment, Service Gateway – Create, Service Gateway – Delete Begin, Service Gateway – Delete End, Service Gateway – Update, Service Gateway – Attach Service, Service Gateway – Detach Service, Service Gateway – Change Compartment.

+
Observation

No notification has been configured for changes on network gateways.

+

3.14 – Ensure VCN flow logging is enabled for all subnets.

+
Description

VCN flow logs record details about traffic that has been accepted or rejected based on the security list rule.

+
Rationale

Enabling VCN flow logs enables you to monitor traffic flowing within your virtual network and can be used to detect anomalous traffic.

+
Impact

Enabling VCN flow logs will not affect the performance of your virtual network but it will generate additional use of object storage that should be controlled via object lifecycle management.

By default, VCN flow logs are stored for 30 days in object storage. Users can specify a longer retention period.

+
Remediation

Enable Flow Logs (all records) on Virtual Cloud Networks (subnets) under the relevant resource compartment. Before hand create Log group if not exist in the Log services.

+
Observation

12 of 13 VCNs have no flow logging configured.

+

3.16 – Ensure customer created Customer Managed Key (CMK) is rotated at least annually.

+
Description

Oracle Cloud Infrastructure Vault securely stores master encryption keys that protect your encrypted data. You can use the Vault service to rotate keys to generate new cryptographic material. Periodically rotating keys limits the amount of data encrypted by one key version.

+
Rationale

Rotating keys annually limits the data encrypted under one key version. Key rotation thereby reduces the risk in case a key is ever compromised.

+
Remediation

Select the security service and select vault. Ensure the date of each Master Encryption Key under the Created column of the Master Encryption key is no more than 365 days old.

+
Observation

5 of 8 customer-managed keys are older than one year.

+

3.17 – Ensure write level Object Storage logging is enabled for all buckets.

+
Description

Object Storage write logs will log all write requests made to objects in a bucket.

+
Rationale

Enabling an Object Storage write log, the 'requestAction' property would contain values of 'PUT', 'POST', or 'DELETE'. This will provide you more visibility into changes to objects in your buckets.

+
Impact

There is no performance impact when enabling the above described features, but will generate additional use of object storage that should be controlled via object lifecycle management.

By default, Object Storage logs are stored for 30 days in object storage. Users can specify a longer retention period.

+
Remediation

To the relevant bucket enable log by providing Write Access Events from the Log Category. Beforehand create log group if required.

+
Observation

3 of 3 object stores have no write level logging enabled.

+

4.1.2 – Ensure Object Storage Buckets are encrypted with a Customer-Managed Key (CMK).

+
Description

Oracle Object Storage buckets support encryption with a Customer Managed Key (CMK). By default, Object Storage buckets are encrypted with an Oracle managed key.

+
Rationale

Encryption of Object Storage buckets with a Customer Managed Key (CMK) provides an additional level of security on your data by allowing you to manage your own encryption key lifecycle management for the bucket.

+
Impact

Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize Object Storage service to use keys on your behalf.

Required Policy: +

+Allow service objectstorage-<region_name>, to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'

+
Remediation

Assign Master encryption key to Encryption key in every Object storage under Bucket name by clicking assign and select vault.

+
Observation

3 of 3 object store buckets do not use Customer-Managed Keys (CMK).

+

4.1.3 – Ensure Versioning is Enabled for Object Storage Buckets.

+
Description

A bucket is a logical container for storing objects. Object versioning is enabled at the bucket level and is disabled by default upon creation. Versioning directs Object Storage to automatically create an object version each time a new object is uploaded, an existing object is overwritten, or when an object is deleted. You can enable object versioning at bucket creation time or later.

+
Rationale

Versioning object storage buckets provides for additional integrity of your data. Management of data integrity is critical to protecting and accessing protected data. Some customers want to identify object storage buckets without versioning in order to apply their own data lifecycle protection and management policy.

+
Remediation

Enable Versioning by clicking on every bucket by editing the bucket configuration.

+
Observation

3 of 3 object store buckets have no versioning enabled.

+

4.2.2 – Ensure Boot Volumes are encrypted with Customer-Managed Key.

+
Description

When you launch a virtual machine (VM) or bare metal instance based on a platform image or custom image, a new boot volume for the instance is created in the same compartment. That boot volume is associated with that instance until you terminate the instance. By default, the Oracle service manages the keys that encrypt this boot volume. Boot Volumes can also be encrypted using a customer managed key.

+
Rationale

Encryption of boot volumes provides an additional level of security for your data. Management of encryption keys is critical to protecting and accessing protected data. Customers should identify boot volumes encrypted with Oracle service managed keys in order to determine if they want to manage the keys for certain boot volumes and then apply their own key lifecycle management to the selected boot volumes.

+
Impact

Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize the Boot Volume service to use the keys you create. +Required IAM Policy: +

+Allow service Bootstorage to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'
+

+
Remediation

For each boot volumes from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.

+
Observation

2 of 2 boot volumes are not encrypted with a Customer-Managed Key.

+

4.3.1 – Ensure File Storage Systems are encrypted with Customer-Managed Keys.

+
Description

Oracle Cloud Infrastructure File Storage service (FSS) provides a durable, scalable, secure, enterprise-grade network file system. By default, the Oracle service manages the keys that encrypt FSS file systems. FSS file systems can also be encrypted using a customer managed key.

+
Rationale

Encryption of FSS systems provides an additional level of security for your data. Management of encryption keys is critical to protecting and accessing protected data. Customers should identify FSS file systems that are encrypted with Oracle service managed keys in order to determine if they want to manage the keys for certain FSS file systems and then apply their own key lifecycle management to the selected FSS file systems.

+
Impact

Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize the File Storage service to use the keys you create. +Required IAM Policy: +

+Allow service FssOc1Prod to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'
+

+
Remediation

For each file storage system from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.

+
Observation

1 of 1 file storage services (FSS) are not encrypted with a Customer-Managed Key.

+
+
From e8d40aa1fcf2e76cd355160cd4062c39d8a19eab Mon Sep 17 00:00:00 2001 From: Olaf Heimburger Date: Mon, 5 Feb 2024 10:10:21 +0100 Subject: [PATCH 2/2] Missing permission. --- .../files/oci-security-health-check-standard/standard.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/standard.sh diff --git a/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/standard.sh b/security/security-design/shared-assets/oci-security-health-check-standard/files/oci-security-health-check-standard/standard.sh old mode 100644 new mode 100755