> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API and Infrastructure Security

> API and infrastructure security audit for Express.js apps highlighting misconfigurations, risks, PoCs, and minimal remediations for CORS, rate limiting, headers, JWTs, and request limits.

This lesson covers API and infrastructure security for an Express.js application. Whether your API is public-facing, internal, or restricted to specific customers, apply security controls to protect endpoints and the application surface.

Below are excerpts from an automated audit run that frame the issues we address: configuration gaps, exploitability notes, concise proofs-of-concept (PoCs), and minimal drop-in remediations.

Audit interactive output (example)

```text theme={null}
/help for help, /status for your current setup

Cwd: /Users/jeremy/Repos/Claude Code Course/Express-login-demo

> Try "how do I log an error?"

? for shortcuts
```

The audit prompt used for the run asked for a focused API & infrastructure security review and to produce a structured finding report:

```text theme={null}
## API & Infrastructure Security

Review API-specific security configurations.

Check for:
1. CORS configuration
  - Not using wildcard (*) in production
  - Proper origin validation
  - Credentials handling

2. Rate Limiting
  - Implemented on all endpoints
  - Different limits for different operations
  - Distributed rate limiting for scaled apps

3. API Versioning security
  - Deprecated version handling
  - Breaking change management

4. Request size limits
  - Body parser limits
  - File upload restrictions
  - JSON depth limits

5. HTTP Security Headers
  - Helmet.js configuration
  - CSP headers
  - X-Frame-Options
  - X-Content-Type-Options
  - Strict-Transport-Security

6. API key/token management
  - Secure storage
  - Rotation policy
  - Scope limitations

7. Error handling
  - No stack traces in production
  - Generic error messages
  - Proper status codes

## Provide:

A structured finding report with the following for each issue:
Title, Severity (Critical/High/Medium/Low), CWE (if applicable), Evidence (file, function, line ranges), Why it matters, Exploitability notes, (safe) PoC/reproduction steps, Remediation (code/config change), summary risk score (0–10), top 3–5 prioritized fixes, and a checklist diff marking items Pass/Fail/N/A.

Constraints: Be concrete and cite exact code locations and identifiers. Prefer minimal, drop-in fix snippets. If context is missing, mark as Unable to verify and say what code would prove it.
```

The audit run produced a structured report for an example Express login app and highlighted several missing controls (CORS configuration, rate limiting, security headers, request size limits, weak JWT secret handling, etc.).

Search & audit snippets captured during the run:

```text theme={null}
Search(pattern: "console\.log|console\.error|console\.warn", output_mode: "content")
└ Found 725 lines

Search(pattern: "stack|trace", glob: "routes/*.js", output_mode: "content")
└ Found 0 lines

Update Todos
├ ☒ Explore codebase structure and identify main application files
├ ☒ Analyze CORS configuration
├ ☒ Check rate limiting implementation
├ ☒ Review API versioning security
├ ☒ Examine request size limits
├ ☒ Audit HTTP security headers
├ ☒ Review API key/token management
├ ☒ Analyze error handling security
└ ☐ Generate structured security audit report

Write(audits/API_INFRASTRUCTURE_SECURITY_AUDIT.md)
└ Wrote 379 lines to audits/API_INFRASTRUCTURE_SECURITY_AUDIT.md
```

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/Xs8Ruv7b0QCZf7iM/images/Claude-Code-for-Beginners/Security-Auditing-with-Claude-Code/API-and-Infrastructure-Security/vscode-api-infra-audit-express-login.jpg?fit=max&auto=format&n=Xs8Ruv7b0QCZf7iM&q=85&s=c3b608eb726343a3bc2f9748d99217e2" alt="A screenshot of a code editor (Visual Studio Code) displaying a Markdown &#x22;API & Infrastructure Security Audit Report&#x22; for an Express.js login app, showing an executive summary, risk score, and detailed findings (e.g., missing CORS configuration). The left sidebar shows project files and folders for the app." width="1920" height="1080" data-path="images/Claude-Code-for-Beginners/Security-Auditing-with-Claude-Code/API-and-Infrastructure-Security/vscode-api-infra-audit-express-login.jpg" />
</Frame>

***

## Executive summary

* Primary gaps found: missing or permissive CORS, no rate limiting, absent request size limits, missing HTTP security headers, weak JWT secret handling, and inconsistent error handling.
* Immediate high-impact fixes: add per-route rate limiting on authentication endpoints, enable Helmet.js with sane defaults, set `express.json({ limit: '100kb' })`, and replace weak secrets.
* Example overall risk: High (example score 8.5 / 10).
* Always prefer least-privilege, short token TTLs, and defense-in-depth (WAF, gateway rate limiting, central logging).

<Callout icon="warning" color="#FF6B6B">
  This audit is focused on configuration and implementation. If a code artifact (file or function) is missing from the repository, mark the finding as "Unable to verify" and list the specific file(s) that would prove the configuration (e.g., `app.js`, `server.js`, `routes/auth.js`, `config/jwt.js`).
</Callout>

