feat(ssrf): implement SSRF protection in HTTP clients and validation functions

This commit is contained in:
CaIon
2026-07-06 14:52:01 +08:00
parent 1e11dfcfb5
commit df087b022d
10 changed files with 799 additions and 97 deletions
+20 -9
View File
@@ -68,11 +68,16 @@ func VideoProxy(c *gin.Context) {
var videoURL string
proxy := channel.GetSetting().Proxy
client, err := service.GetHttpClientWithProxy(proxy)
if err != nil {
logger.LogError(c.Request.Context(), fmt.Sprintf("Failed to create proxy client for task %s: %s", taskID, err.Error()))
videoProxyError(c, http.StatusInternalServerError, "server_error", "Failed to create proxy client")
return
client := service.GetSSRFProtectedHTTPClient()
if proxy != "" {
// 渠道代理路径的连接由代理侧建立,无法做拨号时逐 IP 校验,
// 因此后面对 videoURL 保留请求前的一次性 SSRF 校验。
client, err = service.GetHttpClientWithProxy(proxy)
if err != nil {
logger.LogError(c.Request.Context(), fmt.Sprintf("Failed to create proxy client for task %s: %s", taskID, err.Error()))
videoProxyError(c, http.StatusInternalServerError, "server_error", "Failed to create proxy client")
return
}
}
ctx, cancel := context.WithTimeout(c.Request.Context(), 60*time.Second)
@@ -129,10 +134,16 @@ func VideoProxy(c *gin.Context) {
return
}
fetchSetting := system_setting.GetFetchSetting()
if err := common.ValidateURLWithFetchSetting(videoURL, fetchSetting.EnableSSRFProtection, fetchSetting.AllowPrivateIp, fetchSetting.DomainFilterMode, fetchSetting.IpFilterMode, fetchSetting.DomainList, fetchSetting.IpList, fetchSetting.AllowedPorts, fetchSetting.ApplyIPFilterForDomain); err != nil {
logger.LogError(c.Request.Context(), fmt.Sprintf("Video URL blocked for task %s: %v", taskID, err))
videoProxyError(c, http.StatusForbidden, "server_error", fmt.Sprintf("request blocked: %v", err))
var validateErr error
if proxy == "" {
validateErr = service.ValidateSSRFProtectedFetchURL(videoURL)
} else {
fetchSetting := system_setting.GetFetchSetting()
validateErr = common.ValidateURLWithFetchSetting(videoURL, fetchSetting.EnableSSRFProtection, fetchSetting.AllowPrivateIp, fetchSetting.DomainFilterMode, fetchSetting.IpFilterMode, fetchSetting.DomainList, fetchSetting.IpList, fetchSetting.AllowedPorts, fetchSetting.ApplyIPFilterForDomain)
}
if validateErr != nil {
logger.LogError(c.Request.Context(), fmt.Sprintf("Video URL blocked for task %s: %v", taskID, validateErr))
videoProxyError(c, http.StatusForbidden, "server_error", fmt.Sprintf("request blocked: %v", validateErr))
return
}