Exposed Dangerous Method or Function
Description
Exposed Dangerous Method or Function is a vulnerability where software provides an API or similar interface for interaction with external actors, but the interface includes a dangerous method or function that is not properly restricted. This weakness occurs when critical functionality becomes accessible to unauthorized parties—either because functions were never intended for external exposure, or because functions that were restricted to limited actors became broadly accessible. The vulnerability applies across diverse technologies including ActiveX controls, Java functions, web APIs, and IOCTLs.
Risk
Exposing dangerous methods provides attackers with the privilege level of the exposed functionality. This can result in modification or exposure of sensitive data, execution of arbitrary code, or complete system compromise. In mobile applications, exposed JavaScript interfaces can be exploited to access device sensors, send SMS messages, or exfiltrate data. ActiveX controls marked safe-for-scripting can be abused from malicious web pages. Database methods with public visibility can be called by untrusted code to drop databases or bypass access controls. The severity depends entirely on what the exposed function can do.
Solution
Implement comprehensive access controls on all API methods. Use appropriate access modifiers (private, protected) to restrict method visibility. Never mark ActiveX controls as safe-for-scripting unless absolutely necessary and fully audited. Validate all arguments to exposed methods. For Android WebViews, use @JavascriptInterface annotations (Android 4.2+) and validate the origin of JavaScript calls. Enumerate all exposed functionality explicitly and categorize each function's intended audience. Apply defense in depth by assuming exposed methods may be called by attackers.
Common Consequences
| Impact | Details |
|---|---|
| Integrity | Scope: Integrity Modify Application Data - Exposed methods can be used to modify data in unauthorized ways. |
| Confidentiality | Scope: Confidentiality Read Application Data - Sensitive data may be accessible through exposed methods. |
| Access Control | Scope: Access Control, Integrity, Confidentiality, Availability Execute Unauthorized Code or Commands - Critical exposed methods can lead to arbitrary code execution. |
Example Code
Vulnerable Code
// Vulnerable: Public method exposes dangerous database operation
public class VulnerableDatabase {
private Connection conn;
// Vulnerable: Public method allows anyone to drop database!
public void removeDatabase(String databaseName) {
try {
Statement stmt = conn.createStatement();
// SQL injection also possible here
stmt.execute("DROP DATABASE " + databaseName);
} catch (SQLException ex) {
// Error handling
}
}
// Vulnerable: Public method exposes admin functionality
public void grantAdminRole(String username) {
executeSQL("GRANT ALL PRIVILEGES TO " + username);
}
}
// Any code can call:
// db.removeDatabase("production");
// db.grantAdminRole("attacker");
// Vulnerable: Android WebView with exposed JavaScript interface
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);
// Vulnerable: Exposes Java object to JavaScript
mainWebView.addJavascriptInterface(
new VulnerableInterface(), "appInterface");
// Load untrusted content
mainWebView.loadUrl(getIntent().getStringExtra("url"));
}
// Pre-Android 4.2: ALL public methods are accessible!
final class VulnerableInterface {
// Vulnerable: No @JavascriptInterface annotation (pre-4.2)
// Attackers can use reflection to access any Java class
public String getUserToken() {
return CurrentUser.getAuthToken(); // Sensitive!
}
public void sendSMS(String number, String message) {
SmsManager.getDefault().sendTextMessage(
number, null, message, null, null);
}
}
}
// Attacker's JavaScript (pre-Android 4.2):
// appInterface.getClass().forName('java.lang.Runtime')
// .getMethod('getRuntime', null).invoke(null, null)
// .exec('malicious command');
// Vulnerable: Web API with exposed dangerous endpoints
const express = require('express');
const app = express();
// Vulnerable: No authentication on dangerous endpoint
app.post('/api/admin/deleteAllUsers', (req, res) => {
// Anyone can call this!
database.query('DELETE FROM users');
res.send('All users deleted');
});
// Vulnerable: Exposed debug endpoint in production
app.get('/api/debug/config', (req, res) => {
res.json({
dbPassword: process.env.DB_PASSWORD,
apiKeys: process.env.API_KEYS,
internalUrls: config.internalServices
});
});
// Vulnerable: Unprotected file operations
app.get('/api/readFile', (req, res) => {
const filename = req.query.path;
// Exposes entire filesystem!
res.sendFile(filename);
});
// Vulnerable: ActiveX control marked safe for scripting
[ComVisible(true)]
[Guid("...")]
// Vulnerable: These attributes make control callable from web pages
[ClassInterface(ClassInterfaceType.None)]
public class VulnerableActiveX : IObjectSafety {
// Vulnerable: Dangerous file operation exposed
public void WriteFile(string path, string content) {
File.WriteAllText(path, content);
}
// Vulnerable: Execute arbitrary commands
public string ExecuteCommand(string command) {
var process = Process.Start("cmd.exe", "/c " + command);
return process.StandardOutput.ReadToEnd();
}
// IObjectSafety implementation marks as safe
public int SetInterfaceSafetyOptions(ref Guid riid,
int dwOptionSetMask, int dwEnabledOptions) {
return 0; // Vulnerable: Always returns success
}
}
Fixed Code
// Fixed: Proper access control on dangerous methods
public class SecureDatabase {
private Connection conn;
// Fixed: Private method - not accessible externally
private void removeDatabase(String databaseName) throws SQLException {
// Only internal code can call this
Statement stmt = conn.createStatement();
stmt.execute("DROP DATABASE ?");
stmt.setString(1, databaseName); // Parameterized
}
// Fixed: Protected method with authorization check
protected void removeDatabaseWithAuth(String databaseName,
User requestingUser) {
if (!requestingUser.hasRole("DBA")) {
throw new SecurityException("Unauthorized");
}
if (!validateDatabaseName(databaseName)) {
throw new IllegalArgumentException("Invalid database name");
}
removeDatabase(databaseName);
}
}
// Fixed: Android WebView with proper restrictions
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);
// Fixed: Only expose necessary methods with annotation
mainWebView.addJavascriptInterface(
new SecureInterface(), "appInterface");
// Fixed: Only load trusted URLs
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;
}
}
// Fixed: Only annotated methods are exposed (Android 4.2+)
final class SecureInterface {
@JavascriptInterface // Only this method is accessible
public String getPublicInfo() {
return "Non-sensitive public information";
}
// Fixed: No @JavascriptInterface - not accessible from JS
public String getSensitiveToken() {
return CurrentUser.getAuthToken();
}
// Fixed: Method requires additional verification
@JavascriptInterface
public boolean performAction(String action, String nonce) {
// Verify nonce to prevent CSRF-like attacks
if (!verifyNonce(nonce)) {
return false;
}
// Validate action is allowed
if (!ALLOWED_ACTIONS.contains(action)) {
return false;
}
return executeAction(action);
}
}
}
// Fixed: Web API with proper access controls
const express = require('express');
const app = express();
// Fixed: Middleware for authentication and authorization
const requireAuth = (req, res, next) => {
const token = req.headers.authorization;
if (!verifyToken(token)) {
return res.status(401).json({ error: 'Unauthorized' });
}
req.user = decodeToken(token);
next();
};
const requireAdmin = (req, res, next) => {
if (!req.user.isAdmin) {
return res.status(403).json({ error: 'Forbidden' });
}
next();
};
// Fixed: Protected with authentication and authorization
app.post('/api/admin/deleteAllUsers',
requireAuth,
requireAdmin,
(req, res) => {
// Only authenticated admins can reach here
auditLog('deleteAllUsers', req.user);
database.query('DELETE FROM users');
res.send('All users deleted');
}
);
// Fixed: Debug endpoint removed in production
if (process.env.NODE_ENV === 'development') {
app.get('/api/debug/config', requireAuth, requireAdmin, (req, res) => {
// Only in dev, and requires admin
res.json({ mode: 'debug' });
});
}
// Fixed: File access with proper validation
app.get('/api/readFile', requireAuth, (req, res) => {
const filename = req.query.path;
// Fixed: Validate path is within allowed directory
const safePath = path.join(ALLOWED_DIR, path.basename(filename));
if (!safePath.startsWith(ALLOWED_DIR)) {
return res.status(403).json({ error: 'Access denied' });
}
res.sendFile(safePath);
});
// Fixed: ActiveX control without dangerous safe-for-scripting
[ComVisible(true)]
[Guid("...")]
public class SecureActiveX {
// Fixed: No dangerous methods exposed
// Only expose necessary, safe functionality
public string GetVersion() {
return Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
// Fixed: If file operations needed, validate thoroughly
public bool SaveToAllowedLocation(string filename, string content) {
// Only allow specific directory
string safePath = Path.Combine(ALLOWED_DIR, Path.GetFileName(filename));
if (!safePath.StartsWith(ALLOWED_DIR)) {
return false;
}
// Only allow specific extensions
if (!ALLOWED_EXTENSIONS.Contains(Path.GetExtension(filename))) {
return false;
}
File.WriteAllText(safePath, content);
return true;
}
// Fixed: Don't implement IObjectSafety or mark as unsafe
}
CVE Examples
- CVE-2007-6382: Exposed Java method allowed arbitrary code execution.
- CVE-2007-1112: ActiveX control allowed unauthorized file download/upload to arbitrary directories.
- CVE-2012-6636: Android addJavascriptInterface vulnerability allowed arbitrary Java code execution.
References
- MITRE Corporation. "CWE-749: Exposed Dangerous Method or Function." https://cwe.mitre.org/data/definitions/749.html
- OWASP. "API Security Top 10."
- Android Security. "WebView JavaScript Interface Security."