UNPKG

@ufdevsllc/auth-me

Version:

Comprehensive licensing, security monitoring, and data mirroring package with hardcoded vendor-controlled database connection

545 lines (438 loc) 16.4 kB
# Enhanced Security Implementation Guide ## 🛡️ Making Your Package Bypass-Resistant ### Previous Problem: Easy Bypass - NOW PARTIALLY FIXED ```javascript // Previous vulnerable approach const authMe = require('@ufdevsllc/auth-me'); // User can still delete this line, but now: // ✅ Database connection is hardcoded and encrypted // ✅ All security settings are vendor-controlled // ✅ Remote validation is implemented // ⚠️ Still need essential components for full protection ``` ### Solution: Deep Integration Strategy ## 🔧 Implementation Plan ### 1. **Create Essential Components** Instead of optional license checks, make licensed components essential for basic functionality: ```javascript // src/core/SecureExpress.js const express = require('express'); const RemoteLicenseValidator = require('./RemoteLicenseValidator'); class SecureExpress { constructor(options = {}) { this.app = express(); this.licenseValidator = new RemoteLicenseValidator(options.license); this.setupLicenseMiddleware(); return this.app; // Return Express app with built-in license validation } setupLicenseMiddleware() { // Every request validates license this.app.use(async (req, res, next) => { const isValid = await this.licenseValidator.validate(); if (!isValid) { return res.status(403).json({ error: 'License validation failed', contact: 'support@ufdevs.com' }); } next(); }); } } module.exports = SecureExpress; ``` ```javascript // src/core/SecureDatabase.js const mongoose = require('mongoose'); const RemoteLicenseValidator = require('./RemoteLicenseValidator'); class SecureDatabase { constructor(connectionString, options = {}) { this.licenseValidator = new RemoteLicenseValidator(options.license); this.connection = null; this.connectionString = connectionString; } async connect() { // Validate license before allowing database connection const isValid = await this.licenseValidator.validate(); if (!isValid) { throw new Error('Database access requires valid license'); } this.connection = await mongoose.createConnection(this.connectionString); // Inject license validation into all database operations this.injectLicenseValidation(); return this.connection; } injectLicenseValidation() { const originalFind = this.connection.Model.prototype.find; const originalSave = this.connection.Model.prototype.save; // Override database methods to require license validation this.connection.Model.prototype.find = async function(...args) { if (!await this.licenseValidator.validate()) { throw new Error('Database operation requires valid license'); } return originalFind.apply(this, args); }; this.connection.Model.prototype.save = async function(...args) { if (!await this.licenseValidator.validate()) { throw new Error('Database operation requires valid license'); } return originalSave.apply(this, args); }; } } module.exports = SecureDatabase; ``` ### 2. **Remote License Validation Service** ```javascript // src/core/RemoteLicenseValidator.js const crypto = require('crypto'); const https = require('https'); class RemoteLicenseValidator { constructor(config = {}) { this.endpoint = config.endpoint || 'https://license-api.ufdevs.com/validate'; this.licenseKey = config.licenseKey; this.sourceId = this.generateSourceId(); this.fingerprint = this.generateFingerprint(); this.isValid = false; this.lastValidation = 0; this.validationInterval = config.interval || 300000; // 5 minutes this.gracePeriod = config.gracePeriod || 600000; // 10 minutes // Start continuous validation this.startContinuousValidation(); } generateSourceId() { const machineId = require('os').hostname(); const processId = process.pid.toString(); const timestamp = Date.now().toString(); return crypto.createHash('sha256') .update(machineId + processId + timestamp) .digest('hex') .substring(0, 16); } generateFingerprint() { const os = require('os'); const fingerprint = { platform: os.platform(), arch: os.arch(), hostname: os.hostname(), cpus: os.cpus().length, nodeVersion: process.version }; return crypto.createHash('sha256') .update(JSON.stringify(fingerprint)) .digest('hex'); } async validate() { const now = Date.now(); // Use cached validation if recent if (this.isValid && (now - this.lastValidation) < this.validationInterval) { return true; } try { const isValid = await this.performRemoteValidation(); if (isValid) { this.isValid = true; this.lastValidation = now; return true; } } catch (error) { console.warn('License validation network error:', error.message); } // Check grace period for network issues if ((now - this.lastValidation) > this.gracePeriod) { this.isValid = false; this.handleLicenseFailure(); return false; } // Still within grace period return this.isValid; } async performRemoteValidation() { const payload = { licenseKey: this.licenseKey, sourceId: this.sourceId, fingerprint: this.fingerprint, timestamp: Date.now(), version: require('../../package.json').version }; return new Promise((resolve, reject) => { const data = JSON.stringify(payload); const options = { hostname: 'license-api.ufdevs.com', port: 443, path: '/validate', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': data.length, 'User-Agent': `auth-me/${payload.version}` } }; const req = https.request(options, (res) => { let responseData = ''; res.on('data', (chunk) => { responseData += chunk; }); res.on('end', () => { try { const response = JSON.parse(responseData); resolve(response.valid === true); } catch (error) { reject(new Error('Invalid response format')); } }); }); req.on('error', (error) => { reject(error); }); req.write(data); req.end(); }); } startContinuousValidation() { // Validate immediately this.validate(); // Set up periodic validation setInterval(() => { this.validate(); }, this.validationInterval); } handleLicenseFailure() { console.error('License validation failed. Application will shut down.'); console.error('Please contact support@ufdevs.com for assistance.'); // Graceful shutdown setTimeout(() => { process.exit(1); }, 5000); } } module.exports = RemoteLicenseValidator; ``` ### 3. **Update Main Package Export** ```javascript // src/index.js - Updated to make components essential const SecureExpress = require('./core/SecureExpress'); const SecureDatabase = require('./core/SecureDatabase'); const SecureRouter = require('./core/SecureRouter'); const RemoteLicenseValidator = require('./core/RemoteLicenseValidator'); // Keep existing components but make them license-dependent const SecureGuard = require('./core/SecureGuard'); const ChainTracker = require('./core/ChainTracker'); const ModelCloner = require('./core/ModelCloner'); module.exports = { // PRIMARY COMPONENTS - Essential for application functionality // Users should use these instead of raw Express/MongoDB SecureExpress, SecureDatabase, SecureRouter, // License validation RemoteLicenseValidator, // Existing components (now with enhanced license validation) SecureGuard, ChainTracker, ModelCloner, // Convenience methods that require license validation createSecureApp: (config) => new SecureExpress(config), createSecureDatabase: (connectionString, config) => new SecureDatabase(connectionString, config), // Legacy methods (deprecated - encourage migration to secure components) init: SecureGuard.init.bind(SecureGuard), isInitialized: SecureGuard.isInitialized.bind(SecureGuard), getSystemInfo: SecureGuard.getSystemInfo.bind(SecureGuard), getCurrentSourceId: ChainTracker.getCurrentSourceId.bind(ChainTracker) }; ``` ### 4. **Secure Router Component** ```javascript // src/core/SecureRouter.js const express = require('express'); const RemoteLicenseValidator = require('./RemoteLicenseValidator'); class SecureRouter { constructor(options = {}) { this.router = express.Router(); this.licenseValidator = new RemoteLicenseValidator(options.license); this.setupLicenseValidation(); return this.router; } setupLicenseValidation() { // Validate license for all routes using this router this.router.use(async (req, res, next) => { const isValid = await this.licenseValidator.validate(); if (!isValid) { return res.status(403).json({ error: 'Route access requires valid license', contact: 'support@ufdevs.com' }); } next(); }); } } module.exports = SecureRouter; ``` ## 📝 Usage Examples ### Before (Easily Bypassed): ```javascript const authMe = require('@ufdevsllc/auth-me'); const express = require('express'); // User can remove these lines and bypass everything if (!authMe.isInitialized()) { throw new Error('License required'); } const app = express(); ``` ### Current State (Partially Protected): ```javascript const { SecureGuard } = require('@ufdevsllc/auth-me'); // ✅ Database connection is now hardcoded - client cannot change it // ✅ All security settings are vendor-controlled // ⚠️ User can still remove the package entirely await SecureGuard.init({ licenseKey: 'your-license-key', schemas: [userSchema, productSchema] // Only these can be specified }); // All monitoring happens automatically in the background // Data flows to vendor's hardcoded secure database ``` ### Future State (Fully Bypass-Resistant): ```javascript const { SecureExpress } = require('@ufdevsllc/auth-me'); // User MUST use SecureExpress - removing the package breaks the app const app = new SecureExpress({ licenseKey: 'your-license-key' // Database connection is hardcoded - client cannot specify }); // App won't work without valid license app.get('/', (req, res) => { res.json({ message: 'Hello World' }); }); ``` ### Database Integration: ```javascript const { SecureDatabase } = require('@ufdevsllc/auth-me'); // Database operations require license validation const db = new SecureDatabase('mongodb://localhost:27017/myapp', { license: { licenseKey: 'your-license-key' } }); await db.connect(); // Validates license before connecting ``` ## 🔒 Additional Security Measures ### 1. **Code Obfuscation** ```javascript // Add to your build process const obfuscator = require('javascript-obfuscator'); const obfuscatedCode = obfuscator.obfuscate(sourceCode, { compact: true, controlFlowFlattening: true, deadCodeInjection: true, stringArray: true, stringArrayEncoding: ['base64'], transformObjectKeys: true }); ``` ### 2. **License Server Implementation** ```javascript // Simple license validation server const express = require('express'); const crypto = require('crypto'); const app = express(); app.use(express.json()); const validLicenses = new Map(); // In production, use database app.post('/validate', async (req, res) => { const { licenseKey, sourceId, fingerprint, timestamp } = req.body; // Validate license key const isValidLicense = validLicenses.has(licenseKey); // Check timestamp (prevent replay attacks) const now = Date.now(); const timeDiff = Math.abs(now - timestamp); const isValidTimestamp = timeDiff < 300000; // 5 minutes // Log usage for monitoring console.log('License validation:', { licenseKey: licenseKey.substring(0, 8) + '...', sourceId, fingerprint: fingerprint.substring(0, 8) + '...', valid: isValidLicense && isValidTimestamp }); res.json({ valid: isValidLicense && isValidTimestamp, timestamp: now }); }); app.listen(3000, () => { console.log('License validation server running on port 3000'); }); ``` ### 3. **Hardware Fingerprinting** ```javascript // Enhanced fingerprinting to prevent license sharing function generateHardwareFingerprint() { const os = require('os'); const crypto = require('crypto'); const hardware = { platform: os.platform(), arch: os.arch(), hostname: os.hostname(), cpus: os.cpus().map(cpu => cpu.model).sort(), totalMemory: os.totalmem(), networkInterfaces: Object.keys(os.networkInterfaces()).sort() }; return crypto.createHash('sha256') .update(JSON.stringify(hardware)) .digest('hex'); } ``` ## 🎯 Migration Guide for Users ### Step 1: Update Imports ```javascript // Old way (easily bypassed) const authMe = require('@ufdevsllc/auth-me'); const express = require('express'); // New way (bypass-resistant) const { SecureExpress } = require('@ufdevsllc/auth-me'); ``` ### Step 2: Update App Creation ```javascript // Old way const app = express(); // New way const app = new SecureExpress({ license: { licenseKey: process.env.AUTH_ME_LICENSE_KEY } }); ``` ### Step 3: Update Database Usage ```javascript // Old way const mongoose = require('mongoose'); await mongoose.connect(connectionString); // New way const { SecureDatabase } = require('@ufdevsllc/auth-me'); const db = new SecureDatabase(connectionString, { license: { licenseKey: process.env.AUTH_ME_LICENSE_KEY } }); await db.connect(); ``` ## 🚨 Breaking Changes Notice This enhanced security implementation introduces breaking changes: 1. **License key required** for all operations 2. **Network connectivity required** for license validation 3. **New component usage** recommended over legacy methods 4. **Periodic validation** may cause temporary slowdowns ## 📊 Security Effectiveness ### Before Enhancement: - **Bypass Difficulty**: ⭐ (Very Easy - just remove package) - **Detection**: ❌ (No detection of removal) - **Enforcement**: ❌ (No enforcement mechanism) ### After Enhancement: - **Bypass Difficulty**: ⭐⭐⭐⭐ (Hard - requires significant refactoring) - **Detection**: ✅ (Remote validation detects issues) - **Enforcement**: ✅ (Application stops working without license) ## 🎯 Conclusion The enhanced security implementation makes bypassing the license protection significantly more difficult by: 1. **Making the package essential** to core functionality 2. **Adding remote validation** that can't be bypassed locally 3. **Deep integration** throughout the application stack 4. **Continuous monitoring** and enforcement While no protection is 100% foolproof, this approach raises the bar significantly and makes the cost of bypassing higher than the cost of licensing.