服务器端请求伪造¶
ID: rb/request-forgery
Kind: path-problem
Security severity: 9.1
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-918
Query suites:
- ruby-code-scanning.qls
- ruby-security-extended.qls
- ruby-security-and-quality.qls
直接将用户输入合并到 HTTP 请求中而不对其进行验证,可能会导致服务器端请求伪造 (SSRF) 攻击。在这些攻击中,请求可能会被更改、指向不同的服务器或通过不同的协议发送。这可能允许攻击者获取敏感信息或执行具有提升权限的操作。
建议¶
为了防范 SSRF 攻击,您应该避免将用户提供的输入直接放入请求 URL 中。相反,应在服务器上维护一个已授权 URL 列表;然后根据提供的输入从该列表中进行选择。或者,确保从用户输入构建的请求仅限于特定主机或更严格的 URL 前缀。
示例¶
以下示例显示了一个 HTTP 请求参数被直接用于形成一个新的请求而没有验证输入,这会导致 SSRF 攻击。它还显示了如何通过将用户输入与已知固定字符串进行验证来解决此问题。
require "excon"
require "json"
class PostsController < ActionController::Base
def create
user = params[:user_id]
# BAD - user can control the entire URL of the request
users_service_domain = params[:users_service_domain]
response = Excon.post("#{users_service_domain}/logins", body: {user_id: user}).body
token = JSON.parse(response)["token"]
# GOOD - path is validated against a known fixed string
path = if params[:users_service_path] == "v1/users"
"v1/users"
else
"v2/users"
end
response = Excon.post("users-service/#{path}", body: {user_id: user}).body
token = JSON.parse(response)["token"]
@post = Post.create(params[:post].merge(user_token: token))
render @post
end
end
参考¶
常见漏洞枚举:CWE-918.