Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
254 changes: 254 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
# Security Implementation Guide for NeoNest

This document outlines the comprehensive security measures implemented to protect NeoNest users and data.

## 🔒 Security Features Implemented

### 1. Cross-Site Request Forgery (CSRF) Protection
- **Location**: `lib/csrf.js`
- **Implementation**: Token-based CSRF protection for all state-changing requests
- **Usage**: Automatically applied via security middleware

### 2. Cross-Site Scripting (XSS) Prevention
- **Components Fixed**:
- `app/components/TextToSpeech.js`
- `app/components/SpeechRecognition.js`
- **Implementation**: Input sanitization and output encoding
- **Protection**: Prevents malicious script injection

### 3. Server-Side Request Forgery (SSRF) Prevention
- **Location**: `lib/urlValidator.js`
- **Implementation**: URL validation with allowlist approach
- **Features**:
- Domain allowlisting
- Private IP range blocking
- Protocol validation (HTTPS only)

### 4. Input Validation & Sanitization
- **Location**: `lib/auth.js`, `lib/security.js`
- **Implementation**: Comprehensive input validation
- **Features**:
- Type checking
- Length validation
- XSS pattern detection
- SQL injection prevention

### 5. Rate Limiting
- **Location**: `lib/security.js`
- **Implementation**: In-memory rate limiting
- **Configuration**: 60 requests per minute per IP
- **Block Duration**: 15 minutes for violators

### 6. Enhanced Authentication
- **Location**: `app/api/auth/login/route.js`
- **Improvements**:
- Generic error messages (security through obscurity)
- Enhanced input validation
- Secure JWT generation
- Password data exclusion from responses

### 7. Security Headers
- **Implementation**: Added to all API responses
- **Headers**:
- `X-Content-Type-Options: nosniff`
- `X-Frame-Options: DENY`
- `X-XSS-Protection: 1; mode=block`

## 🛠 How to Use Security Features

### For API Routes

```javascript
import { withSecurity } from '@/lib/security';

async function myAPIHandler(req) {
// Your API logic here
return Response.json({ success: true });
}

// Apply security middleware
export const POST = withSecurity(myAPIHandler);
```

### For Client-Side Requests

```javascript
import { secureFetch } from '@/lib/clientSecurity';

// Secure API call with automatic CSRF protection
const response = await secureFetch('/api/data', {
method: 'POST',
body: JSON.stringify({ data: 'example' })
});
```

### Input Validation

```javascript
import { validateAndSanitizeInput } from '@/lib/security';

// Validate user input
if (!validateAndSanitizeInput(userInput, 'string', 100)) {
throw new Error('Invalid input');
}
```

### URL Validation for External Requests

```javascript
import { safeFetch } from '@/lib/urlValidator';

// Safe external API call
try {
const response = await safeFetch('https://api.example.com/data');
} catch (error) {
console.error('URL validation failed:', error.message);
}
```

## 🌐 Internationalization (i18n) Support

### Setup
- **Location**: `lib/i18n.js`
- **Supported Languages**: English, Spanish, Hindi
- **Usage**:

```javascript
import { t, setLanguage } from '@/lib/i18n';

// Set language
setLanguage('es');

// Translate text
const translatedText = t('login', 'Login');
```

### Adding New Languages

1. Edit `lib/i18n.js`
2. Add translations to the `translations` object
3. Update `getAvailableLanguages()` function

## 🔧 Configuration

### Environment Variables Required

```env
JWT_SECRET=your-super-secret-jwt-key-here
MONGODB_URI=your-mongodb-connection-string
```

### Security Configuration

The security middleware can be configured in `lib/security.js`:

```javascript
// Rate limiting configuration
this.maxRequestsPerMinute = 60;
this.blockDuration = 15 * 60 * 1000; // 15 minutes

// Allowed domains for external requests
const ALLOWED_DOMAINS = [
'api.openai.com',
'generativelanguage.googleapis.com',
'cloudinary.com'
];
```

## 🚨 Security Best Practices

### 1. Input Handling
- Always validate and sanitize user inputs
- Use parameterized queries for database operations
- Implement proper error handling

