我已经看到SQL注入字符串通常是这样构造的:
' ; DROP DATABASE db --
因此,如果我不允许在我的应用程序输入中使用分号,这是否100%防止任何SQL注入攻击?
答案 0 :(得分:9)
使用参数化查询(或存储过程)并避免像瘟疫这样的动态SQL。
我建议使用内置的库函数,而不是尝试编写自己的反注入代码。
一个天真的实现将剥离;
,即使它应该被使用(比如传入VARCHAR或CHAR参数,它是合法的)。您最终必须编写自己的SQL解析器才能接受/拒绝查询。
您可以阅读here有关动态SQL及其呈现(和解决)的问题的更多信息。
答案 1 :(得分:8)
不,它不会阻止sql注入攻击。无论何时在客户端动态构建SQL,或者在存储过程中使用EXEC,都存在风险。
参数化查询是获取查询输入的首选方式。
答案 2 :(得分:4)
不,它没有。您刚刚展示了SQL注入的一个示例。但是还有更多,全部取决于您将数据插入的上下文。
除此之外,导致此问题的不是分号,而是'
过早地结束字符串声明。将输入数据正确编码到prevent SQL injection。
答案 3 :(得分:3)
避免SQL注入的最佳方法是避免用户提供的数据的字符串连接。最好通过使用存储过程或使用参数化查询来实现。
答案 4 :(得分:2)
不,不要专注于分号。关注将用户输入放入sql查询的方式 - 通常用引号 - 然后专注于引号。另外不要忘记在sql中使用regexp时,他们需要稍微不同的转义过程。
答案 5 :(得分:1)
它将取决于各种事物(查询等)。你应该使用准备好的陈述
答案 6 :(得分:1)
它可能停止注入像您的drop那样的辅助DDL语句,因为它们很可能会在select中创建语法错误,但是它不会停止这样的语句:
返回的数据超出预期
' or 1=1
删除输出
' or 1 in (select * from (delete someOtherTable OUTPUT DELETED.* ) a)
注入攻击围绕着对预期SQL语句的任何操纵,而不仅仅是终止该语句并注入第二条语句。
注入攻击来自未经消毒的用户输入
但是,重要的是不要将SQL注入攻击与动态/内联sql完全混为一谈。 SQL注入攻击来自动态sql中未使用中文的用户输入使用。您可以毫无问题地“构建”查询,只要该查询的所有组件均来自您信任的来源即可。例如,我们使用架构保存自定义结构...
$"select * from {customSchemaName}.EmployeeExtension where id=@id and clientid=@clientId"
从输入的角度来看,以上仍然是一个参数化查询,但是架构名称是没有接口可以访问的内部系统查询。
我在这里说明内联/动态sql: https://dba.stackexchange.com/a/239571/9798