Fehlende Administrator-Kontrolle über Sicherheit

Beschreibung

Fehlende Administrator-Kontrolle über Sicherheit tritt auf, wenn ein Produkt Administratoren keine ausreichende Kontrolle zur Verwaltung von Sicherheitseinstellungen und -konfigurationen bietet. Dies umfasst hartcodierte Sicherheitsrichtlinien, Unfähigkeit Standard-Anmeldedaten zu ändern, fehlende Audit-Kontrollen, fehlende Schalter für Sicherheitsfunktionen und das Fehlen granularer Berechtigungsverwaltung. Administratoren können die Sicherheitshaltung nicht an die Bedürfnisse ihrer Organisation anpassen.

Risiko

Organisationen können Sicherheitsrichtlinien nicht durchsetzen. Standard-Anmeldedaten bleiben unverändert. Sicherheitsfunktionen können nicht nach Bedarf aktiviert/deaktiviert werden. Keine Möglichkeit, regulatorische Anforderungen zu erfüllen. Unfähigkeit, auf Sicherheitsvorfälle zu reagieren. Audit- und Überwachungslücken. Einheits-Sicherheit für alle Umgebungen ungeeignet.

Lösung

Bieten Sie umfassende Sicherheitskonfigurationsschnittstellen. Ermöglichen Sie Anmeldedaten-Management und -Rotation. Implementieren Sie granulare rollenbasierte Zugriffskontrolle. Stellen Sie Sicherheits-Audit-Logging mit konfigurierbaren Stufen bereit. Ermöglichen Sie Aktivieren/Deaktivieren von Sicherheitsfunktionen über Konfiguration. Dokumentieren Sie alle Sicherheitseinstellungen. Unterstützen Sie Anpassung von Sicherheitsrichtlinien.

Häufige Konsequenzen

AuswirkungDetails
SicherheitBereich: Unfähigkeit zur Anpassung

Sicherheit kann nicht an Umgebung angepasst werden.
ComplianceBereich: Regulatorisches Versagen

Kann Sicherheits-Audit-Anforderungen nicht erfüllen.
BetriebBereich: Vorfallreaktion

Kann nicht effektiv auf Sicherheitsereignisse reagieren.

Beispielcode + Lösungscode

Verwundbarer Code

// VERWUNDBAR: Keine administrativen Sicherheitskontrollen
public class VulnerableSecurityConfig {

    // VERWUNDBAR: Hartcodierte Anmeldedaten, keine Änderungsmöglichkeit
    private static final String ADMIN_USERNAME = "admin";
    private static final String ADMIN_PASSWORD = "admin123";

    public boolean authenticate(String username, String password) {
        // VERWUNDBAR: Kann diese Anmeldedaten nicht ändern
        return ADMIN_USERNAME.equals(username) &&
               ADMIN_PASSWORD.equals(password);
    }

    // VERWUNDBAR: Hartcodiertes Session-Timeout
    private static final int SESSION_TIMEOUT = 3600;  // 1 Stunde, unveränderlich

    // VERWUNDBAR: Hartcodierte Passwort-Richtlinie
    public boolean isPasswordValid(String password) {
        return password.length() >= 6;  // Fest, kann nicht verstärkt werden
    }

    // VERWUNDBAR: Keine Audit-Kontrolle
    public void performAdminAction(String action) {
        // Kein Logging, keine Audit-Spur
        executeAction(action);
    }

    // VERWUNDBAR: Alles-oder-nichts-Berechtigungen
    public boolean hasPermission(User user, String resource) {
        // Nur Admin oder regulärer Benutzer, keine Granularität
        return user.isAdmin();
    }

    // VERWUNDBAR: Sicherheitsfunktionen hartcodiert
    private boolean mfaEnabled = false;  // Kann nicht geändert werden
    private boolean bruteForceProtection = false;  // Keine Möglichkeit zu aktivieren
}

// VERWUNDBAR: Keine Sicherheitskonfigurations-API
@RestController
public class VulnerableAdminController {

