web-vuln-scanner
Version:
Advanced, lightweight web vulnerability scanner with smart detection and easy-to-use interface
353 lines (307 loc) • 8.33 kB
JavaScript
/**
* 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
};