security-hardening
Security Hardening and Secure Coding
OWASP Top 10 (2021) -- Overview and Practical Mitigations
A01: Broken Access Control
- Deny by default. Enforce server-side authorization on every request.
- Use RBAC or ABAC. Disable directory listing. Log repeated access-control failures.
A02: Cryptographic Failures
- Encrypt PII at rest (AES-256-GCM) and in transit (TLS 1.2+).
- Hash passwords with bcrypt, scrypt, or Argon2id. Rotate encryption keys on schedule.
A03: Injection
- Use parameterized queries or prepared statements for all database access.
- Validate and sanitize every input server-side. Use ORMs with parameterized bindings.
A04: Insecure Design
- Threat model (STRIDE, DREAD) during design. Apply least privilege, defense in depth, fail-safe defaults.
A05: Security Misconfiguration
- Remove default credentials and debug endpoints in production. Automate configuration audits.
A06: Vulnerable and Outdated Components
- Maintain an SBOM. Run dependency scanning in CI. Subscribe to security advisories.
A07: Identification and Authentication Failures
- Enforce strong passwords (12+ characters, check breached-password lists). Require MFA for privileged accounts.
- Regenerate session IDs after login. Set short idle timeouts.
A08: Software and Data Integrity Failures
- Verify dependency integrity via lockfiles and checksums. Sign commits and releases.
A09: Security Logging and Monitoring Failures
- Log auth attempts, authorization failures, and privilege changes. Centralize logs. Never log secrets or PII.
A10: Server-Side Request Forgery (SSRF)
- Allowlist URLs before server-side requests. Block private IP ranges. Use network-level controls.
Input Validation
Always validate on the server side. Client-side validation is a convenience for users, not a security control.
Principles
- Prefer allowlists over denylists. Define what is permitted, reject everything else.
- Validate type, length, range, and format for every input field.
- Reject unexpected input early, before it reaches business logic or data stores.
- Canonicalize inputs before validation (decode URL encoding, normalize Unicode).
Example: Server-Side Validation
// Allowlist approach: only permit expected characters
function validateUsername(input) {
const ALLOWED = /^[a-zA-Z0-9_]{3,30}$/;
if (!ALLOWED.test(input)) {
throw new Error('Invalid username format');
}
return input;
}
// Numeric validation with range checking
function validateAge(input) {
const age = Number(input);
if (!Number.isInteger(age) || age < 0 || age > 150) {
throw new Error('Invalid age');
}
return age;
}
SQL Injection Prevention
Parameterized Queries
// VULNERABLE: string concatenation
const result = db.query(`SELECT * FROM users WHERE id = ${req.params.id}`);
// SAFE: parameterized query
const result = db.query('SELECT * FROM users WHERE id = $1', [req.params.id]);
# VULNERABLE
cursor.execute(f"SELECT * FROM users WHERE email = '{email}'")
# SAFE: parameterized
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))
ORM Usage
- ORMs generate parameterized queries by default. Use query builders instead of raw SQL.
- When raw SQL is required, still use parameterized bindings. Audit ORM queries in development.
XSS Prevention
Output Encoding
- Encode all dynamic content before inserting into HTML, JavaScript, CSS, or URL contexts.
- Use context-aware encoding: HTML entity encoding for HTML body, JavaScript escaping for script contexts, URL encoding for URL parameters.
// HTML context: encode before insertion
function escapeHtml(str) {
return str
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
Content Security Policy (CSP)
- Deploy CSP headers to restrict sources of scripts, styles, images, and other resources.
- Avoid
unsafe-inlineandunsafe-eval. Use nonces or hashes for inline scripts when necessary.
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self'; img-src 'self' data:; object-src 'none'; base-uri 'self'; frame-ancestors 'none'
Sanitization
- For user-supplied HTML (rich text editors), use a proven library (DOMPurify, bleach). Never write custom sanitizers.
- Strip
javascript:URIs, event handler attributes, and dangerous elements (<script>,<iframe>,<object>).
CSRF Protection
Token-Based Protection
- Generate a unique, unpredictable CSRF token per session. Include in a hidden form field or custom header.
- Validate server-side on every state-changing request. Regenerate tokens on login.
SameSite Cookies
- Set
SameSite=Laxas a minimum on all session cookies. UseSameSite=Strictwhere cross-site navigation is not needed. - Combine SameSite with CSRF tokens for defense in depth. SameSite alone does not cover all browsers or scenarios.
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/
Security Headers
Apply these headers to every HTTP response in production.
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
| Header | Purpose |
|---|---|
| Content-Security-Policy | Controls which resources the browser may load. Primary defense against XSS. |
| Strict-Transport-Security | Forces HTTPS for all future requests. Prevents protocol downgrade attacks. |
| X-Frame-Options | Prevents clickjacking by blocking framing of the page. |
| X-Content-Type-Options | Stops browsers from MIME-sniffing responses away from the declared content type. |
| Referrer-Policy | Controls how much referrer information is sent with requests. |
| Permissions-Policy | Restricts which browser features (camera, mic, geolocation) the page may use. |
CORS Configuration
- Default to the most restrictive policy: do not set CORS headers unless cross-origin access is required.
- Never use
Access-Control-Allow-Origin: *withAccess-Control-Allow-Credentials: true. Browsers reject this, but the intent reveals a misunderstanding. - Allowlist specific origins. Validate the
Originheader against the allowlist on every request. - Restrict
Access-Control-Allow-MethodsandAccess-Control-Allow-Headersto only what is needed.
// Express example: explicit origin allowlist
const allowedOrigins = ['https://app.example.com', 'https://admin.example.com'];
app.use((req, res, next) => {
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
}
res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
next();
});
Rate Limiting and Brute Force Protection
- Apply rate limiting to authentication endpoints, password reset, and API routes.
- Use sliding window or token bucket algorithms. Return
429 Too Many RequestswithRetry-After. - Implement account lockout after repeated failures (e.g., 5 failures in 10 minutes, 15-minute lockout).
- Rate limit by IP, by account, and by API key independently. Consider CAPTCHA after threshold failures.
File Upload Security
Validation
- Validate file type by inspecting magic bytes, not just extension or client-provided MIME type.
- Enforce maximum file size at web server and application level. Allowlist permitted extensions.
Storage
- Store uploads outside the web root. Rename to random UUIDs; never use the original filename.
- Scan uploads for malware (ClamAV or equivalent).
Serving
- Set
Content-Disposition: attachmentfor downloads. Serve uploads from a separate domain. - Set
X-Content-Type-Options: nosniffto prevent MIME-type sniffing.
Environment Variable Security
.env Files
- Never commit
.envfiles. Add.envto.gitignorebefore the first commit. - Provide
.env.examplewith placeholder values. Restrict file permissions in production (chmod 600).
Secrets Management
- Use a dedicated secrets manager (Vault, AWS Secrets Manager, GCP Secret Manager) in production.
- Rotate secrets on schedule and after any suspected compromise. Never log secrets.
- Prefer short-lived, scoped credentials (IAM roles, OIDC tokens) over static API keys.
Pre-Commit Checks
- Use git-secrets, TruffleHog, or gitleaks in pre-commit hooks.
- Scan full repo history periodically; removed secrets persist in git history.
Dependency Security
- Run
npm audit,pip audit, or equivalent on every CI build. Fail on high/critical vulnerabilities. - Enable Dependabot or Renovate for automated dependency update PRs.
- Use Snyk or Socket for transitive dependency and supply chain analysis.
- Commit lockfiles (
package-lock.json,yarn.lock,poetry.lock) and review changes to them. - Pin dependency versions in production. Audit new dependencies before adding them.
Docker Security
Image Construction
- Use minimal base images (
alpine,distroless,scratch) to reduce attack surface. - Run processes as a non-root user. Add a
USERinstruction in the Dockerfile. - Use multi-stage builds to exclude build tools and source code from the final image.
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
RUN npm run build
FROM node:20-alpine
RUN addgroup -S app && adduser -S app -G app
WORKDIR /app
COPY /app/dist ./dist
COPY /app/node_modules ./node_modules
USER app
EXPOSE 3000
CMD ["node", "dist/server.js"]
Secrets and Scanning
- Never embed secrets in images (ENV, ARG, or COPY). They persist in image layers.
- Pass secrets at runtime via mounted volumes or orchestrator secrets (Kubernetes Secrets, Docker Swarm).
- Scan images with Trivy, Grype, or Snyk Container.
HTTPS Everywhere
- Enforce TLS 1.2 minimum; prefer TLS 1.3. Redirect all HTTP to HTTPS with 301.
- Deploy HSTS with
max-age=63072000; includeSubDomains; preload. Submit to hstspreload.org. - Use strong cipher suites. Disable CBC-mode ciphers and anything below 128-bit.
- Automate certificate renewal (Let's Encrypt/certbot). Test with SSL Labs for an A+ rating.
Logging Security Events
What to Log
- Authentication successes and failures (username, IP, timestamp; never passwords).
- Authorization failures, input validation failures, privilege escalation events, and admin actions.
How to Log Safely
- Use structured logging (JSON). Never log secrets, tokens, passwords, or PII.
- Send logs to a centralized system (ELK, Splunk, CloudWatch, Datadog). Set retention policies.
- Alert on anomalous patterns: spikes in failed logins, unusual data access volumes.
Server Hardening
SSH Configuration
- Disable password authentication; use SSH key pairs only. Disable root login (
PermitRootLogin no). - Use
AllowUsersorAllowGroupsto restrict SSH access. Enable fail2ban to block brute force attempts.
Firewall Basics
- Default-deny inbound traffic. Open only required ports (22, 80, 443).
- Restrict management ports to specific IP ranges or VPN. Log denied connections.
General Hardening
- Disable unused services and uninstall unnecessary packages. Automate OS patching.
- Enable SELinux or AppArmor. Set filesystem permissions following least privilege.
Secrets Management
HashiCorp Vault
- Access secrets via the Vault API. Authenticate using AppRole, Kubernetes auth, or cloud IAM.
- Use dynamic secrets (short-lived database credentials on demand). Enable audit logging.
AWS Secrets Manager / GCP Secret Manager / Azure Key Vault
- Store secrets in the cloud provider's manager. Use IAM policies to restrict access. Enable auto-rotation.
Environment-Based Secrets (When No Secrets Manager Is Available)
- Inject secrets as environment variables at deploy time via CI/CD or orchestrator.
- Never bake secrets into images, version-controlled config, or client-side code.
- Rotate immediately after team member departure or suspected leak.
Security Checklist
- All inputs validated server-side with allowlist approach
- Parameterized queries used for all database access
- Output encoding applied in all rendering contexts
- CSP header deployed and tested
- CSRF tokens on all state-changing requests
- Security headers (HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy) configured
- CORS restricted to specific required origins
- Rate limiting on authentication and sensitive endpoints
- File uploads validated, stored outside web root, and served safely
- No secrets in version control; .env in .gitignore
- Dependency vulnerabilities scanned in CI
- Docker images run as non-root with minimal base
- TLS 1.2+ enforced; HSTS deployed with preload
- Security events logged without sensitive data leakage
- SSH hardened; firewall default-deny configured
- Secrets managed through a dedicated secrets manager or injected at deploy time
Tools
- npm audit / pip audit / bundler-audit -- dependency vulnerability scanning
- Snyk / Socket -- supply chain and transitive dependency analysis
- Dependabot / Renovate -- automated dependency update PRs
- TruffleHog / gitleaks / git-secrets -- secret scanning in repositories
- Trivy / Grype -- container image vulnerability scanning
- OWASP ZAP / Burp Suite -- dynamic application security testing
- SonarQube -- static analysis for code quality and security
- ClamAV -- malware scanning for file uploads
- fail2ban -- brute force protection for SSH and other services
- SSL Labs (ssllabs.com/ssltest) -- TLS configuration testing
- HashiCorp Vault / AWS Secrets Manager -- secrets management
References
- OWASP Top 10: https://owasp.org/www-project-top-ten/
- OWASP Cheat Sheet Series: https://cheatsheetseries.owasp.org/
- CWE/SANS Top 25: https://cwe.mitre.org/top25/
- NIST Cybersecurity Framework: https://www.nist.gov/cyberframework
- Mozilla Web Security Guidelines: https://infosec.mozilla.org/guidelines/web_security
- HSTS Preload List Submission: https://hstspreload.org/
More from 1mangesh1/dev-skills-collection
curl-http
HTTP request construction and API testing with curl and HTTPie. Use when user asks to "test API", "make HTTP request", "curl POST", "send request", "test endpoint", "debug API", "upload file", "check response time", "set auth header", "basic auth with curl", "send JSON", "test webhook", "check status code", "follow redirects", "rate limit testing", "measure API latency", "stress test endpoint", "mock API response", or any HTTP calls from the command line.
28database-indexing
Database indexing internals, index type selection, query plan analysis, and write-overhead tradeoffs across PostgreSQL, MySQL, and MongoDB. Use when user asks to "optimize queries", "create indexes", "fix slow queries", "read EXPLAIN output", "reduce query time", "index strategy", "database performance", "composite index", "covering index", "partial index", "index bloat", "unused indexes", or needs help diagnosing and resolving database performance problems.
13testing-strategies
Testing strategies, patterns, and methodologies across the full testing spectrum. Use when asked about unit tests, integration tests, e2e tests, test pyramid, mocking, test doubles, TDD, property-based testing, snapshot testing, test coverage, mutation testing, contract testing, performance testing, test data management, CI/CD testing, flaky tests, test anti-patterns, test organization, test isolation, test fixtures, test parameterization, or any testing strategy, approach, or methodology.
10secret-scanner
This skill should be used when the user asks to "scan for secrets", "find API keys", "detect credentials", "check for hardcoded passwords", "find leaked tokens", "scan for sensitive keys", "check git history for secrets", "audit repository for credentials", or mentions secret detection, credential scanning, API key exposure, token leakage, password detection, or security key auditing.
10terraform
Terraform infrastructure as code for provisioning, modules, state management, and workspaces. Use when user asks to "create infrastructure", "write Terraform", "manage state", "create module", "import resource", "plan changes", or any IaC tasks.
10kubernetes
Kubernetes and kubectl mastery for deployments, services, pods, debugging, and cluster management. Use when user asks to "deploy to k8s", "create deployment", "debug pod", "kubectl commands", "scale service", "check pod logs", "create ingress", or any Kubernetes tasks.
10