如何防止 SQL 注入转义字符串

Posted

技术标签:

【中文标题】如何防止 SQL 注入转义字符串【英文标题】:How to prevent a SQL Injection escaping strings 【发布时间】:2011-09-26 17:45:36 【问题描述】:

我有一些查询(访问数据库)是这样的:

string comando = "SELECT * FROM ANAGRAFICA WHERE E_MAIL='" + user + "' AND PASSWORD_AZIENDA='" + password + "'";

我想“转义”用户和密码,防止注入。

如何使用 C# 和 .NET 3.5 来做到这一点?我在 php 上搜索类似 mysql_escape_string 的东西...

【问题讨论】:

【参考方案1】:

您需要使用参数。好吧,不必这样做,但会更好。

SqlParameter[] myparm = new SqlParameter[2];
myparm[0] = new SqlParameter("@User",user);
myparm[1] = new SqlParameter("@Pass",password);

string comando = "SELECT * FROM ANAGRAFICA WHERE E_MAIL=@User AND PASSWORD_AZIENDA=@Pass";

【讨论】:

不一定需要使用,但它们是最好的选择并且可靠地工作;-)。可能每一个本土变种都会有一些问题。 @Jethro :但是之后,我可以将实际值传递给查询吗?我需要将 myparam 数组传递给 SqlExecute 查询,不是吗? @Markzzz,是的,您需要将 sql 参数与查询一起传递,以便执行。将实际值传递给查询是什么意思?您会将实际值传递给构建查询的参数。 所以上面的代码(没有任何代码)应该可以工作吗?事实上它没有。现场用户转义到 myparm[0] 对吗?查询不知道该参数... 我的意思是:我不需要将这些参数添加到 SQL 连接?【参考方案2】:

不要转义开头的字符串 - 使用参数化查询。转义的好处:

代码更容易阅读 您不必依赖转义正确 可能会有性能改进(特定于 DB 等) 它将“代码”(SQL)与数据分开,这在逻辑上很合理 这意味着您无需担心数字和日期/时间等数据格式。

SqlCommand.Parameters 的文档提供了一个很好的完整示例。

【讨论】:

【参考方案3】:

您应该使用 SQL 参数来防止 SQL 注入 看代码

//
// The name we are trying to match.
//
string dogName = "Fido";
//
// Use preset string for connection and open it.
//
string connectionString = ConsoleApplication716.Properties.Settings.Default.ConnectionString;
using (SqlConnection connection = new SqlConnection(connectionString))

    connection.Open();
    //
    // Description of SQL command:
    // 1. It selects all cells from rows matching the name.
    // 2. It uses LIKE operator because Name is a Text field.
    // 3. @Name must be added as a new SqlParameter.
    //
    using (SqlCommand command = new SqlCommand("SELECT * FROM Dogs1 WHERE Name LIKE @Name", connection))
    
    //
    // Add new SqlParameter to the command.
    //
    command.Parameters.Add(new SqlParameter("Name", dogName));
    //
    // Read in the SELECT results.
    //
    SqlDataReader reader = command.ExecuteReader();
    while (reader.Read())
    
        int weight = reader.GetInt32(0);
        string name = reader.GetString(1);
        string breed = reader.GetString(2);
        Console.WriteLine("Weight = 0, Name = 1, Breed = 2", weight,    name, breed);
    
    

【讨论】:

【参考方案4】:

是的,您可以使用Named Parameters避免注入

【讨论】:

【参考方案5】:

使用参数而不是转义字符串:

var comando = "SELECT * FROM ANAGRAFICA WHERE E_MAIL=@user AND PASSWORD_AZIENDA=@password";

然后在执行SqlCommand之前为这些参数赋值。

【讨论】:

【参考方案6】:

您可以查看以下链接以了解如何防止 ASP.Net 中的 SQL 注入。我更喜欢使用

    使用参数化查询或存储过程。 验证特殊字符,如 '(非常危险)

http://dotnet.dzone.com/news/aspnet-preventing-sql-injectio

【讨论】:

【参考方案7】:

如果您可以将这些转换为命名参数,我认为您会得到更好的服务。

【讨论】:

好点,命名参数将是 C#/.NET 中的必然结果。【参考方案8】:

@Jethro

你也可以这样写:

SqlParameter[] sqlParams = new SqlParameter[] 
    new SqlParameter("@Name", contact.name),
    new SqlParameter("@Number", contact.number),
    new SqlParameter("@PhotoPath", contact.photoPath),
    new SqlParameter("@ID", contact.id)
;

【讨论】:

【参考方案9】:

PT: Siga os passos a seguir e resolva o problema de SQL INJECTION

EN:按照以下步骤解决 SQL INJECTION 问题:

ES:Siga los siguientes pasos y resolver el problema de la inyección de SQL:

OracleParameter[] tmpParans = new OracleParameter[1];

tmpParans[0] = new Oracle.DataAccess.Client.OracleParameter("@User", txtUser.Text);

string tmpQuery = "SELECT COD_USER, PASS FROM TB_USERS WHERE COD_USER = @User";

OracleCommand tmpComand = new OracleCommand(tmpQuery, yourConnection);

tmpComand.Parameters.AddRange(tmpParans);


OracleDataReader tmpResult = tmpComand.ExecuteReader(CommandBehavior.SingleRow);

【讨论】:

以上是关于如何防止 SQL 注入转义字符串的主要内容,如果未能解决你的问题,请参考以下文章

addslashes,htmlspecialchars,htmlentities转换或者转义php特殊字符防止xss攻击以及sql注入

防止XSS注入的方法

面试题:SQL注入漏洞总结

php如何防止sql注入

SpringMVC如何有效的防止XSS注入?

如何使用 Java 在 PostgreSQL 中安全地转义 SQL 的任意字符串