<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: auditing-serverless-function-security
description: >-
  Audit serverless function security across AWS Lambda, Azure Functions, and GCP
  Cloud Functions for overprivileged execution roles, exposed endpoints, insecure
  environment variables, missing VPC integration, and runtime vulnerabilities.
domain: cybersecurity
subdomain: cloud-security
tags:
  - aws
  - azure
  - gcp
  - serverless
  - lambda
  - azure-functions
  - cloud-functions
  - execution-role
  - api-gateway
  - runtime-security
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1059.009"]
---

# Auditing Serverless Function Security

## Overview

Serverless functions introduce unique security challenges — overprivileged execution
roles, secrets stored in plaintext environment variables, unrestricted function URLs,
outdated runtimes, and missing VPC integration that bypasses network controls. This
skill provides a systematic audit of AWS Lambda, Azure Functions, and GCP Cloud
Functions covering IAM, network, secrets, and runtime configuration.

Mode: `[MODE: BLUE]` — Serverless security posture assessment.

## Prerequisites

| Requirement | Details |
|---|---|
| AWS CLI v2, Azure CLI, `gcloud` CLI configured | Required |
| AWS | `lambda:List*`, `lambda:Get*`, `iam:GetRolePolicy` permissions |
| Azure | `Microsoft.Web/sites/read`, `Reader` role |
| GCP | `cloudfunctions.functions.list`, `cloudfunctions.functions.get` |
| Python 3.10+ with `boto3` | Required |

## Key Concepts

### AWS Lambda Security Audit

```bash
# List all Lambda functions with runtime and role
aws lambda list-functions \
  --query 'Functions[].{Name:FunctionName,Runtime:Runtime,Role:Role,Timeout:Timeout,Memory:MemorySize}' \
  --output table

# Find functions with deprecated runtimes
aws lambda list-functions --query 'Functions[?contains(Runtime, `python3.7`) || contains(Runtime, `python3.8`) || contains(Runtime, `nodejs14`) || contains(Runtime, `nodejs16`)].{Name:FunctionName,Runtime:Runtime}' \
  --output table

# Check function execution role policies
ROLE_NAME=$(aws lambda get-function --function-name $FUNC_NAME --query 'Configuration.Role' --output text | awk -F/ '{print $NF}')
aws iam list-attached-role-policies --role-name $ROLE_NAME --output table
aws iam list-role-policies --role-name $ROLE_NAME --output table

# Find functions with admin-level roles
aws lambda list-functions --query 'Functions[].{Name:FunctionName,Role:Role}' --output json | \
  jq -r '.[] | .Role' | sort -u | while read role_arn; do
    ROLE=$(echo "$role_arn" | awk -F/ '{print $NF}')
    POLICIES=$(aws iam list-attached-role-policies --role-name "$ROLE" --query 'AttachedPolicies[].PolicyArn' --output text 2>/dev/null)
    echo "$POLICIES" | grep -q "AdministratorAccess\|PowerUserAccess" && echo "[CRITICAL] $ROLE has admin policy"
  done

# Check for exposed function URLs (no auth)
aws lambda list-function-url-configs --function-name $FUNC_NAME 2>/dev/null | \
  jq 'select(.FunctionUrlConfigs[].AuthType == "NONE") | .FunctionUrlConfigs[].FunctionUrl'

# Find functions with plaintext secrets in env vars
aws lambda list-functions --query 'Functions[].FunctionName' --output text | tr '\t' '\n' | while read func; do
  ENV=$(aws lambda get-function-configuration --function-name "$func" --query 'Environment.Variables' --output json 2>/dev/null)
  echo "$ENV" | grep -iqE '"(password|secret|key|token|api_key)"' && echo "[HIGH] $func — potential secrets in env vars"
done

# Check VPC configuration
aws lambda list-functions --query 'Functions[?VpcConfig.VpcId==null || VpcConfig.VpcId==``].{Name:FunctionName,VPC:VpcConfig.VpcId}' \
  --output table
```

### Azure Functions Security Audit

