string sqlStr = ”用户输入“;
//先做一个判断
if(sqlStr.IndexOf(';') != -1)
{
//Do Something
}
//再做一个替换
sqlStr=sqlStr.Replace("'","''"); //将一个单引号'替换为两个单引号'',而不是双引号",在sql中,单引号是转义符。
try
{
conn.open();
//Some SqlComman;
}
catch (Exception ex)
{
Response.Write(ex.Message); //直接将错误信息显示给用户,可以考虑高级替换友好界面。
}
finally
{
conn.Close();
}
解析:先查找分隔符位置,当用户简单输入的时候,不允许有分号,防止进行攻击,如:
string Sql="SELECT * FROM MyTable WHERE MyTableId = ' " + userInput + " ' ";
当userInput = Take This ! ' ; DELETE FROM MyTable ;--
悲剧了! 导致生成的SQL语句:
SELECT * FROM MyTable WHERE MyTableId = 'Take This ! ' ; DELETE FROM MyTable ;--'
MyTable内容全部被删除,后面的单引号被注释了。
当然他必须知道你的表名称,但万不可因为这点,费尽心思思考奇怪的表名,导致自己的不方便。
但有时;会是用户的必要输入,所以替换字符串的单引号'就是第一道有用防线,防止一些小问题。
那么我们就应该用高级一些的方法,比如设置数据库账户权限,不允许有删除操作,或者用参数化查询SqlParameters来进行。
原文方法摘自-----C#2005数据库编程经典教程 Karli Watson
我用SqlParameters 方法:
许多人有一个误区:就是只用了SqlParameters参数化存储过程,但是查询语句还是拼接出来的。这样还是会被SQL注入。
正确的方法是使用SqlParameters + SQL存储过程
当有用户输入时,并且需要进行 WHERE 查询的时候。就预先设定存储过程,然后执行。比如登录、搜索。
并且存储过程的执行速度比SQL语句快,但是区别不明显。