***

## Common findings, PoCs, and minimal remediations

Note: Do not invent files or functions that aren't present in the codebase. If the audit cannot verify something, mark it as "Unable to verify" and list the artifact that would prove the configuration.

### 1) CORS misconfiguration (Critical)

Problem: Using `*` for Access-Control-Allow-Origin in production, or no origin validation, allows cross-site pages to call your API and may enable credentialed requests from untrusted origins.

PoC (malicious site calling your API)

```html theme={null}
<!-- Malicious website can call API without restriction -->
<script>
fetch('http://localhost:3000/api/auth/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email: 'victim@example.com', password: 'guessed' })
}).then(r => console.log('CORS Response:', r.status));
</script>
```

Minimal remediation (strict allowlist and origin validation)

```javascript theme={null}
// javascript
const express = require('express');
const cors = require('cors');

const app = express();
const whitelist = ['https://app.example.com', 'https://admin.example.com'];

app.use(cors({
  origin: function (origin, callback) {
    // Allow requests with no origin (mobile/native/CLI)
    if (!origin) return callback(null, true);
    if (whitelist.indexOf(origin) !== -1) return callback(null, true);
    return callback(new Error('CORS policy violation'));
  },
  credentials: true // enable only if necessary and used over TLS
}));
```

If CORS cannot be found in the codebase, mark as Unable to verify and point auditors to the server entry file (e.g., `app.js`, `server.js`) where `app.use(cors(...))` should appear.

Related reading:

