mysql 存储过程 sql注入_存储过程是否可以防止SQL注入?

存储过程并不能神奇地阻止SQL注入,但是它们确实使防止注入变得容易得多。您所要做的只是类似以下内容(Postgres示例):

CREATEORREPLACEFUNCTIONmy_func(INin_user_id INT)[snip]SELECTuser_id,name,addressFROMmy_tableWHEREuser_id=in_user_id;--BAM! SQL INJECTION IMMUNE!![snip]

而已!仅在通过字符串串联(即动态SQL)形成查询时才会出现问题,即使在这种情况下,您也可以绑定!(取决于数据库。)

如何避免在动态查询中进行SQL注入:

步骤1)问问自己是否真的需要动态查询。如果只是为了设置输入而将字符串粘在一起,那么您可能做错了。(此规则有例外-一个例外是报告某些数据库上的查询,如果不强制每次执行都编译一个新查询,则可能会出现性能问题。但是请在跳入此问题之前对其进行研究。 )

步骤2)研究为特定RDBMS设置变量的正确方法。例如,Oracle使您可以执行以下操作(引用其文档):

sql_stmt:='UPDATE employees SET salary = salary + :1 WHERE '||v_column||' = :2';EXECUTEIMMEDIATE sql_stmtUSINGamount,column_value;--INJECTION IMMUNE!!

在这里,您仍然没有连接输入。您安全地绑定了!万岁!

如果您的数据库不支持上述功能(希望它们仍然没有问题,但我不会感到惊讶)-或者您仍然必须将输入连接起来(例如在“有时”将查询报告为我在上面暗示),那么您必须使用适当的转义功能。不要自己写。例如postgres提供quote_literal()函数。因此,您将运行:

sql_stmt:='SELECT salary FROM employees WHERE name = '||quote_literal(in_name);

这样,如果in_name像'[snip]或1 = 1'这样的变量((或“ 1 = 1”部分意味着选择所有行,允许用户查看他不应该的薪水!),那么quote_literal可以节省您的屁股生成结果字符串:

SELECTsalaryFROMemployeesWHEREname='[snip] or 1=1'

找不到结果(除非您有一些名字很奇怪的员工。)

这就是要旨!现在,让我留下Oracle专家Tom Kyte关于SQL Injection主题的经典文章的链接,以阐明这一点:Linky

你可能感兴趣的:(mysql,存储过程,sql注入)