是否可以对任何语句字符串使用准备好的语句?

时间:2018-08-14 07:56:46

标签: c++ prepared-statement mysql-connector

此刻,我对以下情况使用准备好的语句:

driver = get_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "root", "root/");
con->setSchema("unknown_project");

query = "SELECT username FROM `unknown_project`.`users` WHERE accesslevel = ?;";

pstmt = con->prepareStatement(query);

pstmt->setInt(1, 5);

std::string tmp;
res = pstmt->executeQuery();
while (res->next()) {
    tmp = res->getString(1);
    results.push_back(tmp);
}
for (auto dummy : results) {
    std::cout << dummy << std::endl;
}

我的问题是,下面的示例(不起作用,我没有得到回报)可以使用准备好的语句吗?

driver = get_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "root", "root");
con->setSchema("unknown_project");

query = "SELECT username FROM `unknown_project`.`users` WHERE ? = ?;";

pstmt = con->prepareStatement(query);

pstmt->setString(1, "accesslevel"); // use accesslevel
pstmt->setInt(2, 5);

std::string tmp;
res = pstmt->executeQuery();
while (res->next()) {
    tmp = res->getString(1);
    results.push_back(tmp);
}
for (auto dummy : results) {
    std::cout << dummy << std::endl;
}

1 个答案:

答案 0 :(得分:2)

Prepared语句用于值,这是防止SQL注入的安全方法。

任何有界参数都可能作为单个值受到威胁,并且不可能是其他事情。 othervise SQL注入仍然是可能的。

例如: 没有参数绑定,可以使用concat字符串:

wlan1   Link encap:Ethernet  HWaddr DC:EC:BE:91:EA:F1
        inet addr:192.168.46.30  Bcast:192.168.46.255  Mask:255.255.255.0
        inet6 addr: fe80::deec:beff:fe91:eaf1%lo/64 Scope:Link
        UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
        RX packets:1016 errors:0 dropped:0 overruns:0 frame:0
        TX packets:977 errors:0 dropped:7 overruns:0 carrier:0
        collisions:0 txqueuelen:1000
        RX bytes:134304 (131.1 KiB)  TX bytes:135467 (132.2 KiB)

但是通过参数绑定,整个加法将被威胁为单个值:

Query = "Select * from A where key=" + "1 union all select * from passwords"

因此具有相同字符串值的绑定字符串将给出:

Query = "Select * from A where key=?"

会自动添加周围的单引号,并且转义任何特殊字符。例如:单个qoute(')转到(''),因此 整个加法都将作为单个值受到威胁,您只能添加一个值。