This guide details how to set up the necessary AWS infrastructure to act as a secure proxy between the Chrome extension and the CrowdStrike API. This architecture ensures that your CrowdStrike API credentials never leave your AWS account.
Data flow:
Before you begin, you will need:
- An AWS account with permissions to create IAM, Lambda, API Gateway, and Secrets Manager resources.
- Your CrowdStrike API credentials (Client ID and Client Secret) with
vulnerabilities:readpermissions.
- Navigate to the AWS Secrets Manager console.
- Click "Store a new secret".
- Select "Other type of secret".
- Under "Secret key/value", choose the "Plaintext" tab.
- Paste the following JSON (replace the placeholders):
{
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}- Click Next.
- Enter the secret name:
CrowdStrikeCredentials. - Proceed with default settings (no rotation), then click "Store".
- After storing, copy the Secret ARN for later use.
- Go to the AWS Lambda console.
- Click "Create function" → "Author from scratch".
- Function name:
crowdstrike-cve-proxy - Runtime:
Node.js 20.x - Architecture:
x86_64
- Function name:
- Under "Change default execution role", select:
- "Create a new role with basic Lambda permissions"
- Click "Create function"
- Open the Lambda function → Configuration tab → Permissions.
- Click the Role name to open the IAM console.
- On the IAM Role page → "Add permissions" → "Create inline policy".
- Select the JSON tab and paste:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "PASTE_YOUR_SECRET_ARN_HERE"
}
]
}- Click "Review policy", name it (e.g.,
SecretsManagerReadAccess-CrowdStrike) → Create policy.
- Back in Lambda, go to the Code tab.
- Open
index.mjsand paste the following:
import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
let cachedToken = null;
let tokenExpiry = 0;
let cachedSecrets = null;
async function getCrowdStrikeSecrets() {
if (cachedSecrets) return cachedSecrets;
const secretName = "CrowdStrikeCredentials";
const client = new SecretsManagerClient();
const command = new GetSecretValueCommand({ SecretId: secretName });
const response = await client.send(command);
if (!response.SecretString) throw new Error("SecretString is empty.");
cachedSecrets = JSON.parse(response.SecretString);
return cachedSecrets;
}
async function getCrowdStrikeToken(secrets, baseUrl) {
if (cachedToken && Date.now() < tokenExpiry) return cachedToken;
const response = await fetch(`${baseUrl}/oauth2/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `client_id=${secrets.client_id}&client_secret=${secrets.client_secret}`
});
if (!response.ok) throw new Error(`Failed to get token: ${response.status}`);
const data = await response.json();
cachedToken = data.access_token;
tokenExpiry = Date.now() + (data.expires_in - 60) * 1000;
return cachedToken;
}
export const handler = async (event) => {
const headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "POST, OPTIONS"
};
try {
const body = JSON.parse(event.body);
const { cve, region } = body;
if (!cve || !region) throw new Error('Missing CVE or region');
const apiUrls = {
'us-1': 'https://api.crowdstrike.com',
'us-2': 'https://api.us-2.crowdstrike.com',
'eu-1': 'https://api.eu-1.crowdstrike.com',
'us-gov-1': 'https://api.laggar.gcw.crowdstrike.com'
};
const baseUrl = apiUrls[region];
if (!baseUrl) throw new Error(`Invalid region: ${region}`);
const secrets = await getCrowdStrikeSecrets();
const token = await getCrowdStrikeToken(secrets, baseUrl);
const apiUrl = `${baseUrl}/spotlight/combined/vulnerabilities/v1?filter=vulnerability_id:'${cve}'&limit=1`;
const csResponse = await fetch(apiUrl, {
headers: { 'Authorization': `Bearer ${token}` }
});
if (!csResponse.ok) throw new Error(`CrowdStrike API error: ${csResponse.status}`);
const csData = await csResponse.json();
const hostCount = csData.meta.pagination.total;
return {
statusCode: 200,
headers: headers,
body: JSON.stringify({
found: hostCount > 0,
hostCount: hostCount
}),
};
} catch (error) {
console.error("Lambda Error:", error);
return {
statusCode: 500,
headers: headers,
body: JSON.stringify({ error: error.message }),
};
}
};- Click "Deploy".
- Go to the API Gateway console.
- Click "Build" under HTTP API.
- Click "Add integration" → Select Lambda → Choose your Lambda function.
- Name the API:
CVE-RAY-API. - On "Configure routes":
- Method:
POST - Path:
/cve-ray
- Method:
- Ensure the route uses the correct Lambda.
- Click Next → Review → Create
- In the API settings → Click CORS → Edit
- Set Access-Control-Allow-Origin:
- Recommended:
chrome-extension://YOUR_EXTENSION_ID - Temporary (less secure):
*
- Recommended:
- Allow Methods:
POST, OPTIONS - Allow Headers:
Content-Type - Click Save
- In API Gateway → Go to Stages → Click
$default. - Copy the Invoke URL.
- Your full endpoint is:
https://abcdef123.execute-api.us-east-1.amazonaws.com/cve-ray
- Copy the endpoint URL from above.
- Open the extension settings.
- Select "AWS API Gateway" authentication.
- Paste the API Gateway Invoke URL.
- Select your CrowdStrike region.
- Click "Save All Settings".
✅ Your secure backend is now fully configured and ready to use!