@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
Markdown
# 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.