Files
2026-06-25 02:33:30 +08:00

84 lines
2.3 KiB
Go

package service
import (
"fmt"
"regexp"
"strconv"
"strings"
)
const (
ffmpegPixelSmashCVE = "CVE-2026-8461"
ffmpegPixelSmashFixedVersion = "8.1.2"
)
var ffmpegVersionRE = regexp.MustCompile(`(?i)\bff(?:mpeg|probe)\s+version\s+([0-9]+)\.([0-9]+)(?:\.([0-9]+))?`)
type FFmpegSecurityStatus struct {
Status string `json:"status"`
CVE string `json:"cve,omitempty"`
FixedVersion string `json:"fixed_version,omitempty"`
Message string `json:"message,omitempty"`
ParsedVersion string `json:"parsed_version,omitempty"`
}
func EvaluateFFmpegSecurity(versionLine string) FFmpegSecurityStatus {
major, minor, patch, parsed := parseFFmpegVersionLine(versionLine)
if !parsed {
return FFmpegSecurityStatus{
Status: "unknown",
CVE: ffmpegPixelSmashCVE,
FixedVersion: ffmpegPixelSmashFixedVersion,
Message: "无法识别 FFmpeg 版本;请确认 ffmpeg/ffprobe 已更新到 8.1.2 或更高版本",
}
}
status := FFmpegSecurityStatus{
Status: "ok",
CVE: ffmpegPixelSmashCVE,
FixedVersion: ffmpegPixelSmashFixedVersion,
ParsedVersion: fmt.Sprintf("%d.%d.%d", major, minor, patch),
}
if major == 8 && ffmpegVersionLess(major, minor, patch, 8, 1, 2) {
status.Status = "vulnerable"
status.Message = "当前 FFmpeg 8.x 版本低于 8.1.2,可能受 PixelSmash 解码漏洞影响;请升级 ffmpeg/ffprobe"
return status
}
if major < 8 {
status.Status = "review"
status.Message = "当前 FFmpeg 主版本低于 8;请按发行版安全公告确认是否已回补 PixelSmash 修复"
}
return status
}
func ffmpegVersionLess(major, minor, patch, fixedMajor, fixedMinor, fixedPatch int) bool {
if major != fixedMajor {
return major < fixedMajor
}
if minor != fixedMinor {
return minor < fixedMinor
}
return patch < fixedPatch
}
func parseFFmpegVersionLine(versionLine string) (major, minor, patch int, ok bool) {
match := ffmpegVersionRE.FindStringSubmatch(strings.TrimSpace(versionLine))
if len(match) < 3 {
return 0, 0, 0, false
}
major, err := strconv.Atoi(match[1])
if err != nil {
return 0, 0, 0, false
}
minor, err = strconv.Atoi(match[2])
if err != nil {
return 0, 0, 0, false
}
if len(match) > 3 && match[3] != "" {
patch, err = strconv.Atoi(match[3])
if err != nil {
return 0, 0, 0, false
}
}
return major, minor, patch, true
}