← Back

SAS-3: Insecure Serverless Deployment Configuration - Overview

What is Insecure Serverless Deployment Configuration?

Insecure Serverless Deployment Configuration occurs when the many settings that govern serverless functions—and the cloud resources they depend on—are left at insecure defaults or actively misconfigured. A single function is rarely deployed alone: it arrives with an execution role, environment variables, triggers, a possible public URL, and a web of buckets, queues, topics, tables, and API Gateway routes around it. Each of those has security-relevant knobs, and most of them ship in a state optimised for "works in a demo," not "safe in production."

Unlike a coding bug, this weakness lives in the deployment artifact: the serverless.yml, the AWS SAM or CloudFormation template, the Terraform module, and the resource-based policies attached to each service. When those files grant public access, wildcard principals, plaintext secrets, or missing encryption, the vulnerability is baked in before the first request ever arrives. Every subsequent deploy faithfully re-creates it.

Core Concept

Secure Deployment:
  Storage       -> S3 Block Public Access ON, bucket policy scoped to the role
  Resource      -> Lambda/SNS/SQS policies name a specific Principal + condition
  policies
  Function URL  -> AuthType: AWS_IAM, or no Function URL at all
  Secrets       -> pulled from Secrets Manager/SSM, env vars KMS-encrypted
  Encryption    -> at rest (KMS) and in transit (TLS) enforced everywhere
  API Gateway   -> throttling + quotas set, only needed stages, no debug logging
  CORS          -> explicit origin allow-list, never "*"
  Deploy role   -> least privilege, scoped to the stack's own resources

Misconfiguration:
  Storage       -> bucket public-read/public-write, ACL: AllUsers
  Resource      -> AddPermission with Principal: "*", public SNS/SQS/API
  policies
  Function URL  -> AuthType: NONE, anonymous invoke of the function
  Secrets       -> DB_PASSWORD in a plaintext environment variable
  Encryption    -> default/none at rest, mixed HTTP endpoints
  API Gateway   -> no throttling, verbose stage, full request/response logging
  CORS          -> Access-Control-Allow-Origin: * with credentials
  Deploy role   -> AdministratorAccess wildcard on every deploy

Why It's Critical for Serverless

Serverless concentrates several conditions that make deployment misconfiguration especially damaging:

Why Does This Matter?

Business Impact

Technical Impact

Technical Context

Common Misconfiguration Scenarios in Serverless

1. Publicly-Readable / Writable Storage Buckets

# serverless.yml - VULNERABLE
resources:
  Resources:
    UploadsBucket:
      Type: AWS::S3::Bucket
      Properties:
        AccessControl: PublicRead        # anyone can list and read objects
        # No PublicAccessBlockConfiguration -> public policies allowed

Risk: A bucket used to stage function input/output becomes a public file share. Public-write is worse—attackers plant objects the function later trusts.

2. Overly Permissive Resource-Based Policies

{
  "Effect": "Allow",
  "Principal": "*",
  "Action": "lambda:InvokeFunction",
  "Resource": "arn:aws:lambda:us-east-1:123456789012:function:process-orders"
}

Risk: Principal: "*" on a Lambda AddPermission, or on an SNS/SQS/API policy, exposes the resource to the whole world. The same anti-pattern appears as public SNS topics and SQS queues.

3. Public Lambda Function URLs with No Auth

# AWS SAM - VULNERABLE
FunctionUrlConfig:
  AuthType: NONE                         # anonymous, unauthenticated invoke
  Cors:
    AllowOrigins: ["*"]

Risk: A Function URL with AuthType: NONE is a public HTTPS endpoint that invokes the function for anyone. Combined with AllowOrigins: ["*"], any site can call it from a victim's browser.

4. Plaintext Secrets in Environment Variables

# VULNERABLE - secrets in cleartext, no KMS key
Environment:
  Variables:
    DB_PASSWORD: "S3cr3t-Pa55w0rd"
    STRIPE_KEY: "sk_live_51H..."

Risk: Anyone with lambda:GetFunctionConfiguration reads these directly. Without a customer-managed KMS key, they are also stored using only the default service key.

5. Missing Encryption at Rest / In Transit

# VULNERABLE - no encryption specified
QueueResource:
  Type: AWS::SQS::Queue
  # No KmsMasterKeyId -> default handling, no CMK
BucketResource:
  Type: AWS::S3::Bucket
  # No BucketEncryption block, no aws:SecureTransport policy

Risk: Data at rest is unprotected by a managed key, and without an aws:SecureTransport deny, clients may reach the resource over plain HTTP.

Layers Where Serverless Misconfiguration Hides

