FMDB SQL注入問題發(fā)現(xiàn)
早上測試妹紙給提了個bug,給的日志信息有以下兩條:
2018-12-12 09:56:46.390610+0800 IwownFit[1015:508981] DB Error: 1 "near "m": syntax error"
2018-12-12 09:56:46.390765+0800 IwownFit[1015:508981] DB Query: INSERT OR REPLACE INTO Schedule_s (uid , date , title, subTitle, state ,ringSetting) values ('154138128173020196', '2018-12-12 10:03:00', 'I'm ', '(null)', 1, 195)
好家伙,SQL注入。哈哈哈,寫Restful Api的時候肯定會注意這個問題,按理說這個低級錯誤不該犯,但是早期寫app的時候,我哪管這些啊,翻了翻自己的代碼,錯誤示例如圖。

SQL注入風險錯誤代碼.png
上圖使用了NSString的Formatter,導致I'm這樣的用戶輸入字符串在sql中識別錯誤。更嚴重的是可以利用它進行子sql操作,不過在app上這個風險影響范圍比較小。
解決過程
不用想,百度了下"FMDB SQL注入"; 得到的解決方式是用?代替%@。然后把代碼改成這個樣子:

解決SQL注入風險的代碼
這段代碼咋一看沒有問題,然后,這里我的截圖沒有暴露一些關鍵信息。運行后,我收到了這樣的錯誤,App閃退了。

CrashA.png

CrashB.png
上面這兩張圖是同一個錯誤,上下棧的關系。一開始我看的是有點懵逼,我以為是SQL注入那里沒有解決好,沒辦法,繼續(xù)搜,然后并沒有找到方法。SQL注入的解決辦法就是上面說的那樣。
直到我找到了唐巧在2012年的一篇博客。這里有句話這樣寫道:
這里需要注意的是,參數(shù)必須是 NSObject 的子類,所以象 int,double,bool 這種基本類型,需要封裝成對應的包裝類才行
恍然大悟,我上面的幾個參數(shù)里'state'和'ringSetting'都是基本類型。修改代碼如下,解決問題。
__block BOOL _safe_success;
[self.deviceDBQueue inDatabase:^(FMDatabase *db) {
NSString *ssql = @"INSERT OR REPLACE INTO Schedule_s (uid , date , title, subTitle, state ,ringSetting) values (?, ?, ?, ?, ?, ?);";
_safe_success = [db executeUpdate:ssql, uid, dateS, title, subTitle, @(state) ,@(ringSetting)];
}];
return _safe_success;
結論
- 通過使用占位符"?" 代替NSString格式化中的"%@"可以解決SQL注入的問題
- 基礎類型需要轉成NSNumber才能使用"?"作為占位符
- FMDB中參數(shù)與字段長度不一致會導致App閃退