CodeQL 文档

服务器端请求伪造

ID: java/ssrf
Kind: path-problem
Security severity: 9.1
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-918
Query suites:
   - java-code-scanning.qls
   - java-security-extended.qls
   - java-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

在没有验证输入的情况下将用户输入直接合并到 HTTP 请求中会导致服务器端请求伪造 (SSRF) 攻击。在这些攻击中,服务器可能会被欺骗以发出请求并与攻击者控制的服务器进行交互。

建议

为了防范 SSRF 攻击,您应该避免将用户提供的输入直接放入请求 URL 中。相反,在服务器上维护一个已授权 URL 列表;然后根据提供的输入从该列表中进行选择。或者,确保从用户输入构建的请求仅限于特定主机或更严格的 URL 前缀。

示例

以下示例显示了 HTTP 请求参数被直接用于形成新请求,而没有验证输入,这会导致 SSRF 攻击。它还显示了如何通过将用户输入与已知固定字符串进行验证来解决问题。

import java.net.http.HttpClient;

public class SSRF extends HttpServlet {
	private static final String VALID_URI = "http://lgtm.com";
	private HttpClient client = HttpClient.newHttpClient();

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
		URI uri = new URI(request.getParameter("uri"));
		// BAD: a request parameter is incorporated without validation into a Http request
		HttpRequest r = HttpRequest.newBuilder(uri).build();
		client.send(r, null);

		// GOOD: the request parameter is validated against a known fixed string
		if (VALID_URI.equals(request.getParameter("uri"))) {
			HttpRequest r2 = HttpRequest.newBuilder(uri).build();
			client.send(r2, null);
		}
	}
}

参考资料

  • ©GitHub, Inc.
  • 条款
  • 隐私