Security Hardening
Proactive security improvement suggestions. Unlike vulnerability scanners
that find what is broken, this skill identifies what could be better --
defense-in-depth measures, missing security headers, insufficient input
validation, absent rate limiting, and other hardening opportunities that
reduce the blast radius of future vulnerabilities.
Supported Flags
Read ../../shared/schemas/flags.md for the full flag specification.
| Flag |
Hardening Behavior |
--scope |
Default changed. Use full for comprehensive hardening review. |
--depth quick |
Check for missing security headers and obvious hardening gaps only. |
--depth standard |
Full hardening review: headers, validation, logging, error handling, configuration. |
--depth deep |
Standard + analyze middleware chains, review all trust boundaries, check defense layering. |
--depth expert |
Deep + compare against security benchmarks (CIS, OWASP ASVS), generate hardening scorecard. |
--severity |
Filter suggestions by impact level. |
--format |
Default text. Use md for a hardening checklist document. |
Workflow
Step 1: Identify Technology Stack
Scan the codebase to determine:
- Web framework(s): Express, Django, Flask, Spring, Rails, Next.js, ASP.NET, FastAPI, etc.
- Deployment target: Container, serverless, VM, PaaS (from Dockerfile, serverless.yml, etc.).
- Reverse proxy/CDN: Nginx, Apache, Cloudflare, AWS ALB (from config files).
- Database(s): SQL, NoSQL, cache layers.
- Authentication mechanism: Session, JWT, OAuth, SAML.
- Existing security middleware: Helmet, django-security, Spring Security, etc.
Step 2: Check Security Headers
Verify the application sets these HTTP response headers (or that a reverse proxy / CDN handles them):
| Header |
Recommended Value |
Impact |
Content-Security-Policy |
Strict policy, no unsafe-inline / unsafe-eval |
Mitigates XSS |
Strict-Transport-Security |
max-age=31536000; includeSubDomains; preload |
Enforces HTTPS |
X-Content-Type-Options |
nosniff |
Prevents MIME sniffing |
X-Frame-Options |
DENY or SAMEORIGIN |
Prevents clickjacking |
Referrer-Policy |
strict-origin-when-cross-origin or stricter |
Limits referrer leakage |
Permissions-Policy |
Disable unused browser features |
Reduces attack surface |
Cross-Origin-Opener-Policy |
same-origin |
Prevents cross-origin attacks |
Cross-Origin-Resource-Policy |
same-origin |
Controls resource sharing |
Cache-Control |
no-store for sensitive responses |
Prevents cache leaks |
Note: If a reverse proxy config (nginx.conf, etc.) is present and sets these headers, do not flag them as missing from application code.
Step 3: Review CORS Configuration
Check for overly permissive CORS settings:
Access-Control-Allow-Origin: * on authenticated endpoints.
- Reflecting the
Origin header without validation.
Access-Control-Allow-Credentials: true with wildcard origins.
- Overly broad allowed methods or headers.
- Missing
Vary: Origin when origin is dynamic.
Step 4: Assess Input Validation
For each entry point discovered (or in scope):
- Schema validation: Are request bodies validated against a schema (Joi, Zod, Pydantic, JSON Schema)?
- Type coercion: Are string inputs properly typed before use?
- Length limits: Are string lengths bounded? Are array sizes limited?
- Allowlist vs denylist: Is validation positive (allowlist) rather than negative (denylist)?
- Nested input: Are deeply nested objects limited to prevent DoS?
- File validation: Are uploaded files validated beyond extension (magic bytes, size limits)?
Step 5: Check Rate Limiting
Identify endpoints that should have rate limiting:
- Authentication endpoints: Login, registration, password reset, MFA verification.
- API endpoints: Especially those that are computationally expensive or return sensitive data.
- File upload endpoints: To prevent storage exhaustion.
- Search/query endpoints: To prevent enumeration and DoS.
Check if rate limiting is implemented and whether limits are reasonable.
Step 6: Review Error Handling and Information Disclosure
- Stack traces: Are stack traces exposed in production error responses?
- Verbose errors: Do error messages reveal internal paths, versions, or database details?
- Error differentiation: Do auth errors distinguish between "user not found" and "wrong password" (enables enumeration)?
- Default error pages: Are framework default error pages replaced?
- Debug mode: Is debug mode disabled in production configuration?
Step 7: Assess Security Logging
Check that these security-relevant events are logged:
- Authentication events: Login success/failure, logout, password changes.
- Authorization failures: Access denied events with user and resource context.
- Input validation failures: Rejected requests with sanitized details.
- Administrative actions: Config changes, user management, privilege changes.
- Sensitive data access: Audit trail for PII/financial data reads.
Verify logs do NOT contain: passwords, tokens, credit card numbers, SSNs, or other sensitive data.
Step 8: Check Defensive Coding Patterns
- Fail-closed defaults: Do authorization checks default to deny?
- Secure defaults: Are new configurations secure by default?
- Least privilege: Do database connections, API keys, and service accounts use minimal permissions?
- Timeout configuration: Do HTTP clients, database connections, and external calls have timeouts?
- Resource limits: Are memory/CPU-intensive operations bounded?
- Dependency security: Is
npm audit / pip audit / equivalent run in CI?
Step 9: Report
Output hardening suggestions grouped by category.
Output Format
Hardening suggestions are advisory and use a lighter format than vulnerability findings.
## Security Hardening Report
### Summary
- Hardening suggestions: N
- By priority: N HIGH, N MEDIUM, N LOW
- Categories covered: headers, cors, validation, rate-limiting, logging, error-handling, config
### HIGH Priority
#### [H-001] Missing Content-Security-Policy header
**Category**: Headers | **Effort**: Low
**Location**: src/middleware/security.ts
**Current**: No CSP header set
**Recommended**: Add strict CSP via helmet
```js
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:"],
}
}));
MEDIUM Priority
...
LOW Priority
...
When hardening gaps represent actual vulnerabilities (e.g., CORS misconfiguration allowing credential theft), emit a formal finding using `../../shared/schemas/findings.md`.
Finding ID prefix: **HARD** (e.g., `HARD-001`).
- `metadata.tool`: `"harden"`
- `references.cwe`: Varies by suggestion (e.g., `CWE-693` Protection Mechanism Failure, `CWE-16` Configuration)
## Pragmatism Notes
- Hardening is contextual. An internal admin tool has different requirements than a public API.
- Do not recommend CSP for a CLI tool or rate limiting for a batch job.
- If a CDN or reverse proxy handles headers, note that rather than flagging missing headers in app code.
- Prioritize suggestions that are easy to implement with high security impact.
- Acknowledge when existing security measures are already good. Not every review needs findings.
- Some frameworks (Next.js, Rails) include secure defaults. Credit what is already done well.
---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/florianbuetow) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-13 -->
1---2name: florianbuetow-claude-code-harden3description: Security Hardening4---56# Security Hardening78Proactive security improvement suggestions. Unlike vulnerability scanners9that find what is broken, this skill identifies what could be better --10defense-in-depth measures, missing security headers, insufficient input11validation, absent rate limiting, and other hardening opportunities that12reduce the blast radius of future vulnerabilities.1314## Supported Flags1516Read `../../shared/schemas/flags.md` for the full flag specification.1718| Flag | Hardening Behavior |19|------|-------------------|20| `--scope` | Default `changed`. Use `full` for comprehensive hardening review. |21| `--depth quick` | Check for missing security headers and obvious hardening gaps only. |22| `--depth standard` | Full hardening review: headers, validation, logging, error handling, configuration. |23| `--depth deep` | Standard + analyze middleware chains, review all trust boundaries, check defense layering. |24| `--depth expert` | Deep + compare against security benchmarks (CIS, OWASP ASVS), generate hardening scorecard. |25| `--severity` | Filter suggestions by impact level. |26| `--format` | Default `text`. Use `md` for a hardening checklist document. |2728## Workflow2930### Step 1: Identify Technology Stack3132Scan the codebase to determine:33341. **Web framework(s)**: Express, Django, Flask, Spring, Rails, Next.js, ASP.NET, FastAPI, etc.352. **Deployment target**: Container, serverless, VM, PaaS (from Dockerfile, serverless.yml, etc.).363. **Reverse proxy/CDN**: Nginx, Apache, Cloudflare, AWS ALB (from config files).374. **Database(s)**: SQL, NoSQL, cache layers.385. **Authentication mechanism**: Session, JWT, OAuth, SAML.396. **Existing security middleware**: Helmet, django-security, Spring Security, etc.4041### Step 2: Check Security Headers4243Verify the application sets these HTTP response headers (or that a reverse proxy / CDN handles them):4445| Header | Recommended Value | Impact |46|--------|------------------|--------|47| `Content-Security-Policy` | Strict policy, no `unsafe-inline` / `unsafe-eval` | Mitigates XSS |48| `Strict-Transport-Security` | `max-age=31536000; includeSubDomains; preload` | Enforces HTTPS |49| `X-Content-Type-Options` | `nosniff` | Prevents MIME sniffing |50| `X-Frame-Options` | `DENY` or `SAMEORIGIN` | Prevents clickjacking |51| `Referrer-Policy` | `strict-origin-when-cross-origin` or stricter | Limits referrer leakage |52| `Permissions-Policy` | Disable unused browser features | Reduces attack surface |53| `Cross-Origin-Opener-Policy` | `same-origin` | Prevents cross-origin attacks |54| `Cross-Origin-Resource-Policy` | `same-origin` | Controls resource sharing |55| `Cache-Control` | `no-store` for sensitive responses | Prevents cache leaks |5657Note: If a reverse proxy config (nginx.conf, etc.) is present and sets these headers, do not flag them as missing from application code.5859### Step 3: Review CORS Configuration6061Check for overly permissive CORS settings:62631. `Access-Control-Allow-Origin: *` on authenticated endpoints.642. Reflecting the `Origin` header without validation.653. `Access-Control-Allow-Credentials: true` with wildcard origins.664. Overly broad allowed methods or headers.675. Missing `Vary: Origin` when origin is dynamic.6869### Step 4: Assess Input Validation7071For each entry point discovered (or in scope):72731. **Schema validation**: Are request bodies validated against a schema (Joi, Zod, Pydantic, JSON Schema)?742. **Type coercion**: Are string inputs properly typed before use?753. **Length limits**: Are string lengths bounded? Are array sizes limited?764. **Allowlist vs denylist**: Is validation positive (allowlist) rather than negative (denylist)?775. **Nested input**: Are deeply nested objects limited to prevent DoS?786. **File validation**: Are uploaded files validated beyond extension (magic bytes, size limits)?7980### Step 5: Check Rate Limiting8182Identify endpoints that should have rate limiting:83841. **Authentication endpoints**: Login, registration, password reset, MFA verification.852. **API endpoints**: Especially those that are computationally expensive or return sensitive data.863. **File upload endpoints**: To prevent storage exhaustion.874. **Search/query endpoints**: To prevent enumeration and DoS.8889Check if rate limiting is implemented and whether limits are reasonable.9091### Step 6: Review Error Handling and Information Disclosure92931. **Stack traces**: Are stack traces exposed in production error responses?942. **Verbose errors**: Do error messages reveal internal paths, versions, or database details?953. **Error differentiation**: Do auth errors distinguish between "user not found" and "wrong password" (enables enumeration)?964. **Default error pages**: Are framework default error pages replaced?975. **Debug mode**: Is debug mode disabled in production configuration?9899### Step 7: Assess Security Logging100101Check that these security-relevant events are logged:1021031. **Authentication events**: Login success/failure, logout, password changes.1042. **Authorization failures**: Access denied events with user and resource context.1053. **Input validation failures**: Rejected requests with sanitized details.1064. **Administrative actions**: Config changes, user management, privilege changes.1075. **Sensitive data access**: Audit trail for PII/financial data reads.108109Verify logs do NOT contain: passwords, tokens, credit card numbers, SSNs, or other sensitive data.110111### Step 8: Check Defensive Coding Patterns1121131. **Fail-closed defaults**: Do authorization checks default to deny?1142. **Secure defaults**: Are new configurations secure by default?1153. **Least privilege**: Do database connections, API keys, and service accounts use minimal permissions?1164. **Timeout configuration**: Do HTTP clients, database connections, and external calls have timeouts?1175. **Resource limits**: Are memory/CPU-intensive operations bounded?1186. **Dependency security**: Is `npm audit` / `pip audit` / equivalent run in CI?119120### Step 9: Report121122Output hardening suggestions grouped by category.123124## Output Format125126Hardening suggestions are advisory and use a lighter format than vulnerability findings.127128```129## Security Hardening Report130131### Summary132- Hardening suggestions: N133- By priority: N HIGH, N MEDIUM, N LOW134- Categories covered: headers, cors, validation, rate-limiting, logging, error-handling, config135136### HIGH Priority137138#### [H-001] Missing Content-Security-Policy header139**Category**: Headers | **Effort**: Low140**Location**: src/middleware/security.ts141**Current**: No CSP header set142**Recommended**: Add strict CSP via helmet143```js144app.use(helmet.contentSecurityPolicy({145 directives: {146 defaultSrc: ["'self'"],147 scriptSrc: ["'self'"],148 styleSrc: ["'self'", "'unsafe-inline'"],149 imgSrc: ["'self'", "data:"],150 }151}));152```153154### MEDIUM Priority155...156157### LOW Priority158...159```160161When hardening gaps represent actual vulnerabilities (e.g., CORS misconfiguration allowing credential theft), emit a formal finding using `../../shared/schemas/findings.md`.162163Finding ID prefix: **HARD** (e.g., `HARD-001`).164165- `metadata.tool`: `"harden"`166- `references.cwe`: Varies by suggestion (e.g., `CWE-693` Protection Mechanism Failure, `CWE-16` Configuration)167168## Pragmatism Notes169170- Hardening is contextual. An internal admin tool has different requirements than a public API.171- Do not recommend CSP for a CLI tool or rate limiting for a batch job.172- If a CDN or reverse proxy handles headers, note that rather than flagging missing headers in app code.173- Prioritize suggestions that are easy to implement with high security impact.174- Acknowledge when existing security measures are already good. Not every review needs findings.175- Some frameworks (Next.js, Rails) include secure defaults. Credit what is already done well.176177---178> Converted and distributed by [TomeVault](https://tomevault.io/claim/florianbuetow) — claim your Tome and manage your conversions.179<!-- tomevault:4.0:skill_md:2026-04-13 -->