From 9247b174ac90c14543ed0e69d764190e5e925355 Mon Sep 17 00:00:00 2001 From: pearl-truss Date: Fri, 26 Jan 2024 11:14:49 -0500 Subject: [PATCH] use environmental variables for restricting access by ip address --- .envrc | 1 + services/app-api/serverless.yml | 10 --------- services/app-api/src/handlers/apollo_gql.ts | 2 +- .../handlers/third_party_API_authorizer.ts | 22 +++++++++++++------ 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/.envrc b/.envrc index e60feb2742..5c01303a36 100644 --- a/.envrc +++ b/.envrc @@ -26,6 +26,7 @@ export DATABASE_URL='postgresql://postgres:shhhsecret@localhost:5432/postgres?sc export EMAILER_MODE='LOCAL' export LD_SDK_KEY='this-value-must-be-set-in-local' export PARAMETER_STORE_MODE='LOCAL' +export ALLOWED_IP_ADDRESSES='127.0.0.1' export REACT_APP_OTEL_COLLECTOR_URL='http://localhost:4318/v1/traces' export REACT_APP_LD_CLIENT_ID='this-value-can-be-set-in-local-if-desired' diff --git a/services/app-api/serverless.yml b/services/app-api/serverless.yml index ff444880cb..b3b88c8a9d 100644 --- a/services/app-api/serverless.yml +++ b/services/app-api/serverless.yml @@ -188,16 +188,6 @@ functions: graphql: handler: src/handlers/apollo_gql.graphqlHandler - resourcePolicy: - - Effect: Deny - Principal: '*' - Action: execute-api:Invoke - Resource: - - execute-api:/*/*/* - Condition: - NotIpAddress: - aws:SourceIp: - - '123.123.123.123' events: - http: diff --git a/services/app-api/src/handlers/apollo_gql.ts b/services/app-api/src/handlers/apollo_gql.ts index 3ff05b6414..693b5bdcea 100644 --- a/services/app-api/src/handlers/apollo_gql.ts +++ b/services/app-api/src/handlers/apollo_gql.ts @@ -209,7 +209,7 @@ async function initializeGQLHandler(): Promise { if (stageName === undefined) throw new Error('Configuration Error: stage is required') - if (parameterStoreMode !== 'LOCAL' && allowedIpAddresses === undefined) + if (allowedIpAddresses === undefined) throw new Error('Configuration Error: allowed IP addresses is required') if (!dbURL) { diff --git a/services/app-api/src/handlers/third_party_API_authorizer.ts b/services/app-api/src/handlers/third_party_API_authorizer.ts index a3741ba476..48e5d9947f 100644 --- a/services/app-api/src/handlers/third_party_API_authorizer.ts +++ b/services/app-api/src/handlers/third_party_API_authorizer.ts @@ -20,12 +20,17 @@ export const main: APIGatewayTokenAuthorizerHandler = async ( try { // authentication step for validating JWT token const userId = await jwtLib.userIDFromToken(authToken) + const parsedEvent = JSON.parse(JSON.stringify(event)) + const host = parsedEvent.headers.Host + // host is formatted as ipaddress:port + // the following will remove the :port to leave just the ip address + const ipAddress = host.slice(0, host.indexOf(':')) if (userId instanceof Error) { const msg = 'Invalid auth token' console.error(msg) - return generatePolicy(undefined, event) + return generatePolicy(undefined, event, ipAddress) } console.info({ @@ -34,29 +39,32 @@ export const main: APIGatewayTokenAuthorizerHandler = async ( status: 'SUCCESS', }) - return generatePolicy(userId, event) + return generatePolicy(userId, event, ipAddress) } catch (err) { console.error( 'unexpected exception attempting to validate authorization', err ) - return generatePolicy(undefined, event) + return generatePolicy(undefined, event, undefined) } } const generatePolicy = function ( userId: string | undefined, - event: APIGatewayTokenAuthorizerEvent + event: APIGatewayTokenAuthorizerEvent, + ipAddress: string | undefined ): APIGatewayAuthorizerResult { - // If the JWT is verified as valid, send an Allow policy - // this will allow the request to go through + // If the JWT is verified as valid, and the request comes from an allowed IP address + // send an Allow policy // otherwise a Deny policy is returned which restricts access + const validIPAddress = + ipAddress && process.env.ALLOWED_IP_ADDRESSES?.includes(ipAddress) const policyDocument: PolicyDocument = { Version: '2012-10-17', // current version of the policy language Statement: [ { Action: 'execute-api:Invoke', - Effect: userId ? 'Allow' : 'Deny', + Effect: userId && validIPAddress ? 'Allow' : 'Deny', Resource: event['methodArn'], }, ],