const LessonModule = require('../base/LessonModule'); class SQLInjectionShopLesson extends LessonModule { constructor(config) { super(config); } // Mock database with products getMockDatabase() { return { products: [ { id: 1, name: 'Laptop Pro 15', price: 1299.99, category: 'Electronics', stock: 15 }, { id: 2, name: 'Wireless Mouse', price: 29.99, category: 'Accessories', stock: 50 }, { id: 3, name: 'USB-C Cable', price: 12.99, category: 'Accessories', stock: 100 }, { id: 4, name: 'Gaming Keyboard', price: 89.99, category: 'Electronics', stock: 25 }, { id: 5, name: 'Monitor 27"', price: 349.99, category: 'Electronics', stock: 20 }, { id: 6, name: 'Webcam HD', price: 79.99, category: 'Electronics', stock: 30 }, { id: 7, name: 'Desk Lamp', price: 34.99, category: 'Office', stock: 40 }, { id: 8, name: 'Notebook Set', price: 15.99, category: 'Office', stock: 60 } ], users: [ { id: 1, username: 'admin', password: 'hashed_admin_password', role: 'admin' }, { id: 2, username: 'john_doe', password: 'hashed_user_password', role: 'customer' }, { id: 3, username: 'jane_smith', password: 'hashed_user_password', role: 'customer' } ], orders: [ { id: 1, user_id: 2, total: 1329.98, status: 'shipped' }, { id: 2, user_id: 3, total: 89.99, status: 'processing' } ] }; } // Simulate vulnerable SQL query executeVulnerableQuery(searchTerm) { const db = this.getMockDatabase(); // Build the "vulnerable" query string for educational display const vulnerableQuery = `SELECT * FROM products WHERE name LIKE '%${searchTerm}%'`; // Detect SQL injection attempts const injectionDetected = this.detectInjection(searchTerm); let results = []; let injectionType = null; let explanation = ''; if (injectionDetected) { const injectionInfo = this.analyzeInjection(searchTerm); injectionType = injectionInfo.type; explanation = injectionInfo.explanation; // Simulate different injection results if (injectionInfo.type === 'OR_ALWAYS_TRUE') { // Return all products (simulating OR '1'='1') results = db.products; } else if (injectionInfo.type === 'UNION_SELECT') { // Simulate UNION attack showing user data results = [ { id: 'INJECTED', name: 'admin', price: 'hashed_admin_password', category: 'LEAKED DATA', stock: 'admin' }, { id: 'INJECTED', name: 'john_doe', price: 'hashed_user_password', category: 'LEAKED DATA', stock: 'customer' }, { id: 'INJECTED', name: 'jane_smith', price: 'hashed_user_password', category: 'LEAKED DATA', stock: 'customer' } ]; } else if (injectionInfo.type === 'DROP_TABLE') { // Simulate destructive command results = []; explanation += ' In a real scenario, this could delete the entire products table!'; } else if (injectionInfo.type === 'COMMENT_INJECTION') { // Bypass rest of query results = db.products; } } else { // Normal search - filter products by name results = db.products.filter(p => p.name.toLowerCase().includes(searchTerm.toLowerCase()) ); } return { query: vulnerableQuery, results, injectionDetected, injectionType, explanation, recordCount: results.length }; } // Detect if input contains SQL injection detectInjection(input) { const injectionPatterns = [ /'/, // Single quote /--/, // SQL comment /;/, // Statement separator /union/i, // UNION keyword /select/i, // SELECT keyword /drop/i, // DROP keyword /insert/i, // INSERT keyword /update/i, // UPDATE keyword /delete/i, // DELETE keyword /or\s+['"]?\d+['"]?\s*=\s*['"]?\d+['"]?/i // OR 1=1 pattern ]; return injectionPatterns.some(pattern => pattern.test(input)); } // Analyze the type of SQL injection analyzeInjection(input) { const lowerInput = input.toLowerCase(); if (lowerInput.includes('union') && lowerInput.includes('select')) { return { type: 'UNION_SELECT', explanation: '⚠️ UNION SELECT injection detected! This technique combines results from multiple tables, potentially exposing sensitive data like usernames and passwords.' }; } if (lowerInput.includes('drop')) { return { type: 'DROP_TABLE', explanation: '🚨 DROP TABLE injection detected! This is a destructive attack that could delete entire database tables. Critical data loss would occur!' }; } if (lowerInput.includes("'") && (lowerInput.includes('or') || lowerInput.includes('||'))) { if (lowerInput.match(/or\s+['"]?\d+['"]?\s*=\s*['"]?\d+['"]?/)) { return { type: 'OR_ALWAYS_TRUE', explanation: "⚠️ OR injection detected! The condition '1'='1' is always true, bypassing the intended filter and returning ALL records." }; } } if (lowerInput.includes('--') || lowerInput.includes('#')) { return { type: 'COMMENT_INJECTION', explanation: '⚠️ Comment injection detected! The -- sequence comments out the rest of the SQL query, potentially bypassing security checks.' }; } if (lowerInput.includes(';')) { return { type: 'MULTIPLE_STATEMENTS', explanation: '⚠️ Multiple statement injection detected! The semicolon allows execution of additional SQL commands, enabling complex attacks.' }; } // Generic injection return { type: 'GENERIC', explanation: '⚠️ SQL injection attempt detected! Special characters in the input could manipulate the query structure.' }; } // Demonstrate safe parameterized query executeSafeQuery(searchTerm) { const db = this.getMockDatabase(); // Show the safe query with placeholder const safeQuery = `SELECT * FROM products WHERE name LIKE ?`; const parameter = `%${searchTerm}%`; // Execute safe search (treats all input as literal data) const results = db.products.filter(p => p.name.toLowerCase().includes(searchTerm.toLowerCase()) ); return { query: safeQuery, parameter, results, explanation: '✅ Parameterized query used! User input is treated as data only, never as SQL code. Injection is impossible.', recordCount: results.length }; } // Get interactive data for the SQL shop demo getInteractiveData(stepId) { if (stepId === 'shop-demo') { return { database: this.getMockDatabase(), examples: [ { label: 'Normal Search', input: 'laptop', description: 'Search for products containing "laptop"' }, { label: 'View All Products (OR injection)', input: "' OR '1'='1", description: 'Exploit: Returns all products by making condition always true' }, { label: 'Extract User Data (UNION)', input: "' UNION SELECT id, username, password, role, 'LEAKED' FROM users--", description: 'Exploit: Combines product results with user table data' }, { label: 'Destructive Attack (DROP)', input: "'; DROP TABLE products--", description: 'Exploit: Attempts to delete the products table' } ] }; } return null; } } module.exports = SQLInjectionShopLesson;