Serverless Security: The AWS Lambda Static Analysis Standard

Engineering safety into the serverless stack. Automated static analysis for AWS Lambda to prevent event injection and IAM misconfigurations.

4 min read
Serverless Security: The AWS Lambda Static Analysis Standard
Share:

Serverless architectures introduce unique event injection risks. Here is the engineering standard for hardening AWS Lambda through automated static analysis, ensuring safety at the handler level.

Who Is This For?

This plugin is for Node.js teams building serverless applications on AWS:

FrameworkDescription
AWS LambdaNative function handlers
Serverless FrameworkMost popular serverless deployment tool
AWS SAM CLIAWS-native IaC for Lambda
Middy.jsMiddleware engine for Lambda (we have specific rules!)

If you deploy functions to Lambda โ€” whether via CDK, SAM, Serverless Framework, or raw CloudFormation โ€” this plugin catches security issues before they reach production.

Quick Install

bash
npm install --save-dev eslint-plugin-lambda-security

Flat Config

javascript
// eslint.config.js
import lambdaSecurity from "eslint-plugin-lambda-security";

export default [lambdaSecurity.configs.recommended];

Rule Overview

Based on the OWASP Serverless Top 10:

RuleOWASPWhat it catches
no-unvalidated-event-bodyS1, S10Injection via event
no-missing-authorization-checkS2No auth in handlers
no-exposed-error-detailsS3Stack traces in errors
no-unbounded-batch-processingS4Large batch DoS
no-overly-permissive-iam-policyS5* in IAM
no-permissive-cors-responseS6CORS misconfiguration
no-error-swallowingS7Empty catch blocks
no-secrets-in-envS8Secrets in env vars
no-user-controlled-requestsS9SSRF
no-env-loggingS3Env logged
no-hardcoded-credentials-sdkS8AWS creds in code
no-permissive-cors-middyS6Middy CORS
require-timeout-handlingS4No timeout fallback

Run ESLint

bash
npx eslint .

You'll see output like:

bash
src/handlers/api.ts
  12:5  error  ๐Ÿ”’ OWASP-S3 | Error details exposed to client
               Fix: Return generic error message, log details internally

src/handlers/batch.ts
  28:3  error  ๐Ÿ”’ OWASP-S4 | Unbounded batch processing detected
               Fix: Add batch size limit: records.slice(0, 100)

src/config/cors.ts
  8:1   error  ๐Ÿ”’ OWASP-S6 | Permissive CORS origin '*'
               Fix: Specify allowed origins: ['https://app.example.com']

Quick Wins

Error Handling

javascript
// โŒ Dangerous: Exposes stack trace
export const handler = async (event) => {
  try {
    return await processEvent(event);
  } catch (error) {
    return { statusCode: 500, body: JSON.stringify({ error: error.stack }) };
  }
};

// โœ… Safe: Generic error, internal logging
export const handler = async (event) => {
  try {
    return await processEvent(event);
  } catch (error) {
    console.error("Handler error:", error); // Logged to CloudWatch
    return {
      statusCode: 500,
      body: JSON.stringify({ error: "Internal error" }),
    };
  }
};

CORS Configuration

javascript
// โŒ Dangerous: Wildcard origin
return {
  statusCode: 200,
  headers: { "Access-Control-Allow-Origin": "*" },
  body: JSON.stringify(data),
};

// โœ… Safe: Explicit origin
return {
  statusCode: 200,
  headers: { "Access-Control-Allow-Origin": "https://app.example.com" },
  body: JSON.stringify(data),
};

Custom Configuration

Add specific rules or customize options:

javascript
// eslint.config.js
import lambdaSecurity from "eslint-plugin-lambda-security";

export default [
  lambdaSecurity.configs.recommended,
  {
    rules: {
      // Override severity
      "lambda-security/no-error-swallowing": "warn",

      // Configure with options
      "lambda-security/no-unbounded-batch-processing": [
        "error",
        {
          maxBatchSize: 50,
        },
      ],

      // Disable a rule
      "lambda-security/no-env-logging": "off",
    },
  },
];

Strongly-Typed Options (TypeScript)

The plugin exports types for IDE autocompletion:

typescript
// eslint.config.ts
import lambdaSecurity, {
  type RuleOptions,
} from "eslint-plugin-lambda-security";

const batchOptions: RuleOptions["no-unbounded-batch-processing"] = {
  maxBatchSize: 100,
  allowedSources: ["SQS", "Kinesis"],
};

export default [
  lambdaSecurity.configs.recommended,
  {
    rules: {
      "lambda-security/no-unbounded-batch-processing": ["error", batchOptions],
    },
  },
];

Quick Reference

bash
# Install
npm install --save-dev eslint-plugin-lambda-security

# Config (eslint.config.js)
import lambdaSecurity from 'eslint-plugin-lambda-security';
export default [lambdaSecurity.configs.recommended];

# Run
npx eslint .

๐Ÿ“ฆ npm: eslint-plugin-lambda-security ๐Ÿ“– OWASP Serverless Mapping

โญ Star on GitHub


The Interlace ESLint Ecosystem Interlace is a high-fidelity suite of static code analyzers designed to automate security, performance, and reliability for the modern Node.js stack. With over 330 rules across 18 specialized plugins, it provides 100% coverage for OWASP Top 10, LLM Security, and Database Hardening.

Explore the full Documentation

ยฉ 2026 Ofri Peretz. All rights reserved.


Build Securely. I'm Ofri Peretz, a Security Engineering Leader and the architect of the Interlace Ecosystem. I build static analysis standards that automate security and performance for Node.js fleets at scale.

ofriperetz.dev | LinkedIn | GitHub

Built with Nuxt UI โ€ข ยฉ 2026 Ofri Peretz