Skip to content

drfawzyofficial/security

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ”’ Security Demo API

A production-grade, secure REST API built with Express.js 5 and MongoDB (Mongoose 9) that demonstrates 16 security layers applied to a user authentication system. Designed as a teaching resource and reference architecture for building hardened Node.js APIs.


πŸ“‹ Table of Contents


✨ Features

  • User Registration with strong password policy enforcement
  • User Login with account lockout after failed attempts
  • JWT Authentication with token blacklisting for secure logout
  • Password Change with re-authentication and old token revocation
  • Account Deletion with password re-confirmation
  • Profile Retrieval with sensitive data masking (prevents IDOR)
  • 16 layered security controls applied across the entire stack

πŸ›‘οΈ Security Layers

# Layer Technology / Technique
1 HTTP Security Headers helmet β€” sets ~14 browser security headers (CSP, HSTS, X-Frame-Options, etc.)
2 CORS (Cross-Origin Resource Sharing) Origin whitelist β€” only trusted front-ends can call the API
3 Global Rate Limiting express-rate-limit β€” 100 req / 15 min per IP
4 Auth Route Rate Limiting Stricter limit β€” 10 req / 15 min on login, signup, etc.
5 Body Size Limit express.json({ limit: '10kb' }) β€” prevents memory exhaustion
6 NoSQL Injection Prevention Custom sanitizer β€” strips $ and . operators from input
7 XSS Sanitization Custom HTML entity encoder β€” escapes <, >, ", ', &
8 HTTP Parameter Pollution hpp β€” deduplicates query parameters
9 Input Validation express-validator chains β€” validates and sanitises every field
10 Password Hashing bcryptjs with cost factor 12 (4096 iterations)
11 JWT Authentication Bearer token verification + signature validation
12 Token Blacklisting Revoked tokens stored in MongoDB with TTL auto-cleanup
13 Account Lockout 5 failed attempts β†’ 15-minute lock (brute-force defence)
14 Strong Password Policy Min 8 chars, uppercase, lowercase, digit, special character
15 Sensitive Data Masking safeUser() filter β€” password/lockout fields never returned
16 Global Error Handler No stack traces in production β€” generic error messages only

πŸ“ Project Structure

Security/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”œβ”€β”€ db.js              # MongoDB connection with Mongoose
β”‚   β”‚   └── env.js             # Fail-fast environment variable validation
β”‚   β”œβ”€β”€ controllers/
β”‚   β”‚   └── auth.controller.js # Signup, login, logout, change password, delete account, profile
β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   β”œβ”€β”€ auth.middleware.js  # JWT verification + blacklist check (protect)
β”‚   β”‚   └── validate.js        # Centralised express-validator error handler
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”œβ”€β”€ User.js            # User schema with bcrypt hashing + account lockout
β”‚   β”‚   └── TokenBlacklist.js  # JWT blacklist with MongoDB TTL index
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   └── auth.routes.js     # Auth routes with per-route security layers
β”‚   β”œβ”€β”€ validators/
β”‚   β”‚   └── auth.validator.js  # Input validation chains for all auth endpoints
β”‚   β”œβ”€β”€ app.js                 # Express app β€” middleware stack + routes
β”‚   └── server.js              # Entry point β€” connects DB and starts server
β”œβ”€β”€ .env.example               # Template for environment variables
β”œβ”€β”€ .gitignore
β”œβ”€β”€ package.json
└── README.md

πŸ”§ Prerequisites

  • Node.js v18 or later
  • MongoDB (local instance or MongoDB Atlas free tier)
  • npm (bundled with Node.js)

πŸš€ Installation

# 1. Clone the repository
git clone https://github.com/drfawzyofficial/security.git
cd security

# 2. Install dependencies
npm install

# 3. Create your environment file
cp .env.example .env
# Then edit .env with your actual values (see below)

πŸ”‘ Environment Variables

Create a .env file in the project root using .env.example as a template:

