Files
shopify-ai-backup/review/FIXES_APPLIED.md
Developer 98c3b5f040
Some checks are pending
Build Android App (Capacitor) / Build Android APK (push) Waiting to run
fix security
2026-02-21 10:07:02 +00:00

6.0 KiB

Security & Functionality Fixes Applied

Date: February 21, 2026

Summary of Fixes Applied

Critical Fixes (Fixed)

1. Webhook Signature Verification Buffer Length Check

File: server.js:15162-15170 Issue: timingSafeEqual() throws error if buffer lengths differ, potentially bypassing verification. Fix: Added buffer length comparison before calling timingSafeEqual().

const sigBuffer = Buffer.from(signature);
const expectedBuffer = Buffer.from(expectedSignature);
if (sigBuffer.length !== expectedBuffer.length || !require('crypto').timingSafeEqual(sigBuffer, expectedBuffer)) {
  // reject
}

2. Duplicate Variable Declaration in Webhook Handler

File: server.js:15253 Issue: eventId was declared twice in the same function scope, causing SyntaxError. Fix: Removed the duplicate declaration at line 15253.

3. Session Secret Auto-Generation with Persistence

File: server.js:390-420 Issue: Session secret was regenerated on each restart, invalidating all sessions. Fix: Session secret is now persisted to generated-secrets.json and reused on restart.

const secretsFile = path.join(STATE_DIR, 'generated-secrets.json');
// Load existing secret or generate and persist new one

4. SQLCipher Key Validation

File: src/database/connection.js:18-29 Issue: SQLCipher key was only escaping quotes, not fully validating format. Fix: Added comprehensive key validation:

  • Minimum 32 characters
  • Must be hexadecimal only (0-9, a-f, A-F)
function validateSqlcipherKey(key) {
  if (!key || typeof key !== 'string') throw new Error('...');
  if (key.length < 32) throw new Error('...');
  if (!/^[a-fA-F0-9]+$/.test(key)) throw new Error('...');
  return true;
}

5. JSON Body Size Limit in External API

File: src/external-admin-api/handlers.js:108-131 Issue: No size limit on JSON body parsing, potential memory exhaustion. Fix: Added maxBodySize parameter (default 6MB) with streaming size check.

async function parseJsonBody(req, maxBodySize = 6 * 1024 * 1024) {
  // ... size tracking and rejection if exceeded
}

High Priority Fixes (Fixed)

6. CORS Headers

File: server.js:8940-8950 Issue: No explicit CORS configuration. Fix: Added comprehensive CORS headers to sendJson():

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers
  • Access-Control-Allow-Credentials

7. Pending Payment Session Cleanup

File: server.js:1130-1190 Issue: Pending payment sessions accumulate without cleanup. Fix: Added cleanupStalePendingPayments() function that:

  • Removes pending records older than 48 hours
  • Runs during periodic memory cleanup
  • Persists changes after cleanup

8. Builder State Debouncing

File: public/builder.js:19-46 Issue: Every property change triggered localStorage write (performance impact). Fix: Implemented debounced save with 500ms delay.

let builderStateSaveTimer = null;
function saveBuilderState(state) {
  pendingBuilderState = state;
  if (builderStateSaveTimer) clearTimeout(builderStateSaveTimer);
  builderStateSaveTimer = setTimeout(() => {
    localStorage.setItem(BUILDER_STATE_KEY, JSON.stringify(pendingBuilderState));
  }, 500);
}

File: server.js:8950-8975 Issue: Extracted archives could contain symlinks pointing outside workspace. Fix: Added scanForSymlinks() function that removes symlinks after extraction.

10. Enhanced Environment Validation

File: server.js:20672-20720 Issue: Limited production environment checks. Fix: Enhanced validation with:

  • Critical variables check (DATABASE_ENCRYPTION_KEY added)
  • Recommended variables warnings
  • Better console output formatting

Medium Priority Fixes (Fixed)

11. Dangerous File Type Blocking in Zip Extraction

File: server.js:8922-8927 Fix: Added blocking of potentially dangerous file types:

  • .exe, .bat, .cmd, .sh, .ps1, .vbs

Files Modified

  1. chat/server.js - Main server file (multiple fixes)
  2. chat/src/database/connection.js - Database connection with SQLCipher validation
  3. chat/src/external-admin-api/handlers.js - JSON body size limit
  4. chat/public/builder.js - State persistence debouncing

Remaining Recommendations (Non-Critical)

These are recommended but not critical for launch:

Post-Launch Items

  1. OAuth State in Database - Currently stored in memory, will be lost on restart/multi-instance
  2. Atomic Token Operations - Consider using database transactions for high-concurrency scenarios
  3. 2FA for Admin - Add two-factor authentication requirement for admin accounts
  4. IP-Based Admin Restrictions - Consider limiting admin panel access by IP

Testing Performed

  • Webhook signature verification with various buffer lengths
  • Session persistence across simulated restarts
  • SQLCipher key validation with various formats
  • JSON body parsing with oversized payloads
  • Builder state persistence under rapid changes
  • Zip extraction with path traversal attempts

Verification Steps

  1. Webhook Test:
curl -X POST http://localhost:4000/webhooks/dodo \
  -H "dodo-signature: sha256_invalid" \
  -d '{"test": true}'
# Should return 401, not crash
  1. Session Persistence Test:
  • Start server
  • Login as user
  • Restart server
  • Verify session still valid
  1. SQLCipher Test:
# Valid key
DATABASE_ENCRYPTION_KEY=0123456789abcdef0123456789abcdef node server.js
# Invalid key should fail with clear error
DATABASE_ENCRYPTION_KEY="invalid!key" node server.js

Conclusion

All critical and high-priority security and functionality issues have been addressed. The application is now ready for launch with the following improvements:

  • Robust webhook handling
  • Persistent session secrets
  • Validated SQLCipher keys
  • Protected JSON parsing
  • CORS support
  • Automatic cleanup of stale data
  • Better error handling and user feedback