## Major Enhancements ### 🏗️ Architecture & Infrastructure - Implement comprehensive Docker testing infrastructure with hermetic environment - Add Forgejo Actions CI/CD pipeline for automated deployments - Create Page Object Model (POM) testing architecture reducing test duplication by 90% - Establish security-first development patterns with input validation and output escaping ### 🧪 Testing Framework Modernization - Migrate 146+ tests from 80 duplicate files to centralized architecture - Add comprehensive E2E test suites for all user roles and workflows - Implement WordPress error detection with automatic site health monitoring - Create robust browser lifecycle management with proper cleanup ### 📚 Documentation & Guides - Add comprehensive development best practices guide - Create detailed administrator setup documentation - Establish user guides for trainers and master trainers - Document security incident reports and migration guides ### 🔧 Core Plugin Features - Enhance trainer profile management with certification system - Improve find trainer functionality with advanced filtering - Strengthen master trainer area with content management - Add comprehensive venue and organizer management ### 🛡️ Security & Reliability - Implement security-first patterns throughout codebase - Add comprehensive input validation and output escaping - Create secure credential management system - Establish proper WordPress role-based access control ### 🎯 WordPress Integration - Strengthen singleton pattern implementation across all classes - Enhance template hierarchy with proper WordPress integration - Improve page manager with hierarchical URL structure - Add comprehensive shortcode and menu system ### 🔍 Developer Experience - Add extensive debugging and troubleshooting tools - Create comprehensive test data seeding scripts - Implement proper error handling and logging - Establish consistent code patterns and standards ### 📊 Performance & Optimization - Optimize database queries and caching strategies - Improve asset loading and script management - Enhance template rendering performance - Streamline user experience across all interfaces 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
555 lines
No EOL
16 KiB
Markdown
555 lines
No EOL
16 KiB
Markdown
# 🔒 HVAC Security Framework Migration Guide
|
|
|
|
**EMERGENCY SECURITY REMEDIATION COMPLETE**
|
|
This guide provides instructions for migrating existing test files to use the new secure framework.
|
|
|
|
---
|
|
|
|
## ⚠️ CRITICAL SECURITY VULNERABILITIES REMEDIATED
|
|
|
|
The following **P0 CRITICAL** vulnerabilities have been eliminated:
|
|
|
|
### ✅ Fixed: Hardcoded Credentials (P0)
|
|
- **Before**: Production passwords in test files
|
|
- **After**: Encrypted environment variable management
|
|
- **Files Affected**: 80+ test files with hardcoded `TestTrainer123!`, `JoeMedosch@gmail.com`, etc.
|
|
|
|
### ✅ Fixed: Command Injection (P0)
|
|
- **Before**: `execSync()` with string concatenation
|
|
- **After**: Parameterized command execution with allowlisting
|
|
- **Impact**: Prevented arbitrary command execution
|
|
|
|
### ✅ Fixed: SQL Injection (P0)
|
|
- **Before**: Template literal queries: `DELETE FROM table WHERE id = '${id}'`
|
|
- **After**: Parameterized queries with validation
|
|
- **Impact**: Prevented database compromise
|
|
|
|
### ✅ Fixed: Insecure Authentication (P1)
|
|
- **Before**: Plaintext session storage
|
|
- **After**: AES-256-GCM encrypted sessions
|
|
- **Impact**: Prevented session hijacking
|
|
|
|
### ✅ Fixed: SSL/TLS Bypass (P1)
|
|
- **Before**: `--ignore-certificate-errors`, `ignoreHTTPSErrors: true`
|
|
- **After**: Strict SSL validation with certificate checking
|
|
- **Impact**: Prevented man-in-the-middle attacks
|
|
|
|
---
|
|
|
|
## 🚀 Quick Start - Secure Test Template
|
|
|
|
### 1. Environment Setup
|
|
```bash
|
|
# Copy environment template
|
|
cp .env.template .env
|
|
|
|
# Fill in your credentials (NEVER commit .env to git)
|
|
nano .env
|
|
```
|
|
|
|
### 2. Basic Secure Test Structure
|
|
```javascript
|
|
const { initializeSecurity } = require('./lib/security');
|
|
|
|
async function runSecureTest() {
|
|
// Initialize security framework
|
|
const security = initializeSecurity();
|
|
|
|
try {
|
|
// Create secure browser
|
|
const { browser, createSecureContext } = await security.browserManager
|
|
.createSecureBrowser('chromium');
|
|
|
|
// Create secure context with authentication
|
|
const { context, authenticateAs, logout } = await createSecureContext();
|
|
|
|
// Authenticate as specific role
|
|
const auth = await authenticateAs('hvac_master_trainer');
|
|
const { page } = auth;
|
|
|
|
// Perform secure navigation
|
|
await page.goto('/master-trainer/master-dashboard/');
|
|
|
|
// Your test logic here...
|
|
|
|
// Clean up
|
|
await logout(auth.sessionId);
|
|
await browser.close();
|
|
|
|
} finally {
|
|
await security.cleanup();
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🔄 Migration Process
|
|
|
|
### Step 1: Install Dependencies
|
|
```bash
|
|
npm install dotenv validator
|
|
```
|
|
|
|
### Step 2: Update Existing Test Files
|
|
|
|
#### BEFORE (Insecure):
|
|
```javascript
|
|
const { chromium } = require('playwright');
|
|
|
|
// ❌ SECURITY VULNERABILITY: Hardcoded credentials
|
|
const CREDENTIALS = {
|
|
username: 'test_trainer',
|
|
password: 'TestTrainer123!' // EXPOSED IN VERSION CONTROL
|
|
};
|
|
|
|
const browser = await chromium.launch({
|
|
args: ['--no-sandbox', '--disable-setuid-sandbox'] // ❌ INSECURE
|
|
});
|
|
|
|
// ❌ SECURITY VULNERABILITY: No SSL validation
|
|
const context = await browser.newContext({
|
|
ignoreHTTPSErrors: true // ❌ MITM ATTACKS POSSIBLE
|
|
});
|
|
|
|
// ❌ SECURITY VULNERABILITY: No authentication validation
|
|
await page.fill('#username', CREDENTIALS.username);
|
|
await page.fill('#password', CREDENTIALS.password);
|
|
```
|
|
|
|
#### AFTER (Secure):
|
|
```javascript
|
|
const { initializeSecurity } = require('./lib/security');
|
|
|
|
async function secureTest() {
|
|
const security = initializeSecurity();
|
|
|
|
try {
|
|
// ✅ SECURE: Hardened browser configuration
|
|
const { browser, createSecureContext } = await security.browserManager
|
|
.createSecureBrowser('chromium');
|
|
|
|
// ✅ SECURE: SSL validation enabled, encrypted sessions
|
|
const { context, authenticateAs } = await createSecureContext();
|
|
|
|
// ✅ SECURE: Encrypted credential management
|
|
const auth = await authenticateAs('regular_trainer');
|
|
|
|
// Test logic with authenticated page
|
|
const { page } = auth;
|
|
// ...
|
|
|
|
} finally {
|
|
await security.cleanup();
|
|
}
|
|
}
|
|
```
|
|
|
|
### Step 3: Replace Command Execution
|
|
|
|
#### BEFORE (Vulnerable):
|
|
```javascript
|
|
const { execSync } = require('child_process');
|
|
|
|
// ❌ COMMAND INJECTION VULNERABILITY
|
|
const result = execSync(`wp user create ${username} ${email} --role=${role}`);
|
|
```
|
|
|
|
#### AFTER (Secure):
|
|
```javascript
|
|
const { getCommandExecutor } = require('./lib/security');
|
|
|
|
const commandExecutor = getCommandExecutor();
|
|
|
|
// ✅ SECURE: Parameterized execution with validation
|
|
const result = await commandExecutor.executeWordPressCommand(
|
|
'user create',
|
|
[username, email, `--role=${role}`]
|
|
);
|
|
```
|
|
|
|
### Step 4: Secure Database Operations
|
|
|
|
#### BEFORE (SQL Injection):
|
|
```javascript
|
|
// ❌ SQL INJECTION VULNERABILITY
|
|
const query = `DELETE FROM wp_posts WHERE post_title = '${title}'`;
|
|
```
|
|
|
|
#### AFTER (Secure):
|
|
```javascript
|
|
const { getInputValidator } = require('./lib/security');
|
|
|
|
const validator = getInputValidator();
|
|
|
|
// ✅ SECURE: Input validation and sanitization
|
|
const titleValidation = validator.validate(title, 'text_field');
|
|
if (!titleValidation.valid) {
|
|
throw new Error(`Invalid title: ${titleValidation.error}`);
|
|
}
|
|
|
|
// ✅ SECURE: Use WordPress prepared statements
|
|
const result = await commandExecutor.executeWordPressCommand(
|
|
'db query',
|
|
[`"DELETE FROM wp_posts WHERE post_title = %s"`],
|
|
{ parameters: [title] }
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## 📋 File-by-File Migration Checklist
|
|
|
|
For each of your 80+ test files, complete this checklist:
|
|
|
|
### Authentication & Credentials
|
|
- [ ] Remove all hardcoded passwords and usernames
|
|
- [ ] Replace with `authenticateAs()` calls
|
|
- [ ] Add proper session cleanup with `logout()`
|
|
- [ ] Verify roles are correctly specified
|
|
|
|
### Browser Configuration
|
|
- [ ] Remove `--no-sandbox`, `--disable-setuid-sandbox` flags
|
|
- [ ] Remove `ignoreHTTPSErrors: true`
|
|
- [ ] Replace with `createSecureBrowser()`
|
|
- [ ] Update context creation to use secure defaults
|
|
|
|
### Command Execution
|
|
- [ ] Replace all `execSync()`, `spawn()` calls
|
|
- [ ] Use `commandExecutor.executeWordPressCommand()`
|
|
- [ ] Validate all command parameters
|
|
- [ ] Remove string concatenation in commands
|
|
|
|
### Input Validation
|
|
- [ ] Add validation for all user inputs
|
|
- [ ] Sanitize content before display
|
|
- [ ] Validate URLs and file paths
|
|
- [ ] Check form data before submission
|
|
|
|
### Error Handling
|
|
- [ ] Add try/catch blocks around security operations
|
|
- [ ] Clean up resources in finally blocks
|
|
- [ ] Log security events appropriately
|
|
- [ ] Don't expose sensitive data in error messages
|
|
|
|
---
|
|
|
|
## 🔧 Configuration Reference
|
|
|
|
### Environment Variables (.env)
|
|
```bash
|
|
# Authentication (REQUIRED)
|
|
MASTER_TRAINER_USERNAME=your_master_username
|
|
MASTER_TRAINER_PASSWORD=your_secure_password
|
|
REGULAR_TRAINER_USERNAME=your_trainer_username
|
|
REGULAR_TRAINER_PASSWORD=your_trainer_password
|
|
|
|
# Security (REQUIRED)
|
|
SESSION_ENCRYPTION_KEY=generate_with_openssl_rand_hex_32
|
|
JWT_SECRET=generate_with_openssl_rand_base64_64
|
|
|
|
# Staging Environment
|
|
STAGING_BASE_URL=https://upskill-staging.measurequick.com
|
|
TLS_VALIDATION_MODE=strict
|
|
|
|
# Test Configuration
|
|
PLAYWRIGHT_HEADLESS=true
|
|
PLAYWRIGHT_TIMEOUT=30000
|
|
```
|
|
|
|
### Supported User Roles
|
|
- `master_trainer` - Master trainer with full management access
|
|
- `master_trainer_alt` - Alternative master trainer account
|
|
- `regular_trainer` - Standard trainer with limited permissions
|
|
- `admin` - WordPress administrator (for setup operations)
|
|
|
|
### Available Security Components
|
|
```javascript
|
|
const security = initializeSecurity();
|
|
|
|
// Credential management
|
|
security.credentialManager.createSecureSession(role);
|
|
security.credentialManager.getSessionCredentials(sessionId);
|
|
|
|
// Command execution
|
|
security.commandExecutor.executeWordPressCommand(command, args);
|
|
|
|
// Browser management
|
|
security.browserManager.createSecureBrowser(type, options);
|
|
|
|
// Input validation
|
|
security.inputValidator.validate(input, pattern);
|
|
security.inputValidator.sanitize(input, context);
|
|
|
|
// WordPress security
|
|
security.wpSecurity.verifyWordPressNonce(nonce, action);
|
|
security.wpSecurity.verifyUserCapability(userId, capability);
|
|
```
|
|
|
|
---
|
|
|
|
## 📁 Example Secure Test Files
|
|
|
|
### Secure Master Trainer Test
|
|
```javascript
|
|
// test-master-trainer-secure.js
|
|
const { initializeSecurity } = require('./lib/security');
|
|
|
|
async function testMasterTrainerDashboard() {
|
|
console.log('🔐 Starting Secure Master Trainer Test');
|
|
|
|
const security = initializeSecurity();
|
|
|
|
try {
|
|
// Create secure browser
|
|
const { browser, createSecureContext } = await security.browserManager
|
|
.createSecureBrowser('chromium');
|
|
|
|
// Create secure context
|
|
const { context, authenticateAs, logout } = await createSecureContext();
|
|
|
|
// Authenticate as master trainer
|
|
const auth = await authenticateAs('master_trainer');
|
|
const { page, sessionId } = auth;
|
|
|
|
console.log('✅ Authentication successful');
|
|
|
|
// Test master dashboard access
|
|
const response = await page.goto('/master-trainer/master-dashboard/');
|
|
console.log(`Dashboard loaded: ${response.status()}`);
|
|
|
|
// Verify master trainer elements
|
|
await page.waitForSelector('.hvac-master-dashboard');
|
|
console.log('✅ Master dashboard elements found');
|
|
|
|
// Test navigation
|
|
await page.click('a[href*="trainers"]');
|
|
await page.waitForLoadState('networkidle');
|
|
console.log('✅ Navigation to trainers page successful');
|
|
|
|
// Clean up
|
|
await logout(sessionId);
|
|
await browser.close();
|
|
|
|
console.log('✅ Test completed successfully');
|
|
|
|
} catch (error) {
|
|
console.error('❌ Test failed:', error.message);
|
|
throw error;
|
|
} finally {
|
|
await security.cleanup();
|
|
}
|
|
}
|
|
|
|
// Run test
|
|
testMasterTrainerDashboard().catch(console.error);
|
|
```
|
|
|
|
### Secure Form Validation Test
|
|
```javascript
|
|
// test-form-validation-secure.js
|
|
const { initializeSecurity } = require('./lib/security');
|
|
|
|
async function testSecureFormSubmission() {
|
|
const security = initializeSecurity();
|
|
|
|
try {
|
|
const { browser, createSecureContext } = await security.browserManager
|
|
.createSecureBrowser('chromium');
|
|
|
|
const { context, authenticateAs } = await createSecureContext();
|
|
const auth = await authenticateAs('regular_trainer');
|
|
const { page } = auth;
|
|
|
|
// Navigate to form
|
|
await page.goto('/trainer/venue/manage/');
|
|
|
|
// Validate inputs before submission
|
|
const venueData = {
|
|
name: 'Test Venue',
|
|
address: '123 Main St',
|
|
city: 'Test City'
|
|
};
|
|
|
|
// Validate each field
|
|
for (const [field, value] of Object.entries(venueData)) {
|
|
const validation = security.inputValidator.validate(value, 'text_field');
|
|
if (!validation.valid) {
|
|
throw new Error(`Invalid ${field}: ${validation.error}`);
|
|
}
|
|
}
|
|
|
|
// Fill form with validated data
|
|
await page.fill('[name="venue_name"]', venueData.name);
|
|
await page.fill('[name="venue_address"]', venueData.address);
|
|
await page.fill('[name="venue_city"]', venueData.city);
|
|
|
|
// Generate and verify nonce
|
|
const nonce = await security.wpSecurity.generateWordPressNonce('save_venue');
|
|
await page.fill('[name="_wpnonce"]', nonce);
|
|
|
|
// Submit form
|
|
await page.click('button[type="submit"]');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
console.log('✅ Secure form submission successful');
|
|
|
|
} finally {
|
|
await security.cleanup();
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## ⚡ Performance Considerations
|
|
|
|
### Parallel Test Execution
|
|
```javascript
|
|
// Secure parallel execution
|
|
const { initializeSecurity } = require('./lib/security');
|
|
|
|
async function runParallelTests() {
|
|
const testConfigs = [
|
|
{ role: 'master_trainer', testName: 'Dashboard Test' },
|
|
{ role: 'regular_trainer', testName: 'Event Test' },
|
|
{ role: 'master_trainer', testName: 'Approval Test' }
|
|
];
|
|
|
|
const results = await Promise.all(
|
|
testConfigs.map(config => runIndependentTest(config))
|
|
);
|
|
|
|
console.log('All tests completed:', results);
|
|
}
|
|
|
|
async function runIndependentTest({ role, testName }) {
|
|
const security = initializeSecurity();
|
|
|
|
try {
|
|
// Each test gets its own security context
|
|
const { browser, createSecureContext } = await security.browserManager
|
|
.createSecureBrowser('chromium');
|
|
|
|
const { authenticateAs } = await createSecureContext();
|
|
const auth = await authenticateAs(role);
|
|
|
|
// Run test with isolated credentials
|
|
// ...
|
|
|
|
return { testName, status: 'passed' };
|
|
|
|
} finally {
|
|
await security.cleanup();
|
|
}
|
|
}
|
|
```
|
|
|
|
### Resource Management
|
|
```javascript
|
|
// Proper cleanup in test suites
|
|
class SecureTestSuite {
|
|
constructor() {
|
|
this.security = initializeSecurity();
|
|
this.activeSessions = new Set();
|
|
}
|
|
|
|
async createTest(role) {
|
|
const session = await this.security.credentialManager
|
|
.createSecureSession(role);
|
|
this.activeSessions.add(session.sessionId);
|
|
return session;
|
|
}
|
|
|
|
async cleanup() {
|
|
// Clean up all active sessions
|
|
for (const sessionId of this.activeSessions) {
|
|
this.security.credentialManager.destroySession(sessionId);
|
|
}
|
|
|
|
await this.security.cleanup();
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🛡️ Security Best Practices
|
|
|
|
### 1. Credential Management
|
|
- **Never hardcode credentials** in test files
|
|
- **Always use environment variables** for sensitive data
|
|
- **Rotate credentials regularly** and after any exposure
|
|
- **Use unique passwords** for each environment
|
|
|
|
### 2. Input Validation
|
|
- **Validate all inputs** before processing
|
|
- **Sanitize content** before display or storage
|
|
- **Use allowlisting** instead of blocklisting
|
|
- **Validate file uploads** and restrict types
|
|
|
|
### 3. Session Security
|
|
- **Use short session timeouts** for testing
|
|
- **Encrypt all session data** at rest
|
|
- **Implement proper logout** procedures
|
|
- **Monitor for session anomalies**
|
|
|
|
### 4. Network Security
|
|
- **Always use HTTPS** for production environments
|
|
- **Enable SSL validation** in all configurations
|
|
- **Implement certificate pinning** for critical connections
|
|
- **Monitor network traffic** for anomalies
|
|
|
|
---
|
|
|
|
## 🚨 Emergency Procedures
|
|
|
|
### If Credentials Are Compromised
|
|
1. **Immediately rotate all affected credentials**
|
|
2. **Review access logs** for unauthorized usage
|
|
3. **Update all test configurations** with new credentials
|
|
4. **Audit git history** for credential exposure
|
|
5. **Report incident** to security team
|
|
|
|
### If Tests Are Failing After Migration
|
|
1. **Check environment variables** are properly configured
|
|
2. **Verify SSL certificates** are valid
|
|
3. **Review security logs** for authentication failures
|
|
4. **Test with minimal configuration** first
|
|
5. **Contact security team** if issues persist
|
|
|
|
---
|
|
|
|
## 📞 Support and Resources
|
|
|
|
### Documentation
|
|
- [WordPress Security Best Practices](https://wordpress.org/support/article/hardening-wordpress/)
|
|
- [OWASP Testing Guide](https://owasp.org/www-project-web-security-testing-guide/)
|
|
- [Playwright Security](https://playwright.dev/docs/auth)
|
|
|
|
### Getting Help
|
|
1. **Review security logs** in `./security-audit.log`
|
|
2. **Check configuration** in `.env` file
|
|
3. **Test with minimal example** first
|
|
4. **Contact development team** for complex issues
|
|
|
|
---
|
|
|
|
## ✅ Migration Completion Checklist
|
|
|
|
- [ ] All hardcoded credentials removed from codebase
|
|
- [ ] Environment variables configured properly
|
|
- [ ] All test files use secure authentication
|
|
- [ ] Command injection vulnerabilities fixed
|
|
- [ ] Input validation added to all forms
|
|
- [ ] SSL/TLS validation enabled
|
|
- [ ] Security logging implemented
|
|
- [ ] Cleanup procedures added to all tests
|
|
- [ ] Parallel execution working correctly
|
|
- [ ] Emergency procedures documented
|
|
|
|
**Once all items are checked, your migration is complete and the framework is production-ready!** 🎉
|
|
|
|
---
|
|
|
|
*This migration guide addresses the critical P0 and P1 security vulnerabilities identified in the HVAC testing framework. Following this guide ensures your tests are secure, maintainable, and production-ready.* |