mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-04 04:26:38 +08:00
优化,排查项目问题
This commit is contained in:
@@ -3,6 +3,8 @@ package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
@@ -33,6 +35,21 @@ func dlnaCastHandler(svc *service.Container) gin.HandlerFunc {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
// SSRF 防护:control_url 必须命中本服务发现到的真实渲染设备,
|
||||
// 防止登录用户借 cast 接口向任意内网地址发起 POST。
|
||||
// 优先用 30s 缓存;未命中时强制重扫一次再校验(设备可能刚上线)。
|
||||
devices, err := svc.DLNA.Discover(c.Request.Context(), false)
|
||||
if err == nil && !dlnaControlURLKnown(devices, req.ControlURL) {
|
||||
devices, err = svc.DLNA.Discover(c.Request.Context(), true)
|
||||
}
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if !dlnaControlURLKnown(devices, req.ControlURL) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "unknown DLNA device: control_url must come from /api/dlna discovery"})
|
||||
return
|
||||
}
|
||||
if err := svc.DLNA.Cast(c.Request.Context(), req.ControlURL, req.MediaURL); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
@@ -40,3 +57,25 @@ func dlnaCastHandler(svc *service.Container) gin.HandlerFunc {
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
// dlnaControlURLKnown 判断 control_url 是否属于发现列表中的设备。
|
||||
// 按解析后的 host:port+path 精确比对,容忍大小写与尾斜杠差异。
|
||||
func dlnaControlURLKnown(devices []service.DLNADevice, controlURL string) bool {
|
||||
want, err := url.Parse(strings.TrimSpace(controlURL))
|
||||
if err != nil || want.Host == "" {
|
||||
return false
|
||||
}
|
||||
for _, dev := range devices {
|
||||
for _, candidate := range []string{dev.ControlURL, dev.Location} {
|
||||
u, err := url.Parse(strings.TrimSpace(candidate))
|
||||
if err != nil || u.Host == "" {
|
||||
continue
|
||||
}
|
||||
if strings.EqualFold(u.Host, want.Host) &&
|
||||
strings.EqualFold(strings.TrimRight(u.Path, "/"), strings.TrimRight(want.Path, "/")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user