### 2. Authentication
- Use strong JWT secrets
- Implement proper session management
- Add logout functionality that clears tokens

### 3. API Security
- Apply security middleware to all API routes
- Use HTTPS in production
- Implement proper CORS policies

### 4. Client-Side Security
- Use the provided `secureFetch` wrapper
- Sanitize user inputs before display
- Validate forms on both client and server side

## 🔍 Security Testing

### Manual Testing Checklist

- [ ] CSRF protection works for POST/PUT/DELETE requests
- [ ] XSS attempts are blocked and sanitized
- [ ] Rate limiting triggers after 60 requests/minute
- [ ] Invalid URLs are rejected by SSRF protection
- [ ] Authentication requires valid JWT tokens
- [ ] Input validation rejects malicious payloads

### Automated Testing

Consider implementing:
- Unit tests for security functions
- Integration tests for API endpoints
- Security scanning tools (OWASP ZAP, etc.)

## 📋 Security Incident Response

### If a Security Issue is Discovered

1. **Immediate Response**:
- Document the issue
- Assess the impact
- Implement temporary mitigation

2. **Investigation**:
- Check logs for exploitation attempts
- Identify affected users/data
- Determine root cause

3. **Resolution**:
- Apply security patches
- Update security measures
- Notify affected users if necessary

4. **Prevention**:
- Update security documentation
- Improve testing procedures
- Conduct security review

## 🔄 Regular Security Maintenance

### Monthly Tasks
- Review and update dependencies
- Check for new security vulnerabilities
- Update security configurations

### Quarterly Tasks
- Conduct security audits
- Review access controls
- Update security documentation

### Annual Tasks
- Comprehensive penetration testing
- Security training for developers
- Review and update security policies

## 📞 Security Contact

For security-related issues or questions:
- Create a GitHub issue with the `security` label
- Follow responsible disclosure practices
- Provide detailed information about vulnerabilities

## 🔗 Additional Resources

- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [Next.js Security Guidelines](https://nextjs.org/docs/advanced-features/security-headers)
- [Node.js Security Best Practices](https://nodejs.org/en/docs/guides/security/)

---

**Note**: This security implementation provides a strong foundation, but security is an ongoing process. Regular updates and monitoring are essential for maintaining protection against evolving threats.
10 changes: 5 additions & 5 deletions app/Essentials/page.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { useState, useEffect } from "react";
import { useState, useEffect, useCallback } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/card";
import { Button } from "../components/ui/Button";
import Input from "../components/ui/Input";
Expand Down Expand Up @@ -47,7 +47,7 @@ export default function Page() {
};

// Fetch inventory from API
const fetchInventory = async () => {
const fetchInventory = useCallback(async () => {
try {
setIsInventoryLoading(true);
const token = getAuthToken();
Expand All @@ -70,14 +70,14 @@ export default function Page() {
} finally {
setIsInventoryLoading(false);
}
};
}, []);

useEffect(() => {
document.title = "Essentials | NeoNest";
if (isAuth) {
fetchInventory();
}
}, [isAuth]);
}, [isAuth, fetchInventory]);

// Add new item
const addItem = async () => {
Expand Down Expand Up @@ -515,7 +515,7 @@ export default function Page() {
</span>
</div>

{item.notes && <p className="text-sm text-gray-500 italic">"{item.notes}"</p>}
{item.notes && <p className="text-sm text-gray-500 italic">&quot;{item.notes}&quot;</p>}

<div className="flex gap-2">
<Button size="sm" variant="outline" onClick={() => setEditingItem(item)} className="flex-1">
Expand Down
2 changes: 1 addition & 1 deletion app/Login/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export default function LoginPage() {

{/* Signup Link */}
<p className="mt-6 text-sm text-center text-gray-600 dark:text-gray-200">
Don't have an account?{" "}
Don&apos;t have an account?{" "}
<a href="/Signup" className="text-pink-600 hover:text-pink-700 font-medium transition-colors duration-300 hover:underline">
Sign up here
</a>
Expand Down
6 changes: 3 additions & 3 deletions app/Lullaby/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,9 @@ export default function LullabyPage() {
</div>
{index === currentTrackIndex && isPlaying && (
<div className="flex items-center gap-1">
<span className="w-1 h-3 bg-pink-500 rounded-full animate-pulse" style={{ animationDelay: "0s" }}></span>
<span className="w-1 h-4 bg-pink-500 rounded-full animate-pulse" style={{ animationDelay: "0.2s" }}></span>
<span className="w-1 h-3 bg-pink-500 rounded-full animate-pulse" style={{ animationDelay: "0.4s" }}></span>
<span className="w-1 h-3 bg-pink-500 rounded-full animate-pulse [animation-delay:0s]"></span>
<span className="w-1 h-4 bg-pink-500 rounded-full animate-pulse [animation-delay:0.2s]"></span>
<span className="w-1 h-3 bg-pink-500 rounded-full animate-pulse [animation-delay:0.4s]"></span>
</div>
)}
</div>
Expand Down
16 changes: 8 additions & 8 deletions app/Medical/page.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"use client";
import { useState, useEffect } from "react";
import { useState, useEffect, useCallback } from "react";
import axios from "axios";
import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/card";
import Input from "../components/ui/Input";
Expand Down Expand Up @@ -74,9 +74,9 @@ export default function VaccineTracker({ babyId }) {
fetchVaccines();
// fetchBabyBirthDate()
}
}, [isAuth]);
}, [isAuth, fetchVaccines]);

const fetchVaccines = async () => {
const fetchVaccines = useCallback(async () => {
try {
const token = getAuthToken();
const res = await axios.get("/api/vaccine", {
Expand All @@ -86,7 +86,7 @@ export default function VaccineTracker({ babyId }) {
} catch (error) {
console.error("Error fetching vaccines:", error);
}
};
}, []);

const initializeStandardSchedule = async () => {
if (!babyBirthDate) return;
Expand Down Expand Up @@ -207,7 +207,7 @@ export default function VaccineTracker({ babyId }) {
<div className="flex flex-wrap items-center justify-between">
<div>
<h2 className="text-3xl font-bold text-gray-800 dark:text-gray-200">Medical Records: Vaccines & Important Contacts</h2>
<p className="text-gray-600 dark:text-gray-300">Keep track of your baby's vaccination schedule and essential medical contacts for quick access.</p>
<p className="text-gray-600 dark:text-gray-300">Keep track of your baby&apos;s vaccination schedule and essential medical contacts for quick access.</p>
</div>
<Button
onClick={() => {
Expand All @@ -227,11 +227,11 @@ export default function VaccineTracker({ babyId }) {
<CardHeader>
<CardTitle className="flex items-center gap-2 dark:text-gray-200">
<Calendar className="w-5 h-5 text-blue-600 dark:text-blue-500 " />
Set Baby's Birth Date
Set Baby&apos;s Birth Date
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-gray-600 dark:text-gray-200">Enter your baby's birth date to automatically generate the standard vaccination schedule.</p>
<p className="text-gray-600 dark:text-gray-200">Enter your baby&apos;s birth date to automatically generate the standard vaccination schedule.</p>
<div className="flex gap-4 flex-wrap">
<Input type="date" value={babyBirthDate} onChange={(e) => setBabyBirthDate(e.target.value)} className="max-w-xs dark:bg-gray-700 dark:text-gray-200" />
<Button onClick={initializeStandardSchedule} disabled={!babyBirthDate} className="bg-gradient-to-r from-blue-500 to-green-500 hover:from-blue-600 hover:to-green-600">
Expand Down Expand Up @@ -472,7 +472,7 @@ export default function VaccineTracker({ babyId }) {
<div>
<h4 className="font-medium">{vaccine.name}</h4>
<p className="text-sm text-gray-600 dark:text-gray-300">{vaccine.description || "No description"}</p>
{vaccine.notes && <p className="text-sm text-gray-500 italic">"{vaccine.notes}"</p>}
{vaccine.notes && <p className="text-sm text-gray-500 italic">&quot;{vaccine.notes}&quot;</p>}
</div>
</div>

Expand Down
Loading