Skip to content

Commit ac8230a

Browse files
authored
Merge pull request #115 from cloudgraphdev/feature/CG-1294-GCP-CIS-130-118
DRAFT: Feature/cg 1294 gcp cis 130 118
2 parents 622d087 + 08d975e commit ac8230a

5 files changed

Lines changed: 324 additions & 0 deletions

File tree

src/gcp/cis-1.3.0/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ Policy Pack based on the GCP Foundations 1.3.0 benchmark provided by the [Center
7171
| GCP CIS 1.14 | Ensure API keys are restricted to only APIs that application needs access |
7272
| GCP CIS 1.15 | Ensure API keys are rotated every 90 days |
7373
| GCP CIS 1.16 | Ensure Essential Contacts is Configured for Organization |
74+
| GCP CIS 1.17 | Ensure that Dataproc Cluster is encrypted using CustomerManaged Encryption Key |
75+
| GCP CIS 1.18 | Ensure Secrets are Not Stored in Cloud Functions Environment Variables by Using Secret Manager |
7476
| GCP CIS 2.1 | Ensure that Cloud Audit Logging is configured properly across all services and all users from a project |
7577
| GCP CIS 2.2 | Ensure that sinks are configured for all log entries |
7678
| GCP CIS 2.3 | Ensure that retention policies on log buckets are configured using Bucket Lock |
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
2+
/* eslint-disable @typescript-eslint/no-explicit-any */
3+
4+
export default {
5+
id: 'gcp-cis-1.3.0-1.17',
6+
title: 'GCP CIS 1.17 Ensure that Dataproc Cluster is encrypted using CustomerManaged Encryption Key',
7+
description:
8+
'When you use Dataproc, cluster and job data is stored on Persistent Disks (PDs) associated with the Compute Engine VMs in your cluster and in a Cloud Storage staging bucket. This PD and bucket data is encrypted using a Google-generated data encryption key (DEK) and key encryption key (KEK). The CMEK feature allows you to create, use, and revoke the key encryption key (KEK). Google still controls the data encryption key (DEK).',
9+
audit: `**From Console:**
10+
11+
1. Login to the GCP Console and navigate to the Dataproc Cluster page by visiting:
12+
13+
https://console.cloud.google.com/dataproc/clusters.
14+
15+
2. Select the project from the project dropdown list.
16+
3. On the Dataproc Clusters page, select the cluster and click on the Name attribute value that you want to examine.
17+
4. On the details page, select the Configurations tab.
18+
5. On the Configurations tab, check the Encryption type configuration attribute value. If the value is set to Google-managed key, then Dataproc Cluster is not encrypted with Customer managed encryption keys.
19+
20+
Repeat step no. 3 - 5 for other Dataproc Clusters available in the selected project.
21+
22+
6. Change the project from the project dropdown list and repeat the audit procedure for other projects.
23+
24+
**From Command Line:**
25+
26+
1. Run clusters list command to list all the Dataproc Clusters available in the region:
27+
28+
gcloud dataproc clusters list --region='us-central1'
29+
30+
2. Run clusters describe command to get the key details of the selected cluster:
31+
32+
gcloud dataproc clusters describe <cluster_name> --region=us-central1 --flatten=config.encryptionConfig.gcePdKmsKeyName
33+
34+
3. If the above command output return "null", then the selected cluster is not encrypted with Customer managed encryption keys.
35+
4. Repeat step no. 2 and 3 for other Dataproc Clusters available in the selected region. Change the region by updating --region and repeat step no. 2 for other clusters available in the project. Change the project by running the below command and repeat the audit procedure for other Dataproc clusters available in other projects:
36+
37+
gcloud config set project <project_ID>"
38+
`,
39+
rationale:
40+
'Many Google Cloud services, such as Cloud Billing, send out notifications to share important information with Google Cloud users. By default, these notifications are sent to members with certain Identity and Access Management (IAM) roles. With Essential Contacts, you can customize who receives notifications by providing your own list of contacts.',
41+
remediation: `**From Console:**
42+
1. Login to the GCP Console and navigate to the Dataproc Cluster page by visiting
43+
44+
https://console.cloud.google.com/dataproc/clusters.
45+
46+
2. Select the project from the projects dropdown list.
47+
3. On the *Dataproc Cluster* page, click on the *Create Cluster* to create a new cluster with Customer managed encryption keys.
48+
4. On *Create a cluster* page, perform below steps:
49+
• Inside *Set up cluster* section perform below steps:
50+
-In the *Name* textbox, provide a name for your cluster.
51+
o From *Location* select the location in which you want to deploy a cluster.
52+
o Configure other configurations as per your requirements.
53+
• Inside *Configure Nodes* and *Customize cluster* section configure the settings as per your requirements.
54+
• Inside *Manage security* section, perform below steps:
55+
o From *Encryption*, select *Customer-managed key*.
56+
o Select a customer-managed key from dropdown list.
57+
o Ensure that the selected KMS Key have Cloud KMS CryptoKey Encrypter/Decrypter role assign to Dataproc Cluster service account ("serviceAccount:service-<project_number>@computesystem.iam.gserviceaccount.com").
58+
o Click on *Create* to create a cluster.
59+
• Once the cluster is created migrate all your workloads from the older cluster to the new cluster and delete the old cluster by performing the below steps:
60+
o On the *Clusters* page, select the old cluster and click on *Delete cluster*.
61+
o On the *Confirm deletion* window, click on *Confirm* to delete the cluster.
62+
o Repeat step above for other Dataproc clusters available in the selected project.
63+
• Change the project from the project dropdown list and repeat the remediation procedure for other Dataproc clusters available in other projects.
64+
65+
66+
**From Command Line:**
67+
68+
Before creating cluster ensure that the selected KMS Key have Cloud KMS CryptoKey Encrypter/Decrypter role assign to Dataproc Cluster service account ("serviceAccount:service-<project_number>@compute-system.iam.gserviceaccount.com").
69+
Run clusters create command to create new cluster with customer-managed key:
70+
71+
gcloud dataproc clusters create <cluster_name> --region=us-central1 --gce-pdkms-key=<key_resource_name>
72+
73+
The above command will create a new cluster in the selected region.
74+
Once the cluster is created migrate all your workloads from the older cluster to the new cluster and Run clusters delete command to delete cluster:
75+
76+
gcloud dataproc clusters delete <cluster_name> --region=us-central1
77+
78+
Repeat step no. 1 to create a new Dataproc cluster.
79+
Change the project by running the below command and repeat the remediation procedure for other projects:
80+
81+
gcloud config set project <project_ID>"
82+
`,
83+
references: [
84+
'https://cloud.google.com/docs/security/encryption/default-encryption',
85+
],
86+
gql: `{
87+
querygcpDataprocCluster {
88+
id
89+
__typename
90+
config{
91+
encryptionConfigGcePdKmsKeyName
92+
}
93+
}
94+
}`,
95+
resource: 'querygcpDataprocCluster[*]',
96+
severity: 'unknown',
97+
conditions: {
98+
path: '@.config.encryptionConfigGcePdKmsKeyName',
99+
isEmpty: false,
100+
}
101+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
2+
/* eslint-disable @typescript-eslint/no-explicit-any */
3+
4+
export default {
5+
id: 'gcp-cis-1.3.0-1.18',
6+
title: 'GCP CIS 1.18 Ensure Secrets are Not Stored in Cloud Functions Environment Variables by Using Secret Manager',
7+
description:
8+
'Google Cloud Functions allow you to host serverless code that is executed when an event is triggered, without the requiring the management a host operating system. These functions can also store environment variables to be used by the code that may contain authentication or other information that needs to remain confidential.',
9+
audit: `Determine if Confidential Information is Stored in your Functions in Cleartext
10+
11+
**From Console:**
12+
13+
1. Log in to the Google Cloud Web Portal (https://console.cloud.google.com/)
14+
2. Within the project you wish to audit, select the Navigation hamburger menu in the top left. Scroll down to under the heading 'Serverless', then select 'Cloud Functions'
15+
3. Click on a function name from the list
16+
4. Open the Variables tab and you will see both buildEnvironmentVariables and environmentVariables
17+
5. Review the variables whether they are secrets
18+
6. Repeat step 3-5 until all functions are reviewed
19+
20+
**From Command Line:**
21+
22+
1. To view a list of your cloud functions run
23+
24+
cloud functions list
25+
26+
2. For each cloud function in the list run the following command.
27+
28+
gcloud functions describe <function_name>
29+
30+
3. Review the settings of the buildEnvironmentVariables and environmentVariables. Determine if this is data that should not be publicly accessible.
31+
32+
Determine if Secret Manager API is 'Enabled' for your Project
33+
34+
**From Console**
35+
36+
1. Within the project you wish to audit, select the Navigation hamburger menu in the top left. Hover over 'APIs & Services' to under the heading 'Serverless', then select 'Enabled APIs & Services' in the menu that opens up.
37+
2. Click the button '+ Enable APIS and Services'
38+
3. In the Search bar, search for 'Secret Manager API' and select it.
39+
4. If it is enabled, the blue box that normally says 'Enable' will instead say 'Manage'.
40+
41+
**From Command Line:**
42+
43+
1. Within the project you wish to audit, run the following command.
44+
45+
gcloud services list
46+
47+
2. If 'Secret Manager API' is in the list, it is enabled.
48+
`,
49+
rationale:
50+
'It is recommended to use the Secret Manager, because environment variables are stored unencrypted, and accessible for all users who have access to the code.',
51+
remediation: `Enable Secret Manager API for your Project
52+
53+
**From Console:**
54+
55+
1. Within the project you wish to enable, select the Navigation hamburger menu in the top left. Hover over 'APIs & Services' to under the heading 'Serverless', then select 'Enabled APIs & Services' in the menu that opens up.
56+
2. Click the button '+ Enable APIS and Services'
57+
3. In the Search bar, search for 'Secret Manager API' and select it.
58+
4. Click the blue box that says 'Enable'.
59+
60+
**From Command Line:**
61+
62+
1. Within the project you wish to enable the API in, run the following command.
63+
64+
gcloud services enable Secret Manager API
65+
66+
Reviewing Environment Variables That Should Be Migrated to Secret Manager
67+
68+
**From Console:**
69+
70+
1. Log in to the Google Cloud Web Portal (https://console.cloud.google.com/)
71+
2. Go to Cloud Functions
72+
3. Click on a function name from the list
73+
4. Click on Edit and review the Runtime environment for variables that should be secrets. Leave this list open for the next step.
74+
75+
**From Command Line:**
76+
77+
1. To view a list of your cloud functions run
78+
79+
cloud functions list
80+
81+
2. For each cloud function run the following command.
82+
83+
gcloud functions describe <function_name>
84+
85+
3. Review the settings of the buildEnvironmentVariables and environmentVariables. Keep this information for the next step.
86+
87+
Migrating Environment Variables to Secrets within the Secret Manager
88+
89+
**From Console:**
90+
91+
1. Go to the Secret Manager page in the Cloud Console.
92+
2. On the Secret Manager page, click Create Secret.
93+
3. On the Create secret page, under Name, enter the name of the Environment Variable you are replacing. This will then be the Secret Variable you will reference in your code.
94+
4. You will also need to add a version. This is the actual value of the variable that will be referenced from the code. To add a secret version when creating the initial secret, in the Secret value field, enter the value from the Environment Variable you are replacing.
95+
5. Leave the Regions section unchanged.
96+
6. Click the Create secret button.
97+
7. Repeat for all Environment Variables
98+
99+
**From Command Line**
100+
101+
1. Run the following command with the Environment Variable name you are replacing in the *<secret-id>*. It is most secure to point this command to a file with the Environment Variable value located in it, as if you entered it via command line it would show up in your shell’s command history.
102+
103+
gcloud secrets create <secret-id> --data-file="/path/to/file.txt"
104+
105+
Granting your Runtime's Service Account Access to Secrets
106+
107+
**From Console**
108+
109+
1. Within the project containing your runtime login with account that has the 'roles/secretmanager.secretAccessor' permission.
110+
2. Select the Navigation hamburger menu in the top left. Hover over 'Security' to under the then select 'Secret Manager' in the menu that opens up.
111+
3. Click the name of a secret listed in this screen.
112+
4. If it is not already open, click Show Info Panel in this screen to open the panel.
113+
5.In the info panel, click Add principal.
114+
6.In the New principals field, enter the service account your function uses for its identity. (If you need help locating or updating your runtime's service account, please see the 'docs/securing/function-identity#runtime_service_account' reference.)
115+
5. In the Select a role dropdown, choose Secret Manager and then Secret Manager Secret Accessor.
116+
117+
**From Command Line**
118+
119+
As of the time of writing, using Google CLI to list Runtime variables is only in beta. Because this is likely to change we are not including it here.
120+
121+
Modifying the Code to use the Secrets in Secret Manager
122+
123+
**From Console**
124+
125+
This depends heavily on which language your runtime is in. For the sake of the brevity of this recommendation, please see the '/docs/creating-and-accessing-secrets#access' reference for language specific instructions.
126+
127+
**From Command Line**
128+
129+
This depends heavily on which language your runtime is in. For the sake of the brevity of this recommendation, please see the' /docs/creating-and-accessing-secrets#access' reference for language specific instructions.
130+
131+
Deleting the Insecure Environment Variables Be certain to do this step last. Removing variables from code actively referencing them will prevent it from completing successfully.
132+
133+
**From Console**
134+
135+
1. Select the Navigation hamburger menu in the top left. Hover over 'Security' then select 'Secret Manager' in the menu that opens up.
136+
2. Click the name of a function. Click Edit.
137+
3. Click Runtime, build and connections settings to expand the advanced configuration options.
138+
4. Click 'Security’. Hover over the secret you want to remove, then click 'Delete'.
139+
5. Click Next. Click Deploy. The latest version of the runtime will now reference the secrets in Secret Manager.
140+
141+
**From Command Line**
142+
143+
gcloud functions deploy <Function name>--remove-env-vars <env vars>
144+
145+
If you need to find the env vars to remove, they are from the step where ‘gcloud functions describe *<function_name>*’ was run.
146+
147+
**Default Value:**
148+
149+
By default Secret Manager is not enabled.
150+
`,
151+
references: [
152+
['https://cloud.google.com/functions/docs/configuring/env-var#managing_secrets'],
153+
['https://cloud.google.com/secret-manager/docs/overview'],
154+
],
155+
severity: 'unknown',
156+
}

src/gcp/cis-1.3.0/rules/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import Gcp_CIS_130_113 from './gcp-cis-1.3.0-1.13'
1414
import Gcp_CIS_130_114 from './gcp-cis-1.3.0-1.14'
1515
import Gcp_CIS_130_115 from './gcp-cis-1.3.0-1.15'
1616
import Gcp_CIS_130_116 from './gcp-cis-1.3.0-1.16'
17+
import Gcp_CIS_130_117 from './gcp-cis-1.3.0-1.17'
18+
import Gcp_CIS_130_118 from './gcp-cis-1.3.0-1.18'
1719
import Gcp_CIS_130_21 from './gcp-cis-1.3.0-2.1'
1820
import Gcp_CIS_130_22 from './gcp-cis-1.3.0-2.2'
1921
import Gcp_CIS_130_23 from './gcp-cis-1.3.0-2.3'
@@ -96,6 +98,8 @@ export default [
9698
Gcp_CIS_130_114,
9799
Gcp_CIS_130_115,
98100
Gcp_CIS_130_116,
101+
Gcp_CIS_130_117,
102+
Gcp_CIS_130_118,
99103
Gcp_CIS_130_21,
100104
Gcp_CIS_130_22,
101105
Gcp_CIS_130_23,

src/gcp/cis-1.3.0/tests/gcp-cis-1.3.0-1.x.test.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Gcp_CIS_130_112 from '../rules/gcp-cis-1.3.0-1.12'
1616
import Gcp_CIS_130_113 from '../rules/gcp-cis-1.3.0-1.13'
1717
import Gcp_CIS_130_115 from '../rules/gcp-cis-1.3.0-1.15'
1818
import Gcp_CIS_130_116 from '../rules/gcp-cis-1.3.0-1.16'
19+
import Gcp_CIS_130_117 from '../rules/gcp-cis-1.3.0-1.17'
1920
import { initRuleEngine } from '../../../utils/test'
2021

2122
export interface MetricDescriptor {
@@ -111,13 +112,27 @@ export interface QuerygcpIamPolicy {
111112
bindings: Bindings[]
112113
}
113114

115+
export interface QuerygcpEssentialContact {
116+
id: string
117+
notificationCategorySubscriptions: string[]
118+
email: string
119+
}
120+
export interface DataprocClusterConfig {
121+
encryptionConfigGcePdKmsKeyName?: string
122+
}
123+
export interface QuerygcpDataprocCluster {
124+
id: string
125+
config: DataprocClusterConfig
126+
}
114127
export interface CIS1xQueryResponse {
115128
querygcpOrganization?: QuerygcpOrganization[]
116129
querygcpProject?: QuerygcpProject[]
117130
querygcpApiKey?: QuerygcpApiKey[]
118131
querygcpServiceAccount?: QuerygcpServiceAccount[]
119132
querygcpKmsKeyRing?: QuerygcpKmsKeyRing[]
120133
querygcpIamPolicy?: QuerygcpIamPolicy[]
134+
querygcpEssentialContact?: QuerygcpEssentialContact[]
135+
querygcpDataprocCluster?: QuerygcpDataprocCluster[]
121136
}
122137

123138
describe('CIS Google Cloud Platform Foundations: 1.3.0', () => {
@@ -985,4 +1000,50 @@ describe('CIS Google Cloud Platform Foundations: 1.3.0', () => {
9851000
await testRule(data, Result.FAIL)
9861001
})
9871002
})
1003+
1004+
describe('GCP CIS 1.17 Ensure that Dataproc Cluster is encrypted using Customer Managed Encryption Key', () => {
1005+
const getRuleFixture = (): CIS1xQueryResponse => {
1006+
return {
1007+
querygcpDataprocCluster: [
1008+
{
1009+
id: cuid(),
1010+
config: {},
1011+
},
1012+
],
1013+
}
1014+
}
1015+
1016+
const testRule = async (
1017+
data: CIS1xQueryResponse,
1018+
expectedResult: Result
1019+
): Promise<void> => {
1020+
// Act
1021+
const [processedRule] = await rulesEngine.processRule(
1022+
Gcp_CIS_130_117 as Rule,
1023+
{ ...data }
1024+
)
1025+
1026+
// Asserts
1027+
expect(processedRule.result).toBe(expectedResult)
1028+
}
1029+
1030+
test('Security Issue when Customer Managed Encryption Key config is missing ', async () => {
1031+
const data: CIS1xQueryResponse = getRuleFixture()
1032+
await testRule(data, Result.FAIL)
1033+
})
1034+
1035+
test('Security Issue when Customer Managed Encryption Key config is empty ', async () => {
1036+
const data: CIS1xQueryResponse = getRuleFixture()
1037+
const dataprocCluster = data.querygcpDataprocCluster as QuerygcpDataprocCluster[]
1038+
dataprocCluster[0].config.encryptionConfigGcePdKmsKeyName = ''
1039+
await testRule(data, Result.FAIL)
1040+
})
1041+
1042+
test('No Security Issue when Customer Managed Encryption Key is configured', async () => {
1043+
const data: CIS1xQueryResponse = getRuleFixture()
1044+
const dataprocCluster = data.querygcpDataprocCluster as QuerygcpDataprocCluster[]
1045+
dataprocCluster[0].config.encryptionConfigGcePdKmsKeyName = 'MyKey'
1046+
await testRule(data, Result.PASS)
1047+
})
1048+
})
9881049
})

0 commit comments

Comments
 (0)