From a38f7747bc3c92741ce4bceed3c9d4db84c9fb7a Mon Sep 17 00:00:00 2001 From: ravenolf Date: Mon, 21 Jun 2021 11:47:36 -0400 Subject: [PATCH 1/5] add white listing of repositories Signed-off-by: ravenolf --- main.tf | 1 + .../lambdas/webhook/src/webhook/handler.test.ts | 2 ++ .../webhook/lambdas/webhook/src/webhook/handler.ts | 12 ++++++++++++ modules/webhook/variables.tf | 5 +++++ modules/webhook/webhook.tf | 1 + variables.tf | 6 ++++++ 6 files changed, 27 insertions(+) diff --git a/main.tf b/main.tf index 4d14d75c8a..c9bf3029d1 100644 --- a/main.tf +++ b/main.tf @@ -49,6 +49,7 @@ module "webhook" { role_path = var.role_path role_permissions_boundary = var.role_permissions_boundary + repository_white_list = var.webhook_repository_white_list } module "runners" { diff --git a/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts b/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts index 9940351f73..2bb63ec51c 100644 --- a/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts +++ b/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts @@ -14,6 +14,7 @@ describe('handler', () => { let originalError: Console['error']; beforeEach(() => { + process.env.REPOSITORY_WHITE_LIST = '[]'; process.env.GITHUB_APP_WEBHOOK_SECRET = 'TEST_SECRET'; originalError = console.error; console.error = jest.fn(); @@ -71,4 +72,5 @@ describe('handler', () => { expect(resp).toBe(200); expect(sendActionRequest).not.toBeCalled(); }); + }); diff --git a/modules/webhook/lambdas/webhook/src/webhook/handler.ts b/modules/webhook/lambdas/webhook/src/webhook/handler.ts index 5ec86bbdd1..06886677e0 100644 --- a/modules/webhook/lambdas/webhook/src/webhook/handler.ts +++ b/modules/webhook/lambdas/webhook/src/webhook/handler.ts @@ -40,6 +40,18 @@ export const handle = async (headers: IncomingHttpHeaders, payload: any): Promis if (githubEvent === 'check_run') { const body = JSON.parse(payload) as CheckRunEvent; + + const repositoryWhiteListEnv = process.env.REPOSITORY_WHITE_LIST as string || "[]"; + const repositoryWhiteList = JSON.parse(repositoryWhiteListEnv) as Array; + + if (repositoryWhiteList.length > 0) { + const repositoryFullName = body.repository.full_name; + if (!repositoryWhiteList.includes(repositoryFullName)) { + console.error(`Received event from unauthorized repository ${repositoryFullName}`); + return 500; + } + } + let installationId = body.installation?.id; if (installationId == null) { installationId = 0; diff --git a/modules/webhook/variables.tf b/modules/webhook/variables.tf index 665ddaaf34..ccae2a327e 100644 --- a/modules/webhook/variables.tf +++ b/modules/webhook/variables.tf @@ -79,3 +79,8 @@ variable "webhook_lambda_s3_object_version" { default = null } +variable "webhook_repository_white_list" { + description = "List of repositories allowed to use the github app" + type = list(string) + default = [] +} diff --git a/modules/webhook/webhook.tf b/modules/webhook/webhook.tf index fc69049976..11b0103ac9 100644 --- a/modules/webhook/webhook.tf +++ b/modules/webhook/webhook.tf @@ -44,6 +44,7 @@ resource "aws_lambda_function" "webhook" { KMS_KEY_ID = var.encryption.kms_key_id GITHUB_APP_WEBHOOK_SECRET = local.github_app_webhook_secret SQS_URL_WEBHOOK = var.sqs_build_queue.id + REPOSITORY_WHITE_LIST = jsonencode(var.webhook_repository_white_list) } } diff --git a/variables.tf b/variables.tf index 2b914d5ffa..55969b6cec 100644 --- a/variables.tf +++ b/variables.tf @@ -360,3 +360,9 @@ variable "instance_types" { type = set(string) default = null } + +variable "repository_white_list" { + description = "List of repositories allowed to use the github app" + type = list(string) + default = [] +} From dafe36b625d2d4c4308325bd9c19100a580196a9 Mon Sep 17 00:00:00 2001 From: ravenolf Date: Mon, 21 Jun 2021 12:17:44 -0400 Subject: [PATCH 2/5] fix variable naming Signed-off-by: ravenolf --- main.tf | 2 +- modules/webhook/variables.tf | 2 +- modules/webhook/webhook.tf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/main.tf b/main.tf index c9bf3029d1..096e0cccd0 100644 --- a/main.tf +++ b/main.tf @@ -49,7 +49,7 @@ module "webhook" { role_path = var.role_path role_permissions_boundary = var.role_permissions_boundary - repository_white_list = var.webhook_repository_white_list + repository_white_list = var.repository_white_list } module "runners" { diff --git a/modules/webhook/variables.tf b/modules/webhook/variables.tf index ccae2a327e..8b71e1e99b 100644 --- a/modules/webhook/variables.tf +++ b/modules/webhook/variables.tf @@ -79,7 +79,7 @@ variable "webhook_lambda_s3_object_version" { default = null } -variable "webhook_repository_white_list" { +variable "repository_white_list" { description = "List of repositories allowed to use the github app" type = list(string) default = [] diff --git a/modules/webhook/webhook.tf b/modules/webhook/webhook.tf index 11b0103ac9..e3c1b284aa 100644 --- a/modules/webhook/webhook.tf +++ b/modules/webhook/webhook.tf @@ -44,7 +44,7 @@ resource "aws_lambda_function" "webhook" { KMS_KEY_ID = var.encryption.kms_key_id GITHUB_APP_WEBHOOK_SECRET = local.github_app_webhook_secret SQS_URL_WEBHOOK = var.sqs_build_queue.id - REPOSITORY_WHITE_LIST = jsonencode(var.webhook_repository_white_list) + REPOSITORY_WHITE_LIST = jsonencode(var.repository_white_list) } } From 58fb555ba4854d20728f4bb6e9879b552d0ef218 Mon Sep 17 00:00:00 2001 From: ravenolf Date: Tue, 6 Jul 2021 15:10:27 -0400 Subject: [PATCH 3/5] add unit test --- .../lambdas/webhook/src/webhook/handler.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts b/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts index 2bb63ec51c..c4c3b9fc21 100644 --- a/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts +++ b/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts @@ -73,4 +73,14 @@ describe('handler', () => { expect(sendActionRequest).not.toBeCalled(); }); + it('does not handle check_run events from unlisted repositories', async () => { + process.env.REPOSITORY_WHITE_LIST = '["NotCodertocat/Hello-World"]'; + const resp = await handle( + { 'X-Hub-Signature': 'sha1=4a82d2f60346e16dab3546eb3b56d8dde4d5b659', 'X-GitHub-Event': 'check_run' }, + JSON.stringify(check_run_event), + ); + expect(resp).toBe(500); + expect(sendActionRequest).not.toBeCalled(); + }); + }); From 1db499b031647734adffad965abf313d04d4ec6c Mon Sep 17 00:00:00 2001 From: ravenolf Date: Tue, 6 Jul 2021 15:14:08 -0400 Subject: [PATCH 4/5] update docs --- README.md | 3 +++ modules/webhook/README.md | 1 + 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 4d4491053c..48ce800935 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ This [Terraform](https://www.terraform.io/) module creates the required infrastr - [Debugging](#debugging) - [Requirements](#requirements) - [Providers](#providers) +- [Modules](#modules) +- [Resources](#resources) - [Inputs](#inputs) - [Outputs](#outputs) - [Contribution](#contribution) @@ -366,6 +368,7 @@ No requirements. | manage\_kms\_key | Let the module manage the KMS key. | `bool` | `true` | no | | market\_options | Market options for the action runner instances. Setting the value to `null` let the scaler create on-demand instances instead of spot instances. | `string` | `"spot"` | no | | minimum\_running\_time\_in\_minutes | The time an ec2 action runner should be running at minimum before terminated if non busy. | `number` | `5` | no | +| repository\_white\_list | (optional) List of github repository full names (owner/repo_name) that will be allowed to call the runners. Leave empty for no filtering | `list(string)` | `[]` | no | | role\_path | The path that will be added to role path for created roles, if not set the environment name will be used. | `string` | `null` | no | | role\_permissions\_boundary | Permissions boundary that will be added to the created roles. | `string` | `null` | no | | runner\_additional\_security\_group\_ids | (optional) List of additional security groups IDs to apply to the runner | `list(string)` | `[]` | no | diff --git a/modules/webhook/README.md b/modules/webhook/README.md index ef6506a5a1..f564397530 100644 --- a/modules/webhook/README.md +++ b/modules/webhook/README.md @@ -56,6 +56,7 @@ No requirements. | lambda\_timeout | Time out of the lambda in seconds. | `number` | `10` | no | | lambda\_zip | File location of the lambda zip file. | `string` | `null` | no | | logging\_retention\_in\_days | Specifies the number of days you want to retain log events for the lambda log group. Possible values are: 0, 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653. | `number` | `7` | no | +| repository\_white\_list | List of github repository full names (owner/repo_name) that will be allowed to call the runners. Leave empty for no filtering | `list(string)` | `[]` | no | | role\_path | The path that will be added to the role, if not set the environment name will be used. | `string` | `null` | no | | role\_permissions\_boundary | Permissions boundary that will be added to the created role for the lambda. | `string` | `null` | no | | sqs\_build\_queue | SQS queue to publish accepted build events. |
object({
id = string
arn = string
})
| n/a | yes | From 4250f84bd88253206cc5efc3bc1c80961053c6ad Mon Sep 17 00:00:00 2001 From: ravenolf Date: Tue, 6 Jul 2021 15:18:41 -0400 Subject: [PATCH 5/5] add successful unit test --- .../lambdas/webhook/src/webhook/handler.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts b/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts index c4c3b9fc21..3ec25ab5c0 100644 --- a/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts +++ b/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts @@ -83,4 +83,14 @@ describe('handler', () => { expect(sendActionRequest).not.toBeCalled(); }); + it('handles check_run events from whitelisted repositories', async () => { + process.env.REPOSITORY_WHITE_LIST = '["Codertocat/Hello-World"]'; + const resp = await handle( + { 'X-Hub-Signature': 'sha1=4a82d2f60346e16dab3546eb3b56d8dde4d5b659', 'X-GitHub-Event': 'check_run' }, + JSON.stringify(check_run_event), + ); + expect(resp).toBe(200); + expect(sendActionRequest).toBeCalled(); + }); + });