从用户控制的来源构建的 SQL 查询¶
ID: rb/sql-injection
Kind: path-problem
Security severity: 8.8
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-089
Query suites:
- ruby-code-scanning.qls
- ruby-security-extended.qls
- ruby-security-and-quality.qls
如果数据库查询(例如 SQL 或 NoSQL 查询)是在没有足够的清理的情况下从用户提供的数据构建的,恶意用户可能能够运行恶意数据库查询。
建议¶
大多数数据库连接器库提供了一种通过查询参数或准备好的语句安全地将不可信数据嵌入查询的方法。
示例¶
在以下 Rails 示例中,一个 ActionController
类有一个 text_bio
方法来处理获取指定用户传记的请求。
用户由客户端提供的参数 user_name
指定。此值可以使用 params
方法访问。
该方法演示了三种不同的方法来构建和执行 SQL 查询以按名称查找用户。
在第一种情况下,参数 user_name
使用字符串插值插入到 SQL 片段中。该参数由用户提供,未经清理。攻击者可以使用此方法构建原本不应在此执行的 SQL 查询。
第二种情况使用字符串连接,与第一种情况一样容易受到攻击。
在第三种情况下,名称被传递到哈希中。 ActiveRecord
将构建一个参数化的 SQL 查询,该查询不会受到 SQL 注入攻击的影响。
class UserController < ActionController::Base
def text_bio
# BAD -- Using string interpolation
user = User.find_by "name = '#{params[:user_name]}'"
# BAD -- Using string concatenation
find_str = "name = '" + params[:user_name] + "'"
user = User.find_by(find_str)
# GOOD -- Using a hash to parameterize arguments
user = User.find_by name: params[:user_name]
render plain: user&.text_bio
end
end
参考资料¶
维基百科: SQL 注入.
OWASP: SQL 注入预防备忘单.
常见弱点枚举: CWE-89.