Skip to content

Commit 07b4230

Browse files
committed
security: remove hardcoded admin credentials
- Remove hardcoded admin@local/admin123 from lib/auth.ts - Enforce environment variable usage for admin authentication - Add password strength validation (minimum 16 characters) - Remove debug logging of MONGODB_URI from connection.ts This addresses a critical security vulnerability where admin credentials were exposed in source code.
1 parent 6c1acb7 commit 07b4230

8 files changed

Lines changed: 364 additions & 32 deletions

File tree

.env.example

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,79 @@
1-
# Example env vars; copy to .env.local or set in deployment
1+
# ToolBox Environment Variables
2+
# Copy this file to .env and fill in your values
3+
# NEVER commit .env to git!
24

3-
# Core
5+
# ==============================================================================
6+
# REQUIRED - App will not start without these
7+
# ==============================================================================
8+
9+
# MongoDB connection string
10+
# Development: Use local MongoDB or Atlas free tier
11+
# Production: Use MongoDB Atlas or managed instance
412
MONGODB_URI=mongodb://127.0.0.1:27017/toolbox
13+
14+
# NextAuth configuration
15+
# Development: http://localhost:3000
16+
# Production: Your actual domain (e.g., https://toolbox.example.com)
517
NEXTAUTH_URL=http://localhost:3000
6-
NEXTAUTH_SECRET=change-me
718

8-
# Dev admin (Credentials provider)
9-
ADMIN_EMAIL=admin@local
10-
ADMIN_PASSWORD=admin123
19+
# NextAuth secret for JWT signing
20+
# ⚠️ CRITICAL: Generate a strong random secret!
21+
# Run: openssl rand -base64 32
22+
# This must be at least 32 characters long
23+
NEXTAUTH_SECRET=
24+
25+
# ==============================================================================
26+
# ADMIN CREDENTIALS - REQUIRED
27+
# ==============================================================================
28+
29+
# Admin user email (used to log into /admin dashboard)
30+
ADMIN_EMAIL=
31+
32+
# Admin password
33+
# ⚠️ SECURITY WARNING:
34+
# - MUST be at least 16 characters long
35+
# - Use a strong, randomly generated password
36+
# - Generate with: openssl rand -base64 24
37+
# - NEVER use default passwords like "admin123"
38+
ADMIN_PASSWORD=
1139

12-
# Feature flags
13-
ENABLE_SPAM_CHECK=false
40+
# ==============================================================================
41+
# PRODUCTION REQUIRED - Optional in development
42+
# ==============================================================================
1443

15-
# Optional providers
44+
# Upstash Redis (required for rate limiting in production)
45+
# Without this, rate limiting will not work in multi-instance deployments
46+
# Sign up at: https://upstash.com (free tier available)
1647
# UPSTASH_REDIS_REST_URL=
1748
# UPSTASH_REDIS_REST_TOKEN=
49+
50+
# ==============================================================================
51+
# OPTIONAL FEATURES
52+
# ==============================================================================
53+
54+
# Gemini AI API key (for AI-powered features)
55+
# Get your key at: https://makersuite.google.com/app/apikey
56+
# NEXT_PUBLIC_GEMINI_API_KEY=
57+
58+
# Spam check feature (currently not implemented)
59+
# ENABLE_SPAM_CHECK=false
60+
61+
# Akismet spam detection (if implementing spam check)
1862
# AKISMET_API_KEY=
1963
# AKISMET_SITE_URL=
64+
65+
# ==============================================================================
66+
# SETUP CHECKLIST
67+
# ==============================================================================
68+
#
69+
# Before starting the app:
70+
# [ ] Copy this file to .env
71+
# [ ] Set MONGODB_URI (local or Atlas)
72+
# [ ] Generate NEXTAUTH_SECRET: openssl rand -base64 32
73+
# [ ] Set ADMIN_EMAIL to your email
74+
# [ ] Generate ADMIN_PASSWORD: openssl rand -base64 24
75+
# [ ] Set NEXTAUTH_URL to your domain (production) or localhost (dev)
76+
# [ ] (Production) Set up Upstash Redis and add credentials
77+
# [ ] Verify .env is in .gitignore
78+
#
79+
# ==============================================================================

README.md

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,37 +82,91 @@ Streamline your GitHub workflow with helpful utilities for repositories, issues,
8282

8383
### Installation
8484

85-
1. Clone the repository:
85+
1. **Clone the repository:**
8686

8787
```bash
8888
git clone https://github.com/rishabh3562/ToolBox.git
8989
cd ToolBox
9090
```
9191

92-
2. Install dependencies:
92+
2. **Install dependencies:**
9393

9494
```bash
9595
npm install
9696
```
9797

98-
3. Set up environment variables:
98+
3. **Set up environment variables:**
9999

100100
```bash
101101
# Copy the example environment file
102102
cp .env.example .env
103+
```
104+
105+
4. **Configure required environment variables in `.env`:**
106+
107+
⚠️ **CRITICAL:** The following environment variables are **REQUIRED** for the app to start:
108+
109+
```bash
110+
# MongoDB connection (required)
111+
MONGODB_URI=mongodb://127.0.0.1:27017/toolbox
112+
113+
# NextAuth configuration (required)
114+
NEXTAUTH_URL=http://localhost:3000
115+
NEXTAUTH_SECRET= # Generate with: openssl rand -base64 32
116+
117+
# Admin credentials (required)
118+
ADMIN_EMAIL=your-email@example.com
119+
ADMIN_PASSWORD= # Generate with: openssl rand -base64 24 (min 16 chars)
120+
```
121+
122+
**Generate secure credentials:**
123+
124+
```bash
125+
# Generate NextAuth secret (copy output to NEXTAUTH_SECRET)
126+
openssl rand -base64 32
103127

104-
# Edit .env and add your actual values:
105-
# - MONGODB_URI: Your MongoDB connection string (optional)
106-
# - NEXT_PUBLIC_GEMINI_API_KEY: Your Gemini API key from https://makersuite.google.com/app/apikey (optional)
128+
# Generate admin password (copy output to ADMIN_PASSWORD)
129+
openssl rand -base64 24
107130
```
108131