    // Keine Endpoints für:
    // - Ändern von Sicherheitseinstellungen
    // - Verwalten von Benutzern/Rollen
    // - Anzeigen von Audit-Logs
    // - Konfigurieren der Authentifizierung
}
# VERWUNDBAR: Python-Anwendung ohne Sicherheitskontrollen
class VulnerableApp:

    # VERWUNDBAR: Hartcodierte Einstellungen
    SECRET_KEY = "hardcoded_secret_key_12345"
    ADMIN_PASSWORD = "admin"

    # VERWUNDBAR: Keine konfigurierbaren Sicherheitsrichtlinien
    PASSWORD_MIN_LENGTH = 4  # Fest, zu schwach
    SESSION_DURATION = 86400  # 24 Stunden, unveränderlich
    MAX_LOGIN_ATTEMPTS = None  # Kein Rate-Limiting

    def __init__(self):
        # VERWUNDBAR: Keine Konfigurationsmöglichkeit
        self.debug_mode = True  # Immer an
        self.ssl_verify = False  # Kann nicht aktivieren

    # VERWUNDBAR: Keine Audit-Logging-Konfiguration
    def admin_action(self, action, user):
        # Keine Option zum Loggen, keine Schweregrade
        self.execute(action)

    # VERWUNDBAR: Fester Authentifizierungsmechanismus
    def authenticate(self, username, password):
        # Keine MFA-Option
        # Keine OAuth/SAML-Integration
        # Einzelne feste Auth-Methode
        return self.check_password(username, password)

    # VERWUNDBAR: Keine Rollenanpassung
    def check_permission(self, user, action):
        # Hartcodierte Rollen, kann keine benutzerdefinierten erstellen
        return user.role == 'admin'

# VERWUNDBAR: Keine Sicherheitskonfigurationsdatei-Unterstützung
# Keine Möglichkeit, Sicherheitseinstellungen aus Konfig zu laden
# Keine umgebungsspezifischen Sicherheitsprofile
// VERWUNDBAR: Node.js-App ohne Sicherheitskontrollen
const express = require('express');
const app = express();

// VERWUNDBAR: Hartcodierte Sicherheitseinstellungen
const config = {
    jwtSecret: 'hardcoded_jwt_secret',  // Kann nicht ändern
    sessionTimeout: 3600,  // Fest
    corsOrigin: '*',  // Kann nicht einschränken
    rateLimitEnabled: false  // Kann nicht aktivieren
};

// VERWUNDBAR: Keine Möglichkeit, Sicherheitsheader zu modifizieren
app.use((req, res, next) => {
    // Hartcodierte Header, nicht konfigurierbar
    res.setHeader('X-Frame-Options', 'SAMEORIGIN');
    // Admin kann nicht auf DENY ändern
    next();
});

// VERWUNDBAR: Feste Authentifizierung
class VulnerableAuth {
    constructor() {
        // Keine Konfigurationsoptionen
        this.hashRounds = 10;  // Fest
        this.tokenExpiry = '1h';  // Fest
        this.mfaEnabled = false;  // Kann nicht aktivieren
    }

    // Keine Admin-Methoden für:
    // - Ändern von Sicherheitseinstellungen
    // - Verwalten von API-Schlüsseln
    // - Anzeigen von Sicherheitslogs
    // - Konfigurieren von Rate-Limits
}

// VERWUNDBAR: Kein Sicherheits-Dashboard oder Management-UI
// VERWUNDBAR: Keine API für Sicherheitskonfiguration
// VERWUNDBAR: Kein Audit-Log-Zugriff
<?php
// VERWUNDBAR: PHP-Anwendung ohne Admin-Kontrollen

class VulnerableConfig {
    // VERWUNDBAR: Hartcodierte Sicherheitskonstanten
    const ADMIN_USER = 'admin';
    const ADMIN_PASS = 'password123';

    const SESSION_LIFETIME = 3600;
    const PASSWORD_ALGO = PASSWORD_DEFAULT;
    const MIN_PASSWORD_LENGTH = 4;

    // Keine Möglichkeit, diese zur Laufzeit zu ändern
    // Keine Admin-Schnittstelle zum Modifizieren
}

// VERWUNDBAR: Keine konfigurierbaren Sicherheitsfunktionen
class VulnerableSecurityManager {

    private $features = [
        'csrf_protection' => true,  // Hartcodiert
        'xss_filtering' => false,   // Kann nicht aktivieren
        'sql_escaping' => true,
        'rate_limiting' => false,   // Kann nicht aktivieren
        'ip_blocking' => false,     // Kann nicht aktivieren
    ];

    // Keine Setter, keine Admin-Schnittstelle
    public function isEnabled($feature) {
        return $this->features[$feature] ?? false;
    }

    // VERWUNDBAR: Keine Audit-Fähigkeiten
    public function logSecurityEvent($event) {
        // Logging ist hartcodiert aus, keine Möglichkeit zu aktivieren
        // Keine Log-Level-Konfiguration
        // Keine Log-Ziel-Optionen
    }
}

// VERWUNDBAR: Keine Benutzer/Rollen-Verwaltung
class VulnerableUserManager {
    // Hartcodierte Rollen
    private $roles = ['admin', 'user'];  // Kann keine benutzerdefinierten Rollen hinzufügen

    // Hartcodierte Berechtigungen
    private $permissions = [
        'admin' => ['*'],
        'user' => ['read']
    ];
    // Kann nicht modifizieren, keine RBAC-Schnittstelle
}
?>

Lösungscode

// SICHER: Umfassende administrative Sicherheitskontrollen
@Configuration
public class SecureSecurityConfig {

    @Value("${security.session.timeout:3600}")
    private int sessionTimeout;

    @Value("${security.password.minLength:12}")
    private int minPasswordLength;

    @Value("${security.mfa.enabled:false}")
    private boolean mfaEnabled;

    @Value("${security.bruteforce.protection:true}")
    private boolean bruteForceProtection;

    // SICHER: Anmeldedaten aus sicherer Konfiguration
    @Value("${admin.password.hash}")
    private String adminPasswordHash;

    // SICHER: Konfigurierbare Passwort-Richtlinie
    @Bean
    public PasswordPolicy passwordPolicy() {
        return PasswordPolicy.builder()
            .minLength(minPasswordLength)
            .requireUppercase(configService.getBoolean("password.requireUppercase", true))
            .requireNumber(configService.getBoolean("password.requireNumber", true))
            .requireSpecial(configService.getBoolean("password.requireSpecial", false))
            .build();
    }
}

// SICHER: Admin-Sicherheitsverwaltungs-API
@RestController
@RequestMapping("/admin/security")
@PreAuthorize("hasRole('SECURITY_ADMIN')")
public class SecurityAdminController {

    @Autowired
    private SecurityConfigService securityConfigService;

    @Autowired
    private AuditService auditService;

    // SICHER: Sicherheitseinstellungen aktualisieren
    @PutMapping("/settings")
    public ResponseEntity<?> updateSecuritySettings(@RequestBody SecuritySettings settings) {
        auditService.log("SECURITY_SETTINGS_CHANGE", settings);
        securityConfigService.update(settings);
        return ResponseEntity.ok().build();
    }

    // SICHER: Passwort-Richtlinie konfigurieren
    @PutMapping("/password-policy")
    public ResponseEntity<?> updatePasswordPolicy(@RequestBody PasswordPolicy policy) {
        auditService.log("PASSWORD_POLICY_CHANGE", policy);
        securityConfigService.updatePasswordPolicy(policy);
        return ResponseEntity.ok().build();
    }

    // SICHER: MFA aktivieren/deaktivieren
    @PostMapping("/mfa/toggle")
    public ResponseEntity<?> toggleMFA(@RequestParam boolean enabled) {
        auditService.log("MFA_TOGGLE", enabled);
        securityConfigService.setMFAEnabled(enabled);
        return ResponseEntity.ok().build();
    }

    // SICHER: Sicherheits-Audit-Logs anzeigen
    @GetMapping("/audit")
    public ResponseEntity<List<AuditEvent>> getAuditLogs(
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            @RequestParam(required = false) String eventType) {
        return ResponseEntity.ok(auditService.query(startDate, endDate, eventType));
    }

    // SICHER: Sicherheitsfunktionen verwalten
    @GetMapping("/features")
    public ResponseEntity<Map<String, Boolean>> getSecurityFeatures() {
        return ResponseEntity.ok(securityConfigService.getAllFeatures());
    }

    @PutMapping("/features/{feature}")
    public ResponseEntity<?> toggleFeature(
            @PathVariable String feature,
            @RequestParam boolean enabled) {
        auditService.log("FEATURE_TOGGLE", feature + ":" + enabled);
        securityConfigService.setFeature(feature, enabled);
        return ResponseEntity.ok().build();
    }
}

// SICHER: Rollenbasierte Zugriffskontrollverwaltung
@RestController
@RequestMapping("/admin/rbac")
public class RBACAdminController {

    @PostMapping("/roles")
    public ResponseEntity<?> createRole(@RequestBody Role role) {
        return ResponseEntity.ok(rbacService.createRole(role));
    }

    @PutMapping("/roles/{roleId}/permissions")
    public ResponseEntity<?> updatePermissions(
            @PathVariable Long roleId,
            @RequestBody List<Permission> permissions) {
        return ResponseEntity.ok(rbacService.updatePermissions(roleId, permissions));
    }
}
# SICHER: Python mit umfassenden Admin-Kontrollen
from dataclasses import dataclass
from typing import Dict, Any, Optional
import yaml

@dataclass
class SecuritySettings:
    session_timeout: int = 3600
    password_min_length: int = 12
    password_require_uppercase: bool = True
    password_require_number: bool = True
    password_require_special: bool = True
    mfa_enabled: bool = False
    rate_limiting_enabled: bool = True
    max_login_attempts: int = 5
    lockout_duration: int = 900
    audit_level: str = 'INFO'

class SecurityConfigService:
    def __init__(self, config_path: str = '/etc/app/security.yaml'):
        self.config_path = config_path
        self.settings = self._load_settings()
        self.audit_logger = AuditLogger()

    def _load_settings(self) -> SecuritySettings:
        """Einstellungen aus Konfigurationsdatei laden"""
        try:
            with open(self.config_path) as f:
                config = yaml.safe_load(f)
                return SecuritySettings(**config.get('security', {}))
        except FileNotFoundError:
            return SecuritySettings()

    def update_setting(self, key: str, value: Any, admin_user: str):
        """Admin kann jede Sicherheitseinstellung aktualisieren"""
        old_value = getattr(self.settings, key, None)

        # Änderung protokollieren
        self.audit_logger.log(
            event='SECURITY_SETTING_CHANGE',
            user=admin_user,
            details={
                'setting': key,
                'old_value': old_value,
                'new_value': value
            }
        )

        setattr(self.settings, key, value)
        self._save_settings()

    def _save_settings(self):
        """Einstellungen in Konfigurationsdatei speichern"""
        with open(self.config_path, 'w') as f:
            yaml.dump({'security': asdict(self.settings)}, f)

    def get_all_settings(self) -> Dict[str, Any]:
        """Alle Einstellungen für Admin-UI abrufen"""
        return asdict(self.settings)

# SICHER: Admin-API für Sicherheitsverwaltung
from flask import Flask, request, jsonify
from functools import wraps

app = Flask(__name__)
security_service = SecurityConfigService()

def require_security_admin(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        user = get_current_user()
        if not user.has_role('SECURITY_ADMIN'):
            return jsonify({'error': 'Verboten'}), 403
        return f(*args, **kwargs)
    return decorated

@app.route('/admin/security/settings', methods=['GET'])
@require_security_admin
def get_security_settings():
    """Alle Sicherheitseinstellungen abrufen"""
    return jsonify(security_service.get_all_settings())

@app.route('/admin/security/settings/<key>', methods=['PUT'])
@require_security_admin
def update_security_setting(key):
    """Eine Sicherheitseinstellung aktualisieren"""
    value = request.json.get('value')
    admin_user = get_current_user().username
    security_service.update_setting(key, value, admin_user)
    return jsonify({'success': True})

@app.route('/admin/security/audit', methods=['GET'])
@require_security_admin
def get_audit_logs():
    """Sicherheits-Audit-Logs abfragen"""
    start = request.args.get('start')
    end = request.args.get('end')
    event_type = request.args.get('type')
    logs = audit_service.query(start, end, event_type)
    return jsonify(logs)

@app.route('/admin/security/features', methods=['GET', 'PUT'])
@require_security_admin
def manage_features():
    """Sicherheitsfunktionen-Schalter verwalten"""
    if request.method == 'GET':
        return jsonify(security_service.get_features())
    else:
        feature = request.json.get('feature')
        enabled = request.json.get('enabled')
        security_service.toggle_feature(feature, enabled, get_current_user())
        return jsonify({'success': True})

# SICHER: Rollen- und Berechtigungsverwaltung
@app.route('/admin/rbac/roles', methods=['GET', 'POST'])
@require_security_admin
def manage_roles():
    if request.method == 'GET':
        return jsonify(rbac_service.get_all_roles())
    else:
        role = request.json
        created = rbac_service.create_role(role)
        return jsonify(created), 201
// SICHER: Node.js mit Admin-Sicherheitskontrollen
const express = require('express');
const fs = require('fs');
const yaml = require('js-yaml');

class SecurityConfigService {
    constructor(configPath = '/etc/app/security.yaml') {
        this.configPath = configPath;
        this.settings = this.loadSettings();
        this.auditLogger = new AuditLogger();
    }

    loadSettings() {
        try {
            const config = yaml.load(fs.readFileSync(this.configPath));
            return {
                sessionTimeout: config.session?.timeout ?? 3600,
                passwordMinLength: config.password?.minLength ?? 12,
                mfaEnabled: config.mfa?.enabled ?? false,
                rateLimitEnabled: config.rateLimit?.enabled ?? true,
                maxLoginAttempts: config.rateLimit?.maxAttempts ?? 5,
                corsOrigins: config.cors?.origins ?? [],
                auditLevel: config.audit?.level ?? 'INFO',
                ...config
            };
        } catch (e) {
            return this.getDefaultSettings();
        }
    }

    updateSetting(key, value, adminUser) {
        const oldValue = this.settings[key];

        this.auditLogger.log({
            event: 'SECURITY_SETTING_CHANGE',
            user: adminUser,
            setting: key,
            oldValue,
            newValue: value
        });

        this.settings[key] = value;
        this.saveSettings();
    }

    saveSettings() {
        fs.writeFileSync(this.configPath, yaml.dump(this.settings));
    }

    getAllSettings() {
        return { ...this.settings };
    }
}

// SICHER: Admin-Sicherheits-API
const router = express.Router();
const securityService = new SecurityConfigService();

// Middleware für Sicherheits-Admin-Prüfung
const requireSecurityAdmin = (req, res, next) => {
    if (!req.user?.hasRole('SECURITY_ADMIN')) {
        return res.status(403).json({ error: 'Verboten' });
    }
    next();
};

router.use(requireSecurityAdmin);

// Alle Sicherheitseinstellungen abrufen
router.get('/settings', (req, res) => {
    res.json(securityService.getAllSettings());
});

// Sicherheitseinstellung aktualisieren
router.put('/settings/:key', (req, res) => {
    const { key } = req.params;
    const { value } = req.body;
    securityService.updateSetting(key, value, req.user.username);
    res.json({ success: true });
});

// Sicherheitsfunktionen verwalten
router.get('/features', (req, res) => {
    res.json(securityService.getFeatures());
});

router.put('/features/:feature', (req, res) => {
    const { feature } = req.params;
    const { enabled } = req.body;
    securityService.toggleFeature(feature, enabled, req.user);
    res.json({ success: true });
});

// Audit-Logs abfragen
router.get('/audit', async (req, res) => {
    const { start, end, type } = req.query;
    const logs = await auditService.query(start, end, type);
    res.json(logs);
});

// RBAC-Verwaltung
router.get('/roles', (req, res) => {
    res.json(rbacService.getAllRoles());
});

router.post('/roles', (req, res) => {
    const role = rbacService.createRole(req.body);
    res.status(201).json(role);
});

router.put('/roles/:roleId/permissions', (req, res) => {
    rbacService.updatePermissions(req.params.roleId, req.body.permissions);
    res.json({ success: true });
});

module.exports = router;

Ausgenutzt in der Praxis

Hartcodierte Anmeldedaten

Standardpasswörter, die nicht geändert werden können, werden im großen Stil ausgenutzt.

Compliance-Versagen

Organisationen scheitern an Audits wegen unflexibler Sicherheit.

Vorfallreaktionslücken

Unfähigkeit, auf Verstöße zu reagieren wegen fehlender Kontrollen.


Werkzeuge zum Testen/Ausnutzen

  • Sicherheitskonfigurationsscanner.

  • Compliance-Audit-Tools.

  • Standard-Anmeldedaten-Scanner.


CVE-Beispiele

  • Zahlreiche CVEs durch hartcodierte Anmeldedaten.

  • IoT-Geräte mit unveränderlichen Passwörtern.


Referenzen

  1. MITRE. "CWE-671: Lack of Administrator Control over Security." https://cwe.mitre.org/data/definitions/671.html

  2. NIST-Sicherheitskonfigurationsrichtlinien.