harden lastfm playlist parsing and url validation

This commit is contained in:
2026-04-21 19:10:50 +02:00
parent c67be72869
commit ba97fe85fe
2 changed files with 54 additions and 2 deletions

View File

@@ -1640,6 +1640,9 @@ func parseLastFMArgs(args []string, defaultSource, defaultFallback string) (last
if opts.PlaylistURL == "" {
return lastFMOptions{}, fmt.Errorf("missing playlist url")
}
if !isValidLastFMPlaylistURL(opts.PlaylistURL) {
return lastFMOptions{}, fmt.Errorf("playlist url must be a last.fm url")
}
if !isAllowedSearchSource(opts.Source) {
return lastFMOptions{}, fmt.Errorf("%s %q", errLastFMInvalidSource, opts.Source)
}
@@ -1649,11 +1652,27 @@ func parseLastFMArgs(args []string, defaultSource, defaultFallback string) (last
return opts, nil
}
func isValidLastFMPlaylistURL(raw string) bool {
u, err := url.Parse(strings.TrimSpace(raw))
if err != nil || u == nil || u.Host == "" {
return false
}
s := strings.ToLower(strings.TrimSpace(u.Scheme))
if s != "http" && s != "https" {
return false
}
h := strings.ToLower(strings.TrimPrefix(strings.TrimSpace(u.Host), "www."))
return h == "last.fm" || strings.HasSuffix(h, ".last.fm")
}
func fetchLastFMPlaylist(ctx context.Context, verifySSL bool, playlistURL string) (string, []lastFMTrack, error) {
parsed, err := url.Parse(playlistURL)
if err != nil || parsed.Scheme == "" || parsed.Host == "" {
return "", nil, fmt.Errorf("invalid playlist url")
}
if !isValidLastFMPlaylistURL(playlistURL) {
return "", nil, fmt.Errorf("invalid playlist url")
}
client := netutil.NewHTTPClient(30*time.Second, verifySSL)
page1, err := fetchLastFMPlaylistPage(ctx, client, parsed, 1)
@@ -1711,7 +1730,7 @@ func fetchLastFMPlaylistViaMirror(ctx context.Context, verifySSL bool, playlistU
break
}
all = append(all, tracks...)
if !strings.Contains(body, "Show more") {
if !strings.Contains(strings.ToLower(body), "show more") {
break
}
}
@@ -1829,7 +1848,7 @@ func extractLastFMTracksFromMirrorMarkdown(md string) (string, []lastFMTrack) {
title = strings.TrimSpace(html.UnescapeString(m[1]))
}
}
if !strings.HasPrefix(line, "|") || !strings.Contains(line, "Play track") {
if !strings.HasPrefix(line, "|") || !strings.Contains(strings.ToLower(line), "play track") {
continue
}
cols := splitMarkdownTableRow(line)