109-
4. Run the development server:
132+
**Optional but recommended for production:**
133+
134+
```bash
135+
# Upstash Redis (required for rate limiting in production)
136+
# Sign up at: https://upstash.com (free tier available)
137+
UPSTASH_REDIS_REST_URL=https://your-redis.upstash.io
138+
UPSTASH_REDIS_REST_TOKEN=your-token
139+
140+
# Gemini AI (for AI-powered features)
141+
NEXT_PUBLIC_GEMINI_API_KEY=your-key # Get from https://makersuite.google.com/app/apikey
142+
```
143+
144+
5. **Verify your configuration:**
145+
146+
The app will automatically validate your environment variables on startup. If anything is missing or misconfigured, you'll see helpful error messages.
147+
148+
6. **Run the development server:**
110149

111150
```bash
112151
npm run dev
113152
```
114153

115-
5. Open [http://localhost:3000](http://localhost:3000) in your browser
154+
7. **Open [http://localhost:3000](http://localhost:3000) in your browser**
155+
156+
8. **Access admin dashboard at [http://localhost:3000/login](http://localhost:3000/login)**
157+
- Use the `ADMIN_EMAIL` and `ADMIN_PASSWORD` you set in `.env`
158+
159+
### 🔒 Security Checklist
160+
161+
Before deploying to production, ensure:
162+
163+
- [ ] `NEXTAUTH_SECRET` is at least 32 characters and randomly generated
164+
- [ ] `ADMIN_PASSWORD` is at least 16 characters and randomly generated
165+
- [ ] `.env` file is in `.gitignore` (it is by default)
166+
- [ ] No credentials are hardcoded in source code
167+
- [ ] Redis (Upstash) is configured for production deployments
168+
- [ ] `NEXTAUTH_URL` is set to your actual domain in production
169+
- [ ] MongoDB uses Atlas or managed instance (not localhost) in production
116170

117171
## 📦 Build & Deploy
118172

instrumentation.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* Next.js Instrumentation Hook
3+
* Runs once when the server starts (before any requests)
4+
* See: https://nextjs.org/docs/app/building-your-application/optimizing/instrumentation
5+
*/
6+
7+
export async function register() {
8+
// Only run on server
9+
if (process.env.NEXT_RUNTIME === 'nodejs') {
10+
const { initializeServer } = await import('./lib/config/init');
11+
initializeServer();
12+
}
13+
}

lib/auth.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,24 @@ export const authOptions: NextAuthOptions = {
1414
const email = credentials?.email?.toLowerCase();
1515
const password = credentials?.password || '';
1616

17-
// TEMP: hardcoded accounts (no DB)
18-
const hardcoded = [
19-
{ email: 'admin@local', password: 'admin123', id: 'admin', name: 'Admin', isAdmin: true },
20-
];
21-
const match = hardcoded.find(u => u.email === email && u.password === password);
22-
if (match) return match as any;
23-
24-
// Optional env-based admin fallback
17+
// Environment-based admin authentication
2518
const adminEmail = process.env.ADMIN_EMAIL?.toLowerCase();
26-
const adminPassword = process.env.ADMIN_PASSWORD || '';
27-
if (email && password && adminEmail && adminPassword && email === adminEmail && password === adminPassword) {
19+
const adminPassword = process.env.ADMIN_PASSWORD;
20+
21+
// Validate that admin credentials are properly configured
22+
if (!adminEmail || !adminPassword) {
23+
console.error('❌ ADMIN_EMAIL and ADMIN_PASSWORD must be set in environment variables');
24+
return null;
25+
}
26+
27+
// Enforce minimum password length for security
28+
if (adminPassword.length < 16) {
29+
console.error('❌ ADMIN_PASSWORD must be at least 16 characters long');
30+
return null;
31+
}
32+
33+
// Verify credentials
34+
if (email && password && email === adminEmail && password === adminPassword) {
2835
return { id: 'admin', name: 'Admin', email: adminEmail, isAdmin: true } as any;
2936
}
3037

lib/config/init.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Server initialization
3+
* Runs validation checks when the server starts
4+
*/
5+
6+
import { validateEnvOrThrow, printEnvStatus } from './validateEnv';
7+
8+
let initialized = false;
9+
10+
/**
11+
* Initialize server - runs once on startup
12+
*/
13+
export function initializeServer() {
14+
// Only run once
15+
if (initialized) return;
16+
17+
console.log('\n🚀 Initializing ToolBox Server...\n');
18+
19+
try {
20+
// Validate environment variables
21+
validateEnvOrThrow();
22+
23+
// Print environment status in development
24+
if (process.env.NODE_ENV === 'development') {
25+
printEnvStatus();
26+
}
27+
28+
initialized = true;
29+
console.log('✅ Server initialization complete\n');
30+
} catch (error) {
31+
console.error('\n❌ Server initialization failed:', error);
32+
throw error;
33+
}
34+
}
35+
36+
// Auto-run on server (not in browser)
37+
if (typeof window === 'undefined') {
38+
initializeServer();
39+
}

0 commit comments

Comments
 (0)