2017-07-27 52 views
-2

這個錯誤發生在行SQL錯誤:近 「:02」:語法錯誤

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); 
+5

'cout << ...'會暗示需要一個C++標記而不是C. –

+0

請參閱[準備查詢](https://stackoverflow.com/questions/4820374/sqlite-escape-string-c) 。 – tadman

回答

0

尋址你的直接問題,你的字符串沒有引用:

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 ...

enter image description here

來處理這個正確的方法是使用準備好的語句與參數綁定。這可以防止這些類型的攻擊,並且比嘗試手動清理輸入更可靠。

查看SQLite page for prepared statements瞭解如何做到這一點的詳細信息。

+2

這個「解決方案」會像你說的那樣創建一個SQL注入漏洞。它幾乎不是一個解決方案,它只是武器化以前破壞的代碼。 – tadman

+0

@tadman增加了更多關於SQL注入不好的細節和示例,並且討論了更多關於參數綁定的內容。 – dbush

+0

呃,那很明顯,這是一個警告,但準備好的聲明版本是最好的。 – tadman