防止 SQL 未经准备的注入 statements/SQLite/C++

Preventing SQL injection without prepared statements/SQLite/C++

如果有人能提供有关此方案针对 SQL 注入攻击的安全性的反馈,我将不胜感激。

在前端,用户输入个人信息:姓名、地址、phone 号码、电子邮件和一些自由格式的文本。

后端是用 C++ 从头开始​​编写的,没有框架支持,并集成了 SQLite。

C++ 代码使用SQLite 准备好的语句(由于历史原因,现在做任何事情都为时已晚)。相反,所有 SQL 语句都被构造为 printf 样式的格式字符串,如下所示:

#define STATEMENT_N "UPDATE members SET FirstName='%s', Surname='%s', DOB='%s', etc"

实际语句是用手动编码的 sprintf (sqlPrintf) 语句创建的,该语句仅处理 %s%c%d 转换.然后创建最终语句如下:

sqlPrintf(query_buffer, STATEMENT_N, user_str_1, user_str_2, etc)

因此,换句话说(如果您不熟悉 C/sprintf),用户输入 'printed' 到 %s%c%dsqlPrintf 中唯一不明显的处理是用户提供的单引号字符被转义(它们加倍)。

这足以防止 SQL 注入攻击吗? 'prepared statement' 是不是比上面的方案还要多?

基本上,您在这里唯一需要担心的是单引号。查询中包含在单引号内的任何内容都可以,但单独的单引号可以结束字符串,允许其余数据输入 运行 作为代码。如果 sqlPrintf 加倍单引号,你应该没问题。并阅读对您问题的评论,听起来该系统可以抵抗“';--”攻击。 :)

双引号足以防止字符串注入问题。字符串中没有其他可识别的特殊字符。
(请注意 SQLite 已经有 helper functions for this。)

如果您需要处理 blob,则无论如何都必须使用参数。但这是一个不同的问题......