FMDB SQL注入问题发现
早上测试妹纸给提了个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的时候,我哪管这些啊,翻了翻自己的代码,错误示例如图。
上图使用了NSString的Formatter,导致I'm这样的用户输入字符串在sql中识别错误。更严重的是可以利用它进行子sql操作,不过在app上这个风险影响范围比较小。
解决过程
不用想,百度了下"FMDB SQL注入"; 得到的解决方式是用?代替%@。然后把代码改成这个样子:
这段代码咋一看没有问题,然后,这里我的截图没有暴露一些关键信息。运行后,我收到了这样的错误,App闪退了。
上面这两张图是同一个错误,上下栈的关系。一开始我看的是有点懵逼,我以为是SQL注入那里没有解决好,没办法,继续搜,然后并没有找到方法。SQL注入的解决办法就是上面说的那样。
直到我找到了唐巧在2012年的一篇博客。这里有句话这样写道:
这里需要注意的是,参数必须是 NSObject 的子类,所以象 int,double,bool 这种基本类型,需要封装成对应的包装类才行
恍然大悟,我上面的几个参数里'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中参数与字段长度不一致会导致App闪退