* cors package: [https://www.npmjs.com/package/cors](https://www.npmjs.com/package/cors)

***

### 2) Rate limiting (Critical)

Problem: Without rate limiting, attackers can brute-force auth endpoints or perform request floods.

PoC (curl brute-force loop)

```bash theme={null}
# bash
for i in {1..1000}; do
  curl -s -X POST http://localhost:3000/api/auth/login \
    -H "Content-Type: application/json" \
    -d '{"email":"victim@test.com","password":"guess'"$i"'"}'
done
```

Minimal remediation (per-route limiter using express-rate-limit)

```javascript theme={null}
// javascript
const rateLimit = require('express-rate-limit');

// Auth endpoint limiter
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 10, // limit each IP to 10 requests per windowMs
  standardHeaders: true,
  legacyHeaders: false
});

app.use('/api/auth/', authLimiter);
```

For scaled deployments, use a distributed store (e.g., Redis) and a compatible adapter like `rate-limit-redis` or implement gateway-level limits.

Related reading:

* express-rate-limit: [https://www.npmjs.com/package/express-rate-limit](https://www.npmjs.com/package/express-rate-limit)
* rate-limit-redis: [https://www.npmjs.com/package/rate-limit-redis](https://www.npmjs.com/package/rate-limit-redis)

***

### 3) Request size limits / Body parsing (High)

Problem: Unbounded request bodies allow memory exhaustion and DoS.

PoC (send a very large JSON payload)

```bash theme={null}
# bash
curl -X POST http://localhost:3000/api/auth/login \
  -H "Content-Type: application/json" \
  -d "$(python3 -c "import json; print(json.dumps({'email':'test@test.com','password':'%s' % ('x'*50000000)}))")"
```

Minimal remediations

```javascript theme={null}
// javascript
app.use(express.json({ limit: '100kb' })); // tune per app
app.use(express.urlencoded({ extended: true, limit: '100kb' }));
```

For file uploads, use multer with limits:

```javascript theme={null}
// javascript
const multer = require('multer');
const upload = multer({
  limits: { fileSize: 5 * 1024 * 1024 } // 5 MB
});
app.post('/api/upload', upload.single('file'), (req, res) => { /*...*/ });
```

Validate payloads and enforce schema limits with Ajv or similar to constrain depth and keys:

* Ajv: [https://ajv.js.org/](https://ajv.js.org/)

***

### 4) HTTP security headers (Critical)

Problem: Missing headers (CSP, X-Frame-Options, X-Content-Type-Options, HSTS) increase attack surface for content injection, clickjacking, and protocol downgrade.

Minimal remediation (Helmet with CSP override)

```javascript theme={null}
// javascript
const helmet = require('helmet');

app.use(helmet()); // sets a secure baseline

app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'"],
      styleSrc: ["'self'"],
      imgSrc: ["'self'", 'data:'],
      fontSrc: ["'self'"]
    }
  })
);
```

Confirm headers:

```bash theme={null}
# bash
curl -I https://your-api.example.com/ | grep -E "(X-Frame-Options|Content-Security-Policy|X-Content-Type-Options|Strict-Transport-Security)"
```

Helmet docs:

* [https://www.npmjs.com/package/helmet](https://www.npmjs.com/package/helmet)

***

### 5) JWT secret and token management (High)

Problem: Hardcoded or guessable JWT secret allows token forging and privilege escalation.

Example insecure `.env`

```text theme={null}
# .env
JWT_SECRET=your_jwt_secret_key_here
```

PoC (forge token if secret known)

```javascript theme={null}
// javascript
const jwt = require('jsonwebtoken');
const forgedToken = jwt.sign(
  { userId: 1, email: 'admin@example.com' },
  'your_jwt_secret_key_here'
);
```

Remediations:

* Generate a strong secret: `require('crypto').randomBytes(64).toString('hex')`.
* Store secrets in environment variables or a secrets manager (Vault, AWS Secrets Manager, GCP Secret Manager).
* Short-lived access tokens + refresh tokens with revocation list.
* Rotate secrets and support token revocation where feasible.

If JWT usage is not verifiable, mark as Unable to verify and indicate files to inspect: token creation functions, auth middleware, and config files.

***

### 6) API versioning security (High)

Problem: Old API versions can harbor vulnerabilities.

Recommendations:

* Use versioned routes: `/api/v1/`, `/api/v2/`.
* Return deprecation headers for old versions and 410 for removed endpoints.
* Patch or disable old versions; maintain a documented deprecation policy.

***

### 7) Error handling and information disclosure (Medium)

Problem: Returning stack traces or full error objects in responses exposes internal implementation details.

Minimal remediation (sanitized error handler)

```javascript theme={null}
// javascript
app.use((err, req, res, next) => {
  const isProd = process.env.NODE_ENV === 'production';
  const payload = isProd
    ? { message: 'Internal Server Error' }
    : { message: err.message, stack: err.stack };
  res.status(err.status || 500).json(payload);
});
```

Audit note: Search for `console.log`, `console.error` and middleware that exposes `err.stack`. Replace direct console output with structured logging to a secure sink (e.g., a log service).

***

## Structured report expectations (per finding)

For each issue include:

* Title
* Severity (Critical/High/Medium/Low)
* CWE (if applicable)
* Evidence (file path, function name, line ranges)
* Why it matters (concise)
* Exploitability notes and safe PoC or reproduction steps
* Remediation: precise code/config change with a minimal snippet
* Defense-in-depth recommendations
* Summary risk score (0–10)
* Top 3–5 prioritized fixes
* A checklist diff marking items from the “Check for” list as Pass / Fail / Not Applicable

Constraints: Be concrete and cite exact code locations and identifiers. Prefer minimal drop-in fixes. If evidence is missing, mark as Unable to verify and list the artifact that would prove the configuration.

***

## Condensed example audit summary

Quick security checklist (high level)

| Area | Status (example) |
| - | - |
| CORS configuration | FAIL (wildcard or missing) |
| Rate limiting | FAIL |
| Request size limits | FAIL |
| HTTP security headers | FAIL |
| JWT secret management | FAIL (weak/hardcoded) |
| Error handling | PARTIAL (some sensitive logs/outputs) |
| API versioning | FAIL/PARTIAL |

Risk assessment (example)

* Critical: CORS, Rate Limiting, Security Headers
* High: Request Limits, JWT Secret, Versioning
* Medium: Error handling, HSTS enforcement missing

Priority remediation (recommended order)

1. Replace weak or hardcoded JWT secrets and use secure secret storage.
2. Add rate limiting on auth and other sensitive endpoints.
3. Enable Helmet with secure defaults and set a CSP.
4. Configure a strict CORS allowlist and credentials handling.
5. Enforce request body and file upload limits and validate payloads.

Overall example risk score: 8.5 / 10 — High Risk

<Callout icon="lightbulb" color="#1CB2FE">
  Immediate low-effort, high-impact fixes: add express-rate-limit to authentication routes, enable Helmet with sane defaults, and set `express.json({ limit: '100kb' })`. These reduce attack surface quickly.
</Callout>

***

## Tests and verification examples

* Verify HTTP security headers:

```bash theme={null}
# bash
curl -I https://your-api.example.com/ | grep -E "(Content-Security-Policy|X-Frame-Options|X-Content-Type-Options|Strict-Transport-Security)"
```

* CORS check (browser-like request)

```javascript theme={null}
// javascript (from a web page)
fetch('https://your-api.example.com/api/auth/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email: 'test@test.com', password: 'test' })
}).then(r => console.log('CORS Response:', r.status));
```

* Rate-limit verification: repeat requests to an endpoint and confirm 429 responses when limits are exceeded.

* JWT secret verification: search for `process.env.JWT_SECRET` or look for hardcoded strings used with `jsonwebtoken.sign(...)`.

***

## Production readiness checklist (operational recommendations)

* Store secrets in a secrets manager or platform-provided environment variables.
* Centralize logging and monitoring for rate-limit events and anomalies.
* Deploy a WAF or API gateway for bot mitigation and distributed rate limiting.
* Implement an API versioning and deprecation policy to avoid long-lived insecure endpoints.
* Regularly audit third-party dependencies for vulnerabilities.

***

Thanks for reviewing. The audit artifacts and prompts used to generate these findings are available in the referenced repository if you want to replicate or extend these checks.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/claude-code-for-beginners/module/eaf75a67-f28f-4217-a3f9-92d411403129/lesson/02cb824b-3b98-441e-908a-8b34769020db" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.