PORT=5000
NODE_ENV=development
MONGODB_URI=mongodb://localhost:27017/security_demo
JWT_SECRET=your_jwt_secret_here
JWT_EXPIRES_IN=7d
ALLOWED_ORIGINS=http://localhost:3000
Variable Required Default Description
PORT No 5000 Server port
NODE_ENV No development development shows full errors; production hides stack traces
MONGODB_URI Yes β€” MongoDB connection string
JWT_SECRET Yes β€” Secret key used to sign JWT tokens
JWT_EXPIRES_IN No 7d Token expiry duration (e.g. 1h, 7d, 30d)
ALLOWED_ORIGINS No http://localhost:3000 Comma-separated list of allowed CORS origins

⚠️ Never commit your .env file β€” it contains secrets. The .gitignore already excludes it.


▢️ Running the Server

Development (with auto-reload)

npm run dev

Production

npm start

The server will output:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
πŸ”’  Security Demo API β€” Running
    Mode  : development
    Port  : 5000
    URL   : http://localhost:5000
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

πŸ“‘ API Endpoints

All endpoints are prefixed with /api/auth.

Method Endpoint Auth Description
POST /api/auth/signup βœ— Register a new user
POST /api/auth/login βœ— Log in and receive JWT
POST /api/auth/logout βœ” JWT Revoke current token
PATCH /api/auth/change-password βœ” JWT Change password (re-auth required)
GET /api/auth/me βœ” JWT Get current user profile
DELETE /api/auth/account βœ” JWT Permanently delete account

Request / Response Examples

Signup

// POST /api/auth/signup
// Request Body:
{
  "name": "Ahmed Ali",
  "email": "ahmed@example.com",
  "password": "MyP@ssw0rd!"
}

// Response (201):
{
  "success": true,
  "message": "Account created successfully",
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "user": {
    "id": "...",
    "name": "Ahmed Ali",
    "email": "ahmed@example.com",
    "role": "user",
    "createdAt": "2026-04-16T..."
  }
}

Login

// POST /api/auth/login
// Request Body:
{
  "email": "ahmed@example.com",
  "password": "MyP@ssw0rd!"
}

// Response (200):
{
  "success": true,
  "message": "Logged in successfully",
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "user": { ... }
}

Change Password

// PATCH /api/auth/change-password
// Headers: Authorization: Bearer <token>
// Request Body:
{
  "currentPassword": "MyP@ssw0rd!",
  "newPassword": "NewS3cur3P@ss!"
}

// Response (200):
{
  "success": true,
  "message": "Password changed successfully β€” please use the new token",
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "user": { ... }
}

πŸ§ͺ Testing with cURL

# Signup
curl -X POST http://localhost:5000/api/auth/signup \
  -H "Content-Type: application/json" \
  -d '{"name":"Test User","email":"test@example.com","password":"Test@1234"}'

# Login
curl -X POST http://localhost:5000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","password":"Test@1234"}'

# Get Profile (replace <TOKEN> with actual JWT)
curl http://localhost:5000/api/auth/me \
  -H "Authorization: Bearer <TOKEN>"

# Change Password
curl -X PATCH http://localhost:5000/api/auth/change-password \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <TOKEN>" \
  -d '{"currentPassword":"Test@1234","newPassword":"NewTest@5678"}'

# Logout
curl -X POST http://localhost:5000/api/auth/logout \
  -H "Authorization: Bearer <TOKEN>"

# Delete Account
curl -X DELETE http://localhost:5000/api/auth/account \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <TOKEN>" \
  -d '{"password":"NewTest@5678"}'

πŸ› οΈ Tech Stack

Package Version Purpose
express 5.x Web framework
mongoose 9.x MongoDB ODM
bcryptjs 3.x Password hashing
jsonwebtoken 9.x JWT generation & verification
helmet 8.x HTTP security headers
cors 2.x Cross-origin resource sharing
express-rate-limit 8.x Rate limiting
express-validator 7.x Input validation & sanitisation
hpp 0.2.x HTTP parameter pollution protection
dotenv 17.x Environment variable loading
nodemon 3.x Development auto-reload

πŸ“„ License

ISC


Built with ❀️ for teaching secure API development.

About

security

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors