我知道PreparedStatements避免/阻止SQL注入.它是如何做到的?使用PreparedStatements构造的最终表单查询是字符串还是其他?
我们正在讨论在我们的代码中使用参数化sql查询的另一个讨论.我们在讨论中有两个方面:我和其他一些人说我们应该总是使用参数来防止sql注入以及其他不认为有必要的人.相反,他们想要在所有字符串中用两个撇号替换单撇号以避免sql注入.我们的数据库都在运行Sql Server 2005或2008,我们的代码库运行在.NET framework 2.0上.
让我在C#中给你一个简单的例子:
我希望我们使用这个:
string sql = "SELECT * FROM Users WHERE Name=@name";
SqlCommand getUser = new SqlCommand(sql, connection);
getUser.Parameters.AddWithValue("@name", userName);
//... blabla - do something here, this is safe
Run Code Online (Sandbox Code Playgroud)
而其他人想要这样做:
string sql = "SELECT * FROM Users WHERE Name=" + SafeDBString(name);
SqlCommand getUser = new SqlCommand(sql, connection);
//... blabla - are we safe now?
Run Code Online (Sandbox Code Playgroud)
SafeDBString函数定义如下:
string SafeDBString(string inputValue)
{
return "'" + inputValue.Replace("'", "''") + "'";
}
Run Code Online (Sandbox Code Playgroud)
现在,只要我们在查询中的所有字符串值上使用SafeDBString,我们就应该是安全的.对?
使用SafeDBString函数有两个原因.首先,它是自石头老化以来完成的方式,其次,由于您看到在数据库上运行的精确查询,因此更容易调试sql语句.
那么.我的问题是使用SafeDBString函数是否真的足以避免sql注入攻击.我一直试图找到破坏这种安全措施的代码示例,但我找不到任何示例.
那里有人可以打破这个吗?你会怎么做?
编辑: 总结到目前为止的答复:
我很擅长使用数据库.现在我可以写SELECT,UPDATE,DELETE,和INSERT命令.但我看过很多我们喜欢写的论坛:
SELECT empSalary from employee where salary = @salary
Run Code Online (Sandbox Code Playgroud)
...代替:
SELECT empSalary from employee where salary = txtSalary.Text
Run Code Online (Sandbox Code Playgroud)
为什么我们总是喜欢使用参数以及如何使用它们?
我想知道第一种方法的用途和好处.我甚至听说过SQL注入,但我并不完全理解它.我甚至不知道SQL注入是否与我的问题有关.
我知道你绝不应该信任表单中的用户输入,主要是因为SQL注入的可能性.
但是,这是否也适用于唯一输入来自下拉列表的表单(见下文)?
我将保存$_POST['size']到一个会话,然后在整个站点中使用该会话来查询各种数据库(使用mysqliSelect查询),任何SQL注入肯定会损害(可能会丢失)它们.
查询数据库的类型用户输入没有区域,只有下拉列表.
<form action="welcome.php" method="post">
<select name="size">
<option value="All">Select Size</option>
<option value="Large">Large</option>
<option value="Medium">Medium</option>
<option value="Small">Small</option>
</select>
<input type="submit">
</form>
Run Code Online (Sandbox Code Playgroud) 可能重复:
如何从"Bobby Tables"XKCD漫画中注入SQL?
https://stackoverflow.com/search?q=sql+injection
有人可以解释SQL注入吗?它是如何导致漏洞的?注入SQL的确切位置在哪里?
我一直在向我的同事们讲道,在这里谈论在SQL查询中使用参数的好处,特别是在.NET应用程序中.我甚至承诺给予他们免受SQL注入攻击的抵抗力.
但我开始怀疑这是否真的如此.是否有任何已知的SQL注入攻击可以成功对抗参数化查询?例如,您可以发送一个导致服务器缓冲区溢出的字符串吗?
当然还有其他考虑因素可以确保Web应用程序是安全的(比如清理用户输入和所有内容),但现在我正在考虑SQL注入.我对MsSQL 2005和2008的攻击特别感兴趣,因为它们是我的主要数据库,但所有数据库都很有趣.
编辑:澄清参数和参数化查询的含义.通过使用参数我的意思是使用"变量"而不是在字符串中构建SQL查询.
所以不要这样做:
SELECT * FROM Table WHERE Name = 'a name'
Run Code Online (Sandbox Code Playgroud)
我们这样做:
SELECT * FROM Table WHERE Name = @Name
Run Code Online (Sandbox Code Playgroud)
然后在查询/命令对象上设置@Name参数的值.
是否有可能阻止Node.js中的SQL注入(最好使用模块),就像PHP具有保护它们的Prepared Statements一样.
如果是这样,怎么样?如果没有,有哪些例子可能会绕过我提供的代码(见下文).
一些背景:
我正在使用node-mysql模块制作一个带有Node.js + MySql的后端堆栈的Web应用程序.从可用性的角度来看,该模块很棒,但它还没有实现类似于PHP的Prepared Statements(虽然我知道它是在todo上).
根据我的理解,PHP的预处理语句的实现,尤其有助于防止SQL注入.但我担心,我的node.js应用程序可能会受到类似的攻击,即使默认情况下提供了字符串转义(如下面的代码片段).
node-mysql似乎是node.js最受欢迎的mysql连接器,所以我想知道其他人可能正在做什么(如果有的话)来解决这个问题 - 或者甚至是node.js开头的问题(不确定这是怎么回事,因为涉及用户/客户端输入).
我应该暂时切换到node-mysql-native,因为它确实提供了预准备语句吗?我对此犹豫不决,因为它似乎不像node-mysql那样活跃(尽管这可能只是意味着它已经完成).
这是一个用户注册代码片段,它使用sanitizer模块,以及node-mysql准备的类似语句的语法(如上所述,它可以进行字符转义),分别防止跨站点脚本和sql注入:
// Prevent xss
var clean_user = sanitizer.sanitize(username);
// assume password is hashed already
var post = {Username: clean_user, Password: hash};
// This just uses connection.escape() underneath
var query = connection.query('INSERT INTO users SET ?', post,
function(err, results)
{
// Can a Sql injection happen here?
});
Run Code Online (Sandbox Code Playgroud) 如果是,为什么还有那么多成功的SQL注入?仅仅因为一些开发人员太愚蠢而无法使用参数化语句?
为了开始这个,我很清楚参数化查询是最好的选择,但我想知道是什么让我在下面提出的策略容易受到攻击.人们坚持认为下面的解决方案不起作用,所以我找一个为什么它不会这样做的例子.
如果在发送到SQL Server之前使用以下转义在代码中构建动态SQL,那么什么样的注入可以打败这个?
string userInput= "N'" + userInput.Replace("'", "''") + "'"
Run Code Online (Sandbox Code Playgroud)
在SQL Server中无法使用"\"转义单引号.
我相信使用Unicode进行SQL走私(此处概述)会被生成的字符串被单引号前面的N标记为Unicode这一事实所阻碍.据我所知,SQL Server没有其他字符集会自动转换为单引号.没有未转义的单引号,我不相信注射是可能的.
我不相信String Truncation也是一个可行的载体.SQL Server肯定不会截断,因为根据microsoft,a的最大大小为nvarchar2GB .在大多数情况下,2 GB的字符串是不可行的,在我的情况下是不可能的.
二阶注入是可能的,但如果可能的话:
我并不是说这比使用参数化查询更好或者替代,但我想知道我概述的内容是如何易受攻击的.有任何想法吗?
如果你搜索:
你会看到许多试图破解的例子:
1) declare @q varchar(8000) select @q = 0x57414954464F522044454C4159202730303A30303A313527 exec(@q) --
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?它正在尝试使用哪个数据库?你知道有关于此的任何建议吗?
sql-injection ×10
sql ×5
sql-server ×4
security ×3
asp.net ×2
mysql ×2
t-sql ×2
c# ×1
database ×1
exploit ×1
java ×1
javascript ×1
jdbc ×1
mysqli ×1
node-mysql ×1
node.js ×1
php ×1
sanitization ×1
windows ×1