#900·eladmin

[Security] Server-Side Request Forgery (SSRF) via Insecure JDBC Connection Testing

Author: AnalogyC0deCreated May 13, 2026Updated May 13, 2026

[Security] Server-Side Request Forgery (SSRF) via Insecure JDBC Connection Testing

Identification

  • Affected Version/Commit: <= v2.7 (2026.04.21)

CVE Description

A Server-Side Request Forgery (SSRF) vulnerability exists in the database connection testing feature of elunez_eladmin. While connecting to remote databases is an intended business function, the application fails to implement proper network boundaries or strictly sanitize the JDBC URL. The application's weak blacklist filter (sanitizeJdbcUrl) attempts to block dangerous properties but can be bypassed. Consequently, an authenticated user with database:testConnect permissions can supply arbitrary internal IPs, restricted loopback addresses, or non-database ports. This abuses the application server as a confused deputy to probe internal network topologies, discover hidden services behind firewalls, and potentially trigger secondary vulnerabilities (like deserialization or arbitrary file read) via malicious JDBC parameters.

Affected Component

  • File(s):
    • me/zhengjie/modules/maint/rest/DatabaseController.java
    • me/zhengjie/modules/maint/utils/SqlUtils.java
  • Function / Method: DatabaseController.testConnect(), SqlUtils.testConnection(), SqlUtils.sanitizeJdbcUrl()
  • Entry Point: POST /api/database/testConnect (JSON field: jdbcUrl)

Reproduction Summary

  1. Authenticate to the application with a user account having database:testConnect permissions.
  2. Send a POST request to /api/database/testConnect with a payload specifying a restricted internal IP address, port, or malicious JDBC property that circumvents the weak blacklist (e.g., jdbc:mysql://127.0.0.1:6379/test to probe local Redis, or probing internal subnets 192.168.x.x).
  3. Observe the application's responses (success, timeout, or authentication error) which act as an oracle to enumerate internal network topology, proving the server can be abused to bypass network segmentation.

Technical Details

// me/zhengjie/modules/maint/rest/DatabaseController.java (Line 101)
@ApiOperation(value = "测试数据库链接")
@PostMapping("/testConnect")
@PreAuthorize("@el.check('database:testConnect')")
public ResponseEntity<Object> testConnect(@Validated @RequestBody Database resources){
    return new ResponseEntity<>(databaseService.testConnection(resources), HttpStatus.CREATED);
}
  private static DataSource getDataSource(String jdbcUrl, String userName, String password) {
      DruidDataSource druidDataSource = new DruidDataSource();
      String className;
      try {
          className = DriverManager.getDriver(jdbcUrl.trim()).getClass().getName();  // 第53行
      } catch (SQLException e) {
          throw new RuntimeException("Get class name error: =" + jdbcUrl);
      }
      // ...
      jdbcUrl = sanitizeJdbcUrl(jdbcUrl);  // 第68行 — 消毒在此处才执行
      druidDataSource.setUrl(jdbcUrl);
      // ...
  }

// me/zhengjie/modules/mrest/utils/SqlUtils.java (Line 211)
// Proof of failed intended security: Only filters known parameters via weak blacklist, no host/port/loopback restrictions
 private static String sanitizeJdbcUrl(String jdbcUrl) {
      String[][] unsafeParams = {
          {"allowLoadLocalInfile", "false"},
          {"allowUrlInLocalInfile", "false"},
          {"autoDeserialize", "false"},
          {"allowNanAndInf", "false"},
          {"allowMultiQueries", "false"},
          {"allowPublicKeyRetrieval", "false"}
      };
      for (String[] param : unsafeParams) {
          jdbcUrl = jdbcUrl.replaceAll("(?i)" + param[0] + "=true", param[0] + "=" + param[1]);
      }
      return jdbcUrl;
  }
// me/zhengjie/modules/mrest/utils/SqlUtils.java (Line 195)
// The unsanitized/partially sanitized URL reaches the sink
[SqlUtils.testConnection()] -> [DriverManager.getConnection(jdbcUrl, user, pass)]

Validation Notes

  • Endpoint: Verified at DatabaseController.java:101.
  • Sink: Verified at SqlUtils.testConnection() -> DriverManager.getConnection().
  • Validation Defect: Verified at SqlUtils.java:211-232. sanitizeJdbcUrl() explicitly attempts to filter dangerous JDBC properties but uses a bypassable blacklist and lacks any destination scope restrictions (no protection against internal network/loopback access).