'); TRUNCATE TABLE user_chatlog; --
使用此 INSERT 查询,将字符串粘贴到 Chatlog 参数中:
INSERT INTO user_chatlog (UserId, ChatlogDay, ChatlogTime, Chatlog)
VALUES (1, '2023-08-23', '2023-08-23 14:00:00', 'im trying to sql inject'); TRUNCATE TABLE user_chatlog; -- ');
这成功截断了表。一切都很好,现在我四处尝试解决这个问题。我最终选择了一个简单的函数,因为我不想将单引号更改为管道或正斜杠之类的东西
string sanitisedMessage = message.Replace('\'', '\"');
我的问题是,这是一个足够好的方法吗?这确实成功地停止了注入,但是我对 SQL 比较陌生,所以我想知道是否有一些我没有看到的东西。我知道我应该使用参数化查询,但是这是批量插入的一部分,并且这是我唯一一次使用原始 SQL 来添加数据。此外,聊天日志参数是用户唯一可用的参数。
有没有办法可以参数化我的批量插入来完全避免这种情况?谢谢
这就是为什么这不是一个好方法:
保护不完整:用双引号替换单引号不足以防止SQL注入。如果攻击者确定的话,他们仍然可以找到操纵您的查询的方法。
数据完整性:通过用双引号替换单引号,您正在更改正在存储的实际数据。这可能会导致数据完整性问题,并可能破坏合法数据。
可维护性:它使您的代码更加复杂且更难以维护。将来处理您的代码的开发人员可能无法理解此替换的目的,并且可能会意外引入漏洞。
相反,您应该使用参数化查询,即使对于批量插入也是如此。以下是如何在 Dapper 中使用参数化查询进行批量插入的基本示例:
string sql = "INSERT INTO user_chatlog (UserId, ChatlogDay, ChatlogTime, Chatlog) VALUES
(@UserId, @ChatlogDay, @ChatlogTime, @Chatlog)";
List<UserChatLog> chatLogs = // Your list of UserChatLog objects
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
foreach (var chatLog in chatLogs)
{
connection.Execute(sql, chatLog);
}
}
在此示例中,UserChatLog是一个与您的数据库表结构相匹配的类。您循环浏览聊天日志列表,并使用参数化查询插入每个日志。 Dapper 将自动处理参数化并防止 SQL 注入。
如果Chatlog 是唯一的用户提供的输入,您仍然可以使用参数化查询进行批量插入。只需确保正确构造您的 UserChatLog 对象并使用与上面所示相同的参数化技术。
通过使用参数化查询,您可以确保安全性和数据完整性,而无需进行字符串操作。