iOS小记--DB Error: 1 "near "m": syntax error"

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的时候,我哪管这些啊,翻了翻自己的代码,错误示例如图。

iOS小记--DB Error: 1
SQL注入风险错误代码.png

上图使用了NSString的Formatter,导致 I'm这样的用户输入字符串在sql中识别错误。更严重的是可以利用它进行子sql操作,不过在app上这个风险影响范围比较小。

解决过程

不用想,百度了下"FMDB SQL注入"; 得到的解决方式是用?代替%@。然后把代码改成这个样子:

解决SQL注入风险的代码

这段代码咋一看没有问题,然后,这里我的截图没有暴露一些关键信息。运行后,我收到了这样的错误,App闪退了。
iOS小记--DB Error: 1
CrashA.png

iOS小记--DB Error: 1
CrashB.png

上面这两张图是同一个错误,上下栈的关系。一开始我看的是有点懵逼,我以为是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闪退

你可能感兴趣的:(iOS小记--DB Error: 1 "near "m": syntax error")