SQL 注入缺陷
SQL Injection flaw
我正在处理一个项目,客户报告代码中存在 SQL 注入缺陷。这是我的代码……
1 public int ExecuteNonQuery(string query, SqlParameter[] parameters)
2 {
3 using (SqlCommand command = CreateCommand(query, parameters))
4 {
5 int rowsAffected = command.ExecuteNonQuery();
6 return rowsAffected;
7 }
8 }
CreateCommand
方法为
private SqlCommand CreateCommand(string commandText, SqlParameter[] parameters)
{
SqlCommand retVal = this.connection.CreateCommand();
retVal.CommandText = commandText;
retVal.CommandTimeout = this.commandsTimeout;
retVal.Parameters.AddRange(parameters);
return retVal;
}
在行号 3 报告了该缺陷。我无法理解这里发生了什么样的攻击,因为这是一个控制台应用程序。但是我必须修复这个缺陷,我不知道如何修复它。
查询是
@"delete from {0} where runId in
( select runId from {0}
inner join
( select sId as sId_last,
wfId as wfId_last,
max(runId) as runId_last from {0} where endTime is NULL
group by sId, wfId ) t1
on endTime is NULL and sId = sId_last and wfId = wfId_last
and (runId <> runId_last or startTime < @aDateTime)
)";
感谢帮助。
谢谢。
代码是无注入的...但请注意,调用 ExecuteNonQuery
的方法可以通过组合字符串来构建 query
。
当您执行以下操作时会发生注入攻击:
string name = ...; // A name selected by the user.
string query = "SELECT * FROM MyTable WHERE Name = '" + name + "'";
因此,当您使用来自外部的文本片段编写查询时。
请注意,更微妙的注入攻击可能是多层次的:
string name = // The result of a query to the db that retrieves some data
// sadly this data has been manipulated by the attacker
string query = "SELECT * FROM MyTable WHERE Name = '" + name + "'";
一般来说,你不需要用户界面来引起注入攻击...
您可以从 Web site/from 数据库中查询某些内容,并使用未经过滤的结果来查询数据库(如上一个示例),导致注入攻击...甚至使用的内容配置文件可能导致注入攻击:修改配置文件所需的权限可能与在数据库上执行某些操作所需的权限不同,恶意用户可能拥有修改配置文件的权限但不能直接访问数据库。这样他就可以把这个程序当做特洛伊木马来攻击数据库了。
关于查询
该查询(即字符串的组合)的弱点在于 {0}
的计算方式。是在一组固定字符串中选出的字符串吗?类似于:
string tableName;
if (foo)
tableName = "Foo";
else if (bar)
tableName = "Bar";
还是更多用户控制的东西?
如果 table 名称在代码中是固定的,那么应该没有任何注入攻击的可能。如果 table 名称是来自某个用户 input/some 的 "extracted",其他 table 用户可以访问,我们 return 解决了我之前展示的问题。
您公开了一个 public
方法,任何允许执行任何 SQL 表达式的代码都可以访问该方法。
我会考虑将该方法更改为 internal
或 private
,这样不仅任何代码都可以调用该方法。
第 3 行:
using (SqlCommand command = CreateCommand(query, parameters))
查询和参数都可以在这一行中使用。
SQL 不应通过尝试验证您的输入来阻止注入;相反,应该在将输入传递到数据库之前正确转义该输入。
如何转义输入完全取决于您使用何种技术与数据库交互。
Use prepared statements and parameterized queries. These are SQL
statements that are sent to and parsed by the database server
separately from any parameters. This way it is impossible for an
attacker to inject malicious SQL.
Lesson on SQL injection for your reference.link2
我正在处理一个项目,客户报告代码中存在 SQL 注入缺陷。这是我的代码……
1 public int ExecuteNonQuery(string query, SqlParameter[] parameters)
2 {
3 using (SqlCommand command = CreateCommand(query, parameters))
4 {
5 int rowsAffected = command.ExecuteNonQuery();
6 return rowsAffected;
7 }
8 }
CreateCommand
方法为
private SqlCommand CreateCommand(string commandText, SqlParameter[] parameters)
{
SqlCommand retVal = this.connection.CreateCommand();
retVal.CommandText = commandText;
retVal.CommandTimeout = this.commandsTimeout;
retVal.Parameters.AddRange(parameters);
return retVal;
}
在行号 3 报告了该缺陷。我无法理解这里发生了什么样的攻击,因为这是一个控制台应用程序。但是我必须修复这个缺陷,我不知道如何修复它。
查询是
@"delete from {0} where runId in
( select runId from {0}
inner join
( select sId as sId_last,
wfId as wfId_last,
max(runId) as runId_last from {0} where endTime is NULL
group by sId, wfId ) t1
on endTime is NULL and sId = sId_last and wfId = wfId_last
and (runId <> runId_last or startTime < @aDateTime)
)";
感谢帮助。 谢谢。
代码是无注入的...但请注意,调用 ExecuteNonQuery
的方法可以通过组合字符串来构建 query
。
当您执行以下操作时会发生注入攻击:
string name = ...; // A name selected by the user.
string query = "SELECT * FROM MyTable WHERE Name = '" + name + "'";
因此,当您使用来自外部的文本片段编写查询时。
请注意,更微妙的注入攻击可能是多层次的:
string name = // The result of a query to the db that retrieves some data
// sadly this data has been manipulated by the attacker
string query = "SELECT * FROM MyTable WHERE Name = '" + name + "'";
一般来说,你不需要用户界面来引起注入攻击...
您可以从 Web site/from 数据库中查询某些内容,并使用未经过滤的结果来查询数据库(如上一个示例),导致注入攻击...甚至使用的内容配置文件可能导致注入攻击:修改配置文件所需的权限可能与在数据库上执行某些操作所需的权限不同,恶意用户可能拥有修改配置文件的权限但不能直接访问数据库。这样他就可以把这个程序当做特洛伊木马来攻击数据库了。
关于查询
该查询(即字符串的组合)的弱点在于 {0}
的计算方式。是在一组固定字符串中选出的字符串吗?类似于:
string tableName;
if (foo)
tableName = "Foo";
else if (bar)
tableName = "Bar";
还是更多用户控制的东西?
如果 table 名称在代码中是固定的,那么应该没有任何注入攻击的可能。如果 table 名称是来自某个用户 input/some 的 "extracted",其他 table 用户可以访问,我们 return 解决了我之前展示的问题。
您公开了一个 public
方法,任何允许执行任何 SQL 表达式的代码都可以访问该方法。
我会考虑将该方法更改为 internal
或 private
,这样不仅任何代码都可以调用该方法。
第 3 行:
using (SqlCommand command = CreateCommand(query, parameters))
查询和参数都可以在这一行中使用。
SQL 不应通过尝试验证您的输入来阻止注入;相反,应该在将输入传递到数据库之前正确转义该输入。
如何转义输入完全取决于您使用何种技术与数据库交互。
Use prepared statements and parameterized queries. These are SQL statements that are sent to and parsed by the database server separately from any parameters. This way it is impossible for an attacker to inject malicious SQL.
Lesson on SQL injection for your reference.link2