【问题标题】:SQL error: near ":02": syntax errorSQL 错误:“:02”附近:语法错误
【发布时间】:2017-07-27 17:59:49
【问题描述】:

这个错误发生在行

    sprintf(sql, "INSERT INTO Device_Details (imei, mobile_num, passwd, Dev_addr, id) "  \
             "VALUES (%s, %d, %s, %s, %d ); ", imei, id, passwd, dev_addr, id);
rc = sqlite3_exec(db, sql, 0, 0, &zErrMsg);

在哪里

char*  passwd, *imei, *mobile_num, *strtok_var ;
cout<<idIndex << "+" << passwd<<"+"<<imei << "+" << mobile_num << endl;

打印 1+abc+abc+abc

创建的表

sql = "CREATE TABLE Device_Details("  \
            "imei CHAR(32) PRIMARY KEY     NOT NULL," \
            "mobile_num    INT    NOT NULL," \
            "passwd        CHAR(50) ," \
            "Dev_addr        CHAR(50) ," \
            "id            INT);";

        /* Execute SQL statement */
        rc = sqlite3_exec(db, sql, 0/*callback*/, 0, &zErrMsg);

【问题讨论】:

  • cout&lt;&lt;... 会暗示这需要一个 C++ 标签而不是 C。

标签: c++ linux sqlite


【解决方案1】:

解决您的直接问题,您的字符串不被引用:

sprintf(sql, "INSERT INTO Device_Details (imei, mobile_num, passwd, Dev_addr, id) "  \
         "VALUES ('%s', %d, '%s', '%s', %d ); ", imei, id, passwd, dev_addr, id);

但是,我强烈建议不要手动创建这样的 SQL 语句。这样做会暴露SQL injection 攻击。

例如,假设有人将以下字符串用于passwd:

', '', 1);  drop table Device_Details; --

生成的 SQL 如下所示:

INSERT INTO Device_Details (imei, mobile_num, passwd, Dev_addr, id)
VALUES ('+', 1, '', '', 1);  drop table Device_Details; --', 'dev_addr', 1 );

这将关闭原始INSERT 语句,添加DELETE TABLE 语句,并删除原始INSERT 的其余部分。现在您的表格和其中的所有数据都消失了。一定要注意little Bobby tables...

处理这个问题的正确方法是使用带有参数绑定的预处理语句。这可以防止此类攻击,并且比尝试手动清理输入更可靠。

有关如何执行此操作的详细信息,请参阅SQLite page for prepared statements。

【讨论】:

  • 这个“解决方案”会像你说的那样创建一个 SQL 注入错误。这根本不是一个解决方案,它只是将以前破坏的代码武器化。
  • @tadman 添加了更多细节和示例说明 SQL 注入为何不好,并进一步讨论了参数绑定。
  • 嘿,好吧,这显然是一个警告,但最好是准备好的声明版本。
猜你喜欢
  • 1970-01-01
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 2017-01-15
  • 2016-03-12
  • 2018-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多