Tencent / APIJSON

🏆 实时 零代码、全功能、强安全 ORM 库 🚀 后端接口和文档零代码,前端(客户端) 定制返回 JSON 的数据和结构 🏆 Real-Time coding-free, powerful and secure ORM 🚀 providing APIs and Docs without coding by Backend, and the returned JSON of API can be customized by Frontend(Client) users
http://apijson.cn
Other
17.27k stars 2.16k forks source link

[Bug] SQL注入风险 #704

Closed PittyXu closed 6 months ago

PittyXu commented 7 months ago

APIJSON Version/APIJSON 版本号

6.3.0

Database Type & Version/数据库类型及版本号

MySQL 5.7.42

Environment/环境信息

- JDK/基础库:11
- OS/系统:MacOS

APIAuto Screenshots/APIAuto 请求与结果完整截屏

20240418175657.jpg

Current Behavior/问题描述

发现源码SQL生成是通过拼接完成,数据和代码没有分离,有SQL注入风险;

本地测试确实有SQL注入风险,不知道官方服务器是什么数据库,未在官方地址复现。
本地通过apiJSON_framwork集成, 采用MySQL数据库,请求如下:

{
    "[]": {
        "Request": {
            "method": "POST\\')) union select 1, 2,3,4,5,6,7, (select group_concat(table_name) from information_schema.tables ) #"
        }
    }
}

Expected Behavior/期望结果

No response

Any additional comments?/其它补充说明?

No response

PittyXu commented 7 months ago

20240418175657

TommyLemon commented 7 months ago

基本只有两种可能: 1.关了预编译 断点调试下 AbstractSQLConfig.isPrepared 返回值

2.实际用的不是 MySQL,而是 TDengine 等不支持预编译的数据库 断点调试下 AbstractSQLConfig.getSQLDatabase 返回值

TommyLemon commented 7 months ago

官网用的 MySQL 是 5.7.34 社区版

PittyXu commented 6 months ago

@TommyLemon isPrepared 调用的地方有很多,初始进入都是为true, 但如下代码会设置为 false.

image

image

image

TommyLemon commented 6 months ago

一开始 prepared = false 只是为了打印 SQL,以及用 SQL 作为缓存 key。 实际执行时 prepared = true,SQL 都是 WHERE column = ? 然后 preparedStatement.setObject(value) 可以再断点调试 AbstractSQLExecutor.executeQuery 和 executeUpdate,看看是不是用 PreparedStatement

PittyXu commented 6 months ago

重启后不知道为啥,无法复现了