UNPKG

web-vuln-scanner

Version:

Advanced, lightweight web vulnerability scanner with smart detection and easy-to-use interface

353 lines (307 loc) 8.33 kB
/** * Role-Based Access Control (RBAC) System * Enterprise-grade permission and role management */ const { Logger } = require('../monitoring/logger'); const { ConfigManager } = require('../config/config-manager'); // Define system permissions const PERMISSIONS = { // Scan permissions SCAN_CREATE: 'scan:create', SCAN_READ: 'scan:read', SCAN_UPDATE: 'scan:update', SCAN_DELETE: 'scan:delete', SCAN_EXECUTE: 'scan:execute', // User management permissions USER_CREATE: 'user:create', USER_READ: 'user:read', USER_UPDATE: 'user:update', USER_DELETE: 'user:delete', USER_MANAGE_ROLES: 'user:manage_roles', // API key permissions APIKEY_CREATE: 'apikey:create', APIKEY_READ: 'apikey:read', APIKEY_UPDATE: 'apikey:update', APIKEY_DELETE: 'apikey:delete', // Report permissions REPORT_CREATE: 'report:create', REPORT_READ: 'report:read', REPORT_EXPORT: 'report:export', REPORT_DELETE: 'report:delete', // System administration SYSTEM_CONFIG: 'system:config', SYSTEM_MONITOR: 'system:monitor', SYSTEM_AUDIT: 'system:audit', SYSTEM_BACKUP: 'system:backup', // Integration permissions INTEGRATION_SLACK: 'integration:slack', INTEGRATION_JIRA: 'integration:jira', INTEGRATION_EMAIL: 'integration:email' }; // Define system roles with default permissions const DEFAULT_ROLES = { guest: { name: 'Guest', description: 'Limited read-only access', permissions: [ PERMISSIONS.SCAN_READ, PERMISSIONS.REPORT_READ ] }, scanner: { name: 'Scanner User', description: 'Can create and execute scans', permissions: [ PERMISSIONS.SCAN_CREATE, PERMISSIONS.SCAN_READ, PERMISSIONS.SCAN_EXECUTE, PERMISSIONS.REPORT_CREATE, PERMISSIONS.REPORT_READ, PERMISSIONS.REPORT_EXPORT ] }, analyst: { name: 'Security Analyst', description: 'Full scan and report management', permissions: [ PERMISSIONS.SCAN_CREATE, PERMISSIONS.SCAN_READ, PERMISSIONS.SCAN_UPDATE, PERMISSIONS.SCAN_DELETE, PERMISSIONS.SCAN_EXECUTE, PERMISSIONS.REPORT_CREATE, PERMISSIONS.REPORT_READ, PERMISSIONS.REPORT_EXPORT, PERMISSIONS.REPORT_DELETE, PERMISSIONS.APIKEY_CREATE, PERMISSIONS.APIKEY_READ, PERMISSIONS.INTEGRATION_SLACK, PERMISSIONS.INTEGRATION_EMAIL ] }, admin: { name: 'Administrator', description: 'Full system access', permissions: Object.values(PERMISSIONS) }, api: { name: 'API Service', description: 'Programmatic access for integrations', permissions: [ PERMISSIONS.SCAN_CREATE, PERMISSIONS.SCAN_READ, PERMISSIONS.SCAN_EXECUTE, PERMISSIONS.REPORT_CREATE, PERMISSIONS.REPORT_READ, PERMISSIONS.REPORT_EXPORT ] } }; class RBACManager { constructor() { this.config = ConfigManager.getInstance(); this.logger = new Logger(this.config.get('logging')); // Load custom roles from config if available this.roles = { ...DEFAULT_ROLES, ...this.config.get('auth.customRoles', {}) }; this.permissions = PERMISSIONS; } /** * Check if a user has a specific permission */ hasPermission(user, permission) { try { if (!user || !user.roles) { return false; } // Check if user has admin role (full access) if (user.roles.includes('admin')) { return true; } // Check direct permissions if (user.permissions && user.permissions.includes(permission)) { return true; } // Check role-based permissions for (const roleName of user.roles) { const role = this.roles[roleName]; if (role && role.permissions.includes(permission)) { return true; } } return false; } catch (error) { this.logger.error('Permission check failed', { error: error.message, userId: user?.id, permission }); return false; } } /** * Check if a user has any of the specified permissions */ hasAnyPermission(user, permissions) { return permissions.some(permission => this.hasPermission(user, permission)); } /** * Check if a user has all specified permissions */ hasAllPermissions(user, permissions) { return permissions.every(permission => this.hasPermission(user, permission)); } /** * Get all permissions for a user */ getUserPermissions(user) { try { const userPermissions = new Set(); // Add direct permissions if (user.permissions) { user.permissions.forEach(perm => userPermissions.add(perm)); } // Add role-based permissions if (user.roles) { user.roles.forEach(roleName => { const role = this.roles[roleName]; if (role && role.permissions) { role.permissions.forEach(perm => userPermissions.add(perm)); } }); } return Array.from(userPermissions); } catch (error) { this.logger.error('Failed to get user permissions', { error: error.message, userId: user?.id }); return []; } } /** * Validate role exists */ isValidRole(roleName) { return this.roles.hasOwnProperty(roleName); } /** * Get role definition */ getRole(roleName) { return this.roles[roleName] || null; } /** * Get all available roles */ getAllRoles() { return Object.keys(this.roles).map(roleName => ({ name: roleName, ...this.roles[roleName] })); } /** * Get all available permissions */ getAllPermissions() { return Object.values(PERMISSIONS); } /** * Create permission requirement middleware */ requirePermission(permission) { return (req, res, next) => { if (!req.user) { return res.status(401).json({ error: 'Authentication required', code: 'AUTH_REQUIRED' }); } if (!this.hasPermission(req.user, permission)) { this.logger.warn('Permission denied', { userId: req.user.id, permission, userRoles: req.user.roles, endpoint: req.originalUrl }); return res.status(403).json({ error: 'Insufficient permissions', code: 'PERMISSION_DENIED', required: permission }); } next(); }; } /** * Create role requirement middleware */ requireRole(role) { return (req, res, next) => { if (!req.user) { return res.status(401).json({ error: 'Authentication required', code: 'AUTH_REQUIRED' }); } if (!req.user.roles || !req.user.roles.includes(role)) { this.logger.warn('Role requirement not met', { userId: req.user.id, requiredRole: role, userRoles: req.user.roles, endpoint: req.originalUrl }); return res.status(403).json({ error: 'Insufficient role privileges', code: 'ROLE_REQUIRED', required: role }); } next(); }; } /** * Create admin-only middleware */ requireAdmin() { return this.requireRole('admin'); } /** * Resource ownership check */ requireOwnership(resourceOwnerField = 'userId') { return (req, res, next) => { if (!req.user) { return res.status(401).json({ error: 'Authentication required', code: 'AUTH_REQUIRED' }); } // Admins can access all resources if (req.user.roles && req.user.roles.includes('admin')) { return next(); } // Check if user owns the resource const resourceOwnerId = req.resource ? req.resource[resourceOwnerField] : req.params.userId; if (resourceOwnerId && resourceOwnerId.toString() === req.user.id.toString()) { return next(); } this.logger.warn('Resource ownership check failed', { userId: req.user.id, resourceOwner: resourceOwnerId, endpoint: req.originalUrl }); return res.status(403).json({ error: 'Access denied to resource', code: 'OWNERSHIP_REQUIRED' }); }; } } module.exports = { RBACManager, PERMISSIONS, DEFAULT_ROLES };