LayerTypical MisconfigurationConsequence
Function configPlaintext env vars, no KMS, unnecessary triggersSecret theft, unexpected invocation paths
Function URL / API GWAuthType: NONE, no throttling, verbose stageAnonymous invoke, DoS, info disclosure
Resource policiesPrincipal: "*", public SNS/SQS/bucket policyCross-account/public access
Object storagePublic-read/write, no Block Public AccessData exposure, poisoned inputs
EncryptionNone at rest, no TLS enforcementInterception, unprotected data
IAM rolesOver-broad execution and deploy rolesAccount-wide blast radius, escalation
NetworkingDefault VPC exposure, open security groupsReachable internal resources

Real-World Impact

Case Study 1: Public Cloud Storage Buckets (2017–ongoing)

Misconfiguration:

Impact:

Root Cause: Access-control defaults and copy-pasted permissive policies, with no scan enforcing private-by-default storage. Providers later added "Block Public Access" defaults and console warnings in direct response to this pattern.

Case Study 2: Publicly Exposed Serverless Endpoints (class)

Misconfiguration:

Impact:

Root Cause: Auth left at a permissive default during prototyping and never tightened before production, with no policy scan to catch Principal: "*" or AuthType: NONE. Described here as an incident class; specifics vary by organisation.

Case Study 3: Secrets Leaked Through Function Configuration (class)

Misconfiguration:

Impact:

Root Cause: Convenience during development, no separation between configuration and secrets, and no scan flagging cleartext credentials in IaC. Treated here as a recurring class, not a single named breach.

Prevalence and Statistics

Insecure deployment configuration is consistently among the most common findings in serverless security assessments, because it spans every resource a function touches rather than the function code alone.

Rather than cite precise breach counts (which vary by source), the defensible picture is:

Note: exact percentages and record counts differ between reports and years. Treat any single figure as illustrative; the durable takeaway is that serverless misconfiguration is common, cheap to find, and cheap to exploit.

Common Misunderstandings

Myth 1: "Serverless is managed, so the provider secures it for me"

Reality: The provider secures the platform; you own the configuration of your functions, policies, and resources. A public bucket or a Principal: "*" policy is entirely your responsibility under the shared-responsibility model.

Myth 2: "There's no server, so there's nothing to harden"

Reality: The hardening simply moved. Instead of OS and web-server settings, you harden IaC, resource policies, encryption keys, and IAM roles. There are more independently configured resources, not fewer.

Myth 3: "A Function URL is fine because the URL is hard to guess"

Reality: AuthType: NONE means anonymous invoke for anyone who has the URL, and URLs leak through logs, referrers, code, and scanning. Obscurity is not authentication.

Myth 4: "Environment variables are private to my function"

Reality: Any principal that can read the function configuration can read its environment variables. Without a secrets manager and a customer-managed KMS key, plaintext secrets there are effectively shared with every over-broad role.

Myth 5: "It's internal, so the resource policy can stay open"

Reality: Principal: "*" is not "internal"—it grants everyone. Internal resources are reached through SSRF, compromised functions, and cross-account paths; scope every policy to a named principal with conditions.

Myth 6: "We scanned the code, so we're covered"

Reality: Code scanning misses deployment misconfiguration entirely. This class lives in serverless.yml, SAM/CloudFormation, Terraform, and resource policies—scan the infrastructure as code with checkov, cfn-nag, or tfsec.

How Serverless Deployment Misconfiguration Differs from Related Issues

AspectDeployment Misconfiguration (SAS-3)Broken Authentication (SAS-2)Function Injection (SAS-1)
Root causeInsecure resource/deploy settingsWeak or missing identity checksUntrusted event data in a sink
Where it livesIaC + resource policiesAuth logic and token handlingFunction code / event parsing
Typical fixHarden IaC, scope policies, encryptEnforce and verify identityValidate and sanitise events
DetectionIaC scan, policy reviewAuth testingFuzzing, code review

Key Takeaways

  1. The configuration is the security boundary—with no server to harden, IaC and resource policies are the only wall.
  2. Private by default—no public buckets, no Principal: "*", no AuthType: NONE unless deliberately and narrowly justified.
  3. Secrets belong in a manager, not in plaintext environment variables; encrypt at rest and in transit.
  4. Scan the infrastructure as code—checkov, cfn-nag, and tfsec catch these before deploy; code scanners never will.
  5. Least privilege on both roles—the execution role and the deploy role define the blast radius.

How to Identify if You're Vulnerable

Ask these questions about your serverless stack:

If you answered "no" or "not sure" to several of these, you likely have exploitable serverless misconfiguration today.

Next Steps