```bash
# List function apps
az functionapp list --query "[].{Name:name,RG:resourceGroup,Runtime:siteConfig.linuxFxVersion,State:state}" --output table

# Check authentication status
for app in $(az functionapp list --query "[].name" --output tsv); do
  AUTH=$(az webapp auth show --name "$app" --resource-group $RG 2>/dev/null | jq -r '.enabled')
  [ "$AUTH" != "true" ] && echo "[HIGH] $app — authentication not enabled"
done

# Check HTTPS-only
az functionapp list --query "[?httpsOnly==\`false\`].{Name:name,RG:resourceGroup}" --output table

# Check for managed identity
az functionapp list --query "[?identity==null].{Name:name,RG:resourceGroup}" --output table

# List app settings (check for secrets)
az functionapp config appsettings list --name $APP_NAME --resource-group $RG \
  --query "[?contains(name,'SECRET') || contains(name,'PASSWORD') || contains(name,'KEY')].{Name:name}"
```

### GCP Cloud Functions Security Audit

```bash
# List functions with runtime and service account
gcloud functions list \
  --format="table(name,runtime,serviceAccountEmail,status,httpsTrigger.url)"

# Find functions with default service account
gcloud functions list --format=json | jq '
  .[] | select(.serviceAccountEmail | test("@appspot.gserviceaccount.com$")) |
  {name: .name, sa: .serviceAccountEmail}'

# Check for public (unauthenticated) functions
gcloud functions list --format=json | jq '
  .[] | select(.httpsTrigger != null) | {name: .name, url: .httpsTrigger.url}'

# Check IAM bindings for allUsers
for func in $(gcloud functions list --format="value(name)"); do
  gcloud functions get-iam-policy "$func" 2>/dev/null | grep -q "allUsers" && \
    echo "[CRITICAL] $func — allows unauthenticated invocation"
done

# Find functions with outdated runtimes
gcloud functions list --format=json | jq '
  .[] | select(.runtime | test("python37|python38|nodejs14|nodejs16|go113")) |
  {name: .name, runtime: .runtime}'
```

## Workflow

### Step 1: Enumerate All Functions

```bash
# AWS
aws lambda list-functions --query 'Functions | length(@)'

# Azure
az functionapp list --query "length(@)"

# GCP
gcloud functions list --format="value(name)" | wc -l
```

### Step 2: Run Automated Audit

```bash
node scripts/agent.js --provider aws --output /tmp/serverless_audit.json
```

## Detection

```yaml
title: Auditing Serverless Function Security Detection
id: 658ba05e-6f76-4322-9a20-abb24f6e7be0
status: experimental
description: Detects suspicious activity related to auditing serverless function security techniques in cloud security context
logsource:
  product: aws
  service: cloudtrail
detection:
  selection:
    eventName: "*Unauthorized*"
  condition: selection
level: medium
tags:
  - attack.t1059.009
  - attack.credential_access
falsepositives:
  - Automated cloud infrastructure provisioning by approved CI/CD pipelines
```


**Detection Opportunities**

| Indicator | Source | Detection Logic |
|---|---|---|
| Auditing Serverless Function Security Detection | aws | Sigma rule (medium) |
| ATT&CK Coverage | MITRE ATT&CK | T1059.009 |

## Verification

- [ ] No functions with AdministratorAccess or wildcard IAM policies
- [ ] All function URLs require authentication (no AuthType=NONE)
- [ ] Secrets stored in Secrets Manager/Key Vault, not env vars
- [ ] Functions use current supported runtimes
- [ ] Sensitive functions deployed within VPC
- [ ] Function concurrency limits set to prevent abuse
- [ ] Logging enabled for all function invocations
- [ ] Resource-based policies reviewed for cross-account access

## References

- [OWASP Serverless Top 10](https://owasp.org/www-project-serverless-top-10/)
- [AWS Lambda Security Best Practices](https://docs.aws.amazon.com/lambda/latest/dg/lambda-security.html)
- [Azure Functions Security](https://learn.microsoft.com/en-us/azure/azure-functions/security-concepts)
- [GCP Cloud Functions Security](https://cloud.google.com/functions/docs/securing/)
- [MITRE ATT&CK T1648 — Serverless Execution](https://attack.mitre.org/techniques/T1648/)
