@ordojs/security
Version:
Security package for OrdoJS with XSS, CSRF, and injection protection
223 lines • 8.24 kB
JavaScript
/**
* XSS vulnerability detection and analysis
*/
/**
* Types of XSS vulnerabilities
*/
export var XssVulnerabilityType;
(function (XssVulnerabilityType) {
XssVulnerabilityType["REFLECTED"] = "reflected";
XssVulnerabilityType["STORED"] = "stored";
XssVulnerabilityType["DOM_BASED"] = "dom-based";
XssVulnerabilityType["TEMPLATE_INJECTION"] = "template-injection";
})(XssVulnerabilityType || (XssVulnerabilityType = {}));
/**
* Severity levels for vulnerabilities
*/
export var VulnerabilitySeverity;
(function (VulnerabilitySeverity) {
VulnerabilitySeverity["LOW"] = "low";
VulnerabilitySeverity["MEDIUM"] = "medium";
VulnerabilitySeverity["HIGH"] = "high";
VulnerabilitySeverity["CRITICAL"] = "critical";
})(VulnerabilitySeverity || (VulnerabilitySeverity = {}));
/**
* Common XSS attack patterns
*/
const XSS_PATTERNS = [
// Script tags
/<script[^>]*>.*?<\/script>/gi,
/<script[^>]*>/gi,
// Event handlers
/on\w+\s*=\s*['"]/gi,
// JavaScript URLs
/javascript\s*:/gi,
// Data URLs with JavaScript
/data\s*:\s*text\/html/gi,
// SVG with script
/<svg[^>]*>.*?<\/svg>/gi,
// Object/embed tags
/<(object|embed|applet)[^>]*>/gi,
// Meta refresh
/<meta[^>]*http-equiv\s*=\s*['"]\s*refresh/gi,
// Link with JavaScript
/<link[^>]*href\s*=\s*['"]\s*javascript/gi,
// Style with expression
/expression\s*\(/gi,
// Import statements
/@import/gi,
];
/**
* Dangerous HTML attributes that can execute JavaScript
*/
const DANGEROUS_ATTRIBUTES = [
'onabort', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onerror',
'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onmousedown',
'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onreset',
'onresize', 'onselect', 'onsubmit', 'onunload', 'onafterprint',
'onbeforeprint', 'onbeforeunload', 'onhashchange', 'onmessage',
'onoffline', 'ononline', 'onpagehide', 'onpageshow', 'onpopstate',
'onstorage', 'oncontextmenu', 'oninput', 'oninvalid', 'onsearch',
];
/**
* XSS vulnerability detector
*/
export class XssVulnerabilityDetector {
patterns;
dangerousAttributes;
/**
* Create a new XSS vulnerability detector
*/
constructor() {
this.patterns = [...XSS_PATTERNS];
this.dangerousAttributes = [...DANGEROUS_ATTRIBUTES];
}
/**
* Scan content for potential XSS vulnerabilities
* @param content Content to scan
* @param location Location identifier for the content
* @returns Array of detected vulnerabilities
*/
scanContent(content, location = 'unknown') {
const vulnerabilities = [];
// Check for script injection patterns
for (const pattern of this.patterns) {
const matches = content.match(pattern);
if (matches) {
for (const match of matches) {
vulnerabilities.push({
type: this.determineVulnerabilityType(match),
severity: this.determineSeverity(match),
description: `Potential XSS vulnerability detected: ${match.substring(0, 100)}...`,
location,
payload: match,
recommendation: this.getRecommendation(match),
});
}
}
}
// Check for dangerous attributes
for (const attr of this.dangerousAttributes) {
const attrPattern = new RegExp(`${attr}\\s*=`, 'gi');
if (attrPattern.test(content)) {
vulnerabilities.push({
type: XssVulnerabilityType.DOM_BASED,
severity: VulnerabilitySeverity.HIGH,
description: `Dangerous event handler attribute detected: ${attr}`,
location,
payload: attr,
recommendation: 'Remove event handler attributes and use proper event listeners instead.',
});
}
}
return vulnerabilities;
}
/**
* Check if a string contains potential XSS payload
* @param input Input string to check
* @returns True if potential XSS is detected
*/
containsXss(input) {
return this.patterns.some(pattern => pattern.test(input)) ||
this.dangerousAttributes.some(attr => new RegExp(`${attr}\\s*=`, 'gi').test(input));
}
/**
* Analyze template for potential injection vulnerabilities
* @param template Template string
* @param variables Variables used in template
* @returns Array of vulnerabilities
*/
analyzeTemplate(template, variables = {}) {
const vulnerabilities = [];
// Check for unescaped variable interpolation
const interpolationPattern = /\$\{([^}]+)\}/g;
let match;
while ((match = interpolationPattern.exec(template)) !== null) {
const variableName = match[1]?.trim();
if (!variableName)
continue;
const variableValue = variables[variableName];
if (typeof variableValue === 'string' && this.containsXss(variableValue)) {
vulnerabilities.push({
type: XssVulnerabilityType.TEMPLATE_INJECTION,
severity: VulnerabilitySeverity.CRITICAL,
description: `Unescaped variable interpolation with potential XSS: \${${variableName}}`,
location: 'template',
payload: String(variableValue),
recommendation: 'Use proper HTML escaping for all template variables.',
});
}
}
return vulnerabilities;
}
/**
* Determine the type of XSS vulnerability based on the payload
* @param payload The detected payload
* @returns Vulnerability type
*/
determineVulnerabilityType(payload) {
if (payload.includes('<script')) {
return XssVulnerabilityType.REFLECTED;
}
if (payload.includes('javascript:')) {
return XssVulnerabilityType.DOM_BASED;
}
if (payload.includes('${') || payload.includes('{{')) {
return XssVulnerabilityType.TEMPLATE_INJECTION;
}
return XssVulnerabilityType.STORED;
}
/**
* Determine the severity of a vulnerability based on the payload
* @param payload The detected payload
* @returns Vulnerability severity
*/
determineSeverity(payload) {
if (payload.includes('<script') || payload.includes('javascript:')) {
return VulnerabilitySeverity.CRITICAL;
}
if (payload.includes('on') && payload.includes('=')) {
return VulnerabilitySeverity.HIGH;
}
if (payload.includes('<') || payload.includes('>')) {
return VulnerabilitySeverity.MEDIUM;
}
return VulnerabilitySeverity.LOW;
}
/**
* Get recommendation for fixing a vulnerability
* @param payload The detected payload
* @returns Recommendation string
*/
getRecommendation(payload) {
if (payload.includes('<script')) {
return 'Remove script tags and use proper JavaScript loading mechanisms.';
}
if (payload.includes('javascript:')) {
return 'Replace javascript: URLs with proper event handlers.';
}
if (payload.includes('on') && payload.includes('=')) {
return 'Remove inline event handlers and use addEventListener instead.';
}
return 'Sanitize or escape the content before rendering.';
}
/**
* Add a custom XSS pattern to detect
* @param pattern Regular expression pattern
*/
addPattern(pattern) {
this.patterns.push(pattern);
}
/**
* Add a custom dangerous attribute to detect
* @param attribute Attribute name
*/
addDangerousAttribute(attribute) {
this.dangerousAttributes.push(attribute.toLowerCase());
}
}
/**
* Default XSS vulnerability detector instance
*/
export const defaultXssDetector = new XssVulnerabilityDetector();
//# sourceMappingURL=vulnerability-detector.js.map