mirror of
https://github.com/navidrome/navidrome.git
synced 2026-04-28 03:19:38 +00:00
fix(server): clear server-managed fields in savePlaylist to prevent injection via REST API
Some checks are pending
Pipeline: Test, Lint, Build / Get version info (push) Waiting to run
Pipeline: Test, Lint, Build / Lint Go code (push) Waiting to run
Pipeline: Test, Lint, Build / Test Go code (push) Waiting to run
Pipeline: Test, Lint, Build / Test JS code (push) Waiting to run
Pipeline: Test, Lint, Build / Lint i18n files (push) Waiting to run
Pipeline: Test, Lint, Build / Check Docker configuration (push) Waiting to run
Pipeline: Test, Lint, Build / Build (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-1 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-2 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-3 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-4 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-5 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-6 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Upload Linux PKG (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-7 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-8 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-9 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-10 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Push to GHCR (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Push to Docker Hub (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Cleanup digest artifacts (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build Windows installers (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Package/Release (push) Blocked by required conditions
Some checks are pending
Pipeline: Test, Lint, Build / Get version info (push) Waiting to run
Pipeline: Test, Lint, Build / Lint Go code (push) Waiting to run
Pipeline: Test, Lint, Build / Test Go code (push) Waiting to run
Pipeline: Test, Lint, Build / Test JS code (push) Waiting to run
Pipeline: Test, Lint, Build / Lint i18n files (push) Waiting to run
Pipeline: Test, Lint, Build / Check Docker configuration (push) Waiting to run
Pipeline: Test, Lint, Build / Build (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-1 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-2 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-3 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-4 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-5 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-6 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Upload Linux PKG (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-7 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-8 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-9 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build-10 (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Push to GHCR (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Push to Docker Hub (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Cleanup digest artifacts (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Build Windows installers (push) Blocked by required conditions
Pipeline: Test, Lint, Build / Package/Release (push) Blocked by required conditions
Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
parent
d2db41691e
commit
f102036dc6
2 changed files with 41 additions and 1 deletions
|
|
@ -58,10 +58,16 @@ func (s *playlists) TracksRepository(ctx context.Context, playlistId string, ref
|
|||
}
|
||||
|
||||
// savePlaylist creates a new playlist, assigning the owner from context.
|
||||
// Only Name, Comment, Public, and Rules are user-settable via the REST API.
|
||||
func (s *playlists) savePlaylist(ctx context.Context, pls *model.Playlist) (string, error) {
|
||||
usr, _ := request.UserFrom(ctx)
|
||||
pls.OwnerID = usr.ID
|
||||
pls.ID = "" // Force new creation
|
||||
pls.ID = "" // Force new creation
|
||||
pls.Path = "" // Server-managed (M3U file path)
|
||||
pls.Sync = false // Server-managed (M3U sync flag)
|
||||
pls.UploadedImage = "" // Managed by image upload endpoint
|
||||
pls.ExternalImageURL = "" // Managed by M3U import / plugins only
|
||||
pls.EvaluatedAt = nil // Server-managed
|
||||
err := s.ds.Playlist(ctx).Put(pls)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ package playlists_test
|
|||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/deluan/rest"
|
||||
"github.com/navidrome/navidrome/core/playlists"
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/model/criteria"
|
||||
"github.com/navidrome/navidrome/model/request"
|
||||
"github.com/navidrome/navidrome/tests"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
|
|
@ -56,6 +58,38 @@ var _ = Describe("REST Adapter", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(pls.ID).ToNot(Equal("should-be-cleared"))
|
||||
})
|
||||
|
||||
It("clears server-managed fields to prevent injection via REST API", func() {
|
||||
ctx = request.WithUser(ctx, model.User{ID: "user-1", IsAdmin: false})
|
||||
repo = ps.NewRepository(ctx).(rest.Persistable)
|
||||
now := time.Now()
|
||||
pls := &model.Playlist{
|
||||
Name: "Legit Playlist",
|
||||
Comment: "A comment",
|
||||
Public: true,
|
||||
Rules: &criteria.Criteria{Expression: criteria.Contains{"title": "test"}},
|
||||
Path: "/some/path/playlist.m3u",
|
||||
Sync: true,
|
||||
UploadedImage: "injected-image-path",
|
||||
ExternalImageURL: "http://evil.example.com/ssrf",
|
||||
EvaluatedAt: &now,
|
||||
}
|
||||
_, err := repo.Save(pls)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
saved := mockPlsRepo.Last
|
||||
// User-settable fields are preserved
|
||||
Expect(saved.Name).To(Equal("Legit Playlist"))
|
||||
Expect(saved.Comment).To(Equal("A comment"))
|
||||
Expect(saved.Public).To(BeTrue())
|
||||
Expect(saved.Rules).ToNot(BeNil())
|
||||
// Server-managed fields are cleared
|
||||
Expect(saved.Path).To(BeEmpty())
|
||||
Expect(saved.Sync).To(BeFalse())
|
||||
Expect(saved.UploadedImage).To(BeEmpty())
|
||||
Expect(saved.ExternalImageURL).To(BeEmpty())
|
||||
Expect(saved.EvaluatedAt).To(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("Update", func() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue