Exponierte gefährliche Methode oder Funktion

Beschreibung

Exponierte gefährliche Methode oder Funktion ist eine Schwachstelle, bei der Software eine API oder ähnliche Schnittstelle für die Interaktion mit externen Akteuren bereitstellt, aber die Schnittstelle eine gefährliche Methode oder Funktion enthält, die nicht ordnungsgemäß eingeschränkt ist. Diese Schwäche tritt auf, wenn kritische Funktionalität für nicht autorisierte Parteien zugänglich wird - entweder weil Funktionen nie für externe Exposition gedacht waren, oder weil Funktionen, die auf begrenzte Akteure beschränkt waren, breit zugänglich wurden. Die Schwachstelle gilt für verschiedene Technologien einschließlich ActiveX-Steuerelemente, Java-Funktionen, Web-APIs und IOCTLs.

Risiko

Das Exponieren gefährlicher Methoden gibt Angreifern das Privilegniveau der exponierten Funktionalität. Dies kann zur Modifikation oder Preisgabe sensibler Daten, Ausführung willkürlichen Codes oder vollständiger Systemkompromittierung führen. In mobilen Anwendungen können exponierte JavaScript-Schnittstellen ausgenutzt werden, um auf Gerätesensoren zuzugreifen, SMS zu senden oder Daten zu exfiltrieren. Als sicher-für-Scripting markierte ActiveX-Steuerelemente können von bösartigen Webseiten missbraucht werden. Datenbankmethoden mit öffentlicher Sichtbarkeit können von nicht vertrauenswürdigem Code aufgerufen werden, um Datenbanken zu löschen oder Zugriffskontrollen zu umgehen. Die Schwere hängt vollständig davon ab, was die exponierte Funktion tun kann.

Lösung

Implementieren Sie umfassende Zugriffskontrollen für alle API-Methoden. Verwenden Sie geeignete Zugriffsmodifikatoren (private, protected) um Methodensichtbarkeit einzuschränken. Markieren Sie ActiveX-Steuerelemente niemals als sicher-für-Scripting, es sei denn, es ist unbedingt erforderlich und vollständig geprüft. Validieren Sie alle Argumente für exponierte Methoden. Für Android WebViews verwenden Sie @JavascriptInterface-Annotationen (Android 4.2+) und validieren Sie den Ursprung von JavaScript-Aufrufen. Zählen Sie alle exponierte Funktionalität explizit auf und kategorisieren Sie die beabsichtigte Zielgruppe jeder Funktion. Wenden Sie Defense in Depth an, indem Sie davon ausgehen, dass exponierte Methoden von Angreifern aufgerufen werden könnten.

Häufige Auswirkungen

AuswirkungDetails
IntegritätBereich: Integrität

Anwendungsdaten modifizieren - Exponierte Methoden können verwendet werden, um Daten auf nicht autorisierte Weise zu modifizieren.
VertraulichkeitBereich: Vertraulichkeit

Anwendungsdaten lesen - Sensible Daten könnten durch exponierte Methoden zugänglich sein.
ZugriffskontrolleBereich: Zugriffskontrolle, Integrität, Vertraulichkeit, Verfügbarkeit

Nicht autorisierten Code oder Befehle ausführen - Kritische exponierte Methoden können zu willkürlicher Codeausführung führen.

Beispielcode

Verwundbarer Code

// Verwundbar: Öffentliche Methode exponiert gefährliche Datenbankoperation
public class VulnerableDatabase {

    private Connection conn;

    // Verwundbar: Öffentliche Methode erlaubt jedem, Datenbank zu löschen!
    public void removeDatabase(String databaseName) {
        try {
            Statement stmt = conn.createStatement();
            // SQL-Injection hier auch möglich
            stmt.execute("DROP DATABASE " + databaseName);
        } catch (SQLException ex) {
            // Fehlerbehandlung
        }
    }

    // Verwundbar: Öffentliche Methode exponiert Admin-Funktionalität
    public void grantAdminRole(String username) {
        executeSQL("GRANT ALL PRIVILEGES TO " + username);
    }
}

// Jeder Code kann aufrufen:
// db.removeDatabase("production");
// db.grantAdminRole("attacker");
// Verwundbar: Android WebView mit exponierter JavaScript-Schnittstelle
import android.webkit.JavascriptInterface;
import android.webkit.WebView;

public class VulnerableWebViewActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        WebView mainWebView = findViewById(R.id.webview);
        mainWebView.getSettings().setJavaScriptEnabled(true);

        // Verwundbar: Exponiert Java-Objekt an JavaScript
        mainWebView.addJavascriptInterface(
            new VulnerableInterface(), "appInterface");

        // Lädt nicht vertrauenswürdigen Inhalt
        mainWebView.loadUrl(getIntent().getStringExtra("url"));
    }

    // Pre-Android 4.2: ALLE öffentlichen Methoden sind zugänglich!
    final class VulnerableInterface {

        // Verwundbar: Keine @JavascriptInterface-Annotation (pre-4.2)
        // Angreifer können Reflection verwenden um auf jede Java-Klasse zuzugreifen

        public String getUserToken() {
            return CurrentUser.getAuthToken();  // Sensitiv!
        }

        public void sendSMS(String number, String message) {
            SmsManager.getDefault().sendTextMessage(
                number, null, message, null, null);
        }
    }
}

// Angreifers JavaScript (pre-Android 4.2):
// appInterface.getClass().forName('java.lang.Runtime')
//   .getMethod('getRuntime', null).invoke(null, null)
//   .exec('malicious command');
// Verwundbar: Web-API mit exponierten gefährlichen Endpunkten
const express = require('express');
const app = express();

// Verwundbar: Keine Authentifizierung auf gefährlichem Endpunkt
app.post('/api/admin/deleteAllUsers', (req, res) => {
    // Jeder kann dies aufrufen!
    database.query('DELETE FROM users');
    res.send('Alle Benutzer gelöscht');
});

// Verwundbar: Exponierter Debug-Endpunkt in Produktion
app.get('/api/debug/config', (req, res) => {
    res.json({
        dbPassword: process.env.DB_PASSWORD,
        apiKeys: process.env.API_KEYS,
        internalUrls: config.internalServices
    });
});

// Verwundbar: Ungeschützte Dateioperationen
app.get('/api/readFile', (req, res) => {
    const filename = req.query.path;
    // Exponiert gesamtes Dateisystem!
    res.sendFile(filename);
});
// Verwundbar: ActiveX-Steuerelement als sicher-für-Scripting markiert
[ComVisible(true)]
[Guid("...")]
// Verwundbar: Diese Attribute machen Steuerelement von Webseiten aufrufbar
[ClassInterface(ClassInterfaceType.None)]
public class VulnerableActiveX : IObjectSafety {

    // Verwundbar: Gefährliche Dateioperation exponiert
    public void WriteFile(string path, string content) {
        File.WriteAllText(path, content);
    }

    // Verwundbar: Willkürliche Befehle ausführen
    public string ExecuteCommand(string command) {
        var process = Process.Start("cmd.exe", "/c " + command);
        return process.StandardOutput.ReadToEnd();
    }

    // IObjectSafety-Implementierung markiert als sicher
    public int SetInterfaceSafetyOptions(ref Guid riid,
        int dwOptionSetMask, int dwEnabledOptions) {
        return 0;  // Verwundbar: Gibt immer Erfolg zurück
    }
}

Lösungscode

// Behoben: Ordnungsgemäße Zugriffskontrolle auf gefährlichen Methoden
public class SecureDatabase {

    private Connection conn;

    // Behoben: Private Methode - nicht extern zugänglich
    private void removeDatabase(String databaseName) throws SQLException {
        // Nur interner Code kann dies aufrufen
        Statement stmt = conn.createStatement();
        stmt.execute("DROP DATABASE ?");
        stmt.setString(1, databaseName);  // Parametrisiert
    }

    // Behoben: Geschützte Methode mit Autorisierungsprüfung
    protected void removeDatabaseWithAuth(String databaseName,
                                          User requestingUser) {
        if (!requestingUser.hasRole("DBA")) {
            throw new SecurityException("Nicht autorisiert");
        }
        if (!validateDatabaseName(databaseName)) {
            throw new IllegalArgumentException("Ungültiger Datenbankname");
        }
        removeDatabase(databaseName);
    }
}
// Behoben: Android WebView mit ordnungsgemäßen Einschränkungen
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.net.Uri;

public class SecureWebViewActivity extends Activity {

    private static final Set<String> TRUSTED_ORIGINS = Set.of(
        "https://trusted-app.example.com"
    );

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        WebView mainWebView = findViewById(R.id.webview);
        mainWebView.getSettings().setJavaScriptEnabled(true);

        // Behoben: Nur notwendige Methoden mit Annotation exponieren
        mainWebView.addJavascriptInterface(
            new SecureInterface(), "appInterface");

        // Behoben: Nur vertrauenswürdige URLs laden
        String url = getIntent().getStringExtra("url");
        if (isTrustedUrl(url)) {
            mainWebView.loadUrl(url);
        }
    }

    private boolean isTrustedUrl(String url) {
        try {
            Uri uri = Uri.parse(url);
            return TRUSTED_ORIGINS.contains(
                uri.getScheme() + "://" + uri.getHost());
        } catch (Exception e) {
            return false;
        }
    }

    // Behoben: Nur annotierte Methoden sind exponiert (Android 4.2+)
    final class SecureInterface {

        @JavascriptInterface  // Nur diese Methode ist zugänglich
        public String getPublicInfo() {
            return "Nicht-sensitive öffentliche Information";
        }

        // Behoben: Keine @JavascriptInterface - nicht von JS zugänglich
        public String getSensitiveToken() {
            return CurrentUser.getAuthToken();
        }

        // Behoben: Methode erfordert zusätzliche Verifikation
        @JavascriptInterface
        public boolean performAction(String action, String nonce) {
            // Nonce verifizieren um CSRF-ähnliche Angriffe zu verhindern
            if (!verifyNonce(nonce)) {
                return false;
            }
            // Validieren, dass Aktion erlaubt ist
            if (!ALLOWED_ACTIONS.contains(action)) {
                return false;
            }
            return executeAction(action);
        }
    }
}
// Behoben: Web-API mit ordnungsgemäßen Zugriffskontrollen
const express = require('express');
const app = express();

// Behoben: Middleware für Authentifizierung und Autorisierung
const requireAuth = (req, res, next) => {
    const token = req.headers.authorization;
    if (!verifyToken(token)) {
        return res.status(401).json({ error: 'Nicht autorisiert' });
    }
    req.user = decodeToken(token);
    next();
};

const requireAdmin = (req, res, next) => {
    if (!req.user.isAdmin) {
        return res.status(403).json({ error: 'Verboten' });
    }
    next();
};

// Behoben: Geschützt mit Authentifizierung und Autorisierung
app.post('/api/admin/deleteAllUsers',
    requireAuth,
    requireAdmin,
    (req, res) => {
        // Nur authentifizierte Admins können hierher gelangen
        auditLog('deleteAllUsers', req.user);
        database.query('DELETE FROM users');
        res.send('Alle Benutzer gelöscht');
    }
);

// Behoben: Debug-Endpunkt in Produktion entfernt
if (process.env.NODE_ENV === 'development') {
    app.get('/api/debug/config', requireAuth, requireAdmin, (req, res) => {
        // Nur in Dev, und erfordert Admin
        res.json({ mode: 'debug' });
    });
}

// Behoben: Dateizugriff mit ordnungsgemäßer Validierung
app.get('/api/readFile', requireAuth, (req, res) => {
    const filename = req.query.path;

    // Behoben: Validieren, dass Pfad innerhalb erlaubtem Verzeichnis ist
    const safePath = path.join(ALLOWED_DIR, path.basename(filename));

    if (!safePath.startsWith(ALLOWED_DIR)) {
        return res.status(403).json({ error: 'Zugriff verweigert' });
    }

    res.sendFile(safePath);
});
// Behoben: ActiveX-Steuerelement ohne gefährliches sicher-für-Scripting
[ComVisible(true)]
[Guid("...")]
public class SecureActiveX {

    // Behoben: Keine gefährlichen Methoden exponiert
    // Nur notwendige, sichere Funktionalität exponieren

    public string GetVersion() {
        return Assembly.GetExecutingAssembly().GetName().Version.ToString();
    }

    // Behoben: Wenn Dateioperationen benötigt, gründlich validieren
    public bool SaveToAllowedLocation(string filename, string content) {
        // Nur bestimmtes Verzeichnis erlauben
        string safePath = Path.Combine(ALLOWED_DIR, Path.GetFileName(filename));

        if (!safePath.StartsWith(ALLOWED_DIR)) {
            return false;
        }

        // Nur bestimmte Erweiterungen erlauben
        if (!ALLOWED_EXTENSIONS.Contains(Path.GetExtension(filename))) {
            return false;
        }

        File.WriteAllText(safePath, content);
        return true;
    }

    // Behoben: IObjectSafety nicht implementieren oder als unsicher markieren
}

CVE-Beispiele

  • CVE-2007-6382: Exponierte Java-Methode ermöglichte willkürliche Codeausführung.
  • CVE-2007-1112: ActiveX-Steuerelement ermöglichte nicht autorisierten Datei-Download/-Upload in willkürliche Verzeichnisse.
  • CVE-2012-6636: Android addJavascriptInterface-Schwachstelle ermöglichte willkürliche Java-Codeausführung.

Referenzen

  1. MITRE Corporation. "CWE-749: Exposed Dangerous Method or Function." https://cwe.mitre.org/data/definitions/749.html
  2. OWASP. "API Security Top 10."
  3. Android Security. "WebView JavaScript Interface Security."