Skip to content

Commit bd0a81f

Browse files
authored
fix: fixes missed cases to validate user scope when downloading, streaming and actions (#3460)
1 parent f2e56f7 commit bd0a81f

File tree

4 files changed

+82
-3
lines changed

4 files changed

+82
-3
lines changed

assets/auto-imports.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,21 @@ declare global {
369369
// @ts-ignore
370370
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
371371
import('vue')
372+
// @ts-ignore
373+
export type { DrawerWidth } from './composable/drawer'
374+
import('./composable/drawer')
375+
// @ts-ignore
376+
export type { LogStreamSource } from './composable/eventStreams'
377+
import('./composable/eventStreams')
378+
// @ts-ignore
379+
export type { Config, Profile } from './stores/config'
380+
import('./stores/config')
381+
// @ts-ignore
382+
export type { Host } from './stores/hosts'
383+
import('./stores/hosts')
384+
// @ts-ignore
385+
export type { Settings } from './stores/settings'
386+
import('./stores/settings')
372387
}
373388

374389
// for vue template auto import

internal/web/actions.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@ func (h *handler) containerActions(w http.ResponseWriter, r *http.Request) {
1414
action := chi.URLParam(r, "action")
1515
id := chi.URLParam(r, "id")
1616

17+
validIdMap, err := h.validContainerIDsForHost(r, hostKey(r))
18+
if err != nil {
19+
http.Error(w, err.Error(), http.StatusInternalServerError)
20+
return
21+
}
22+
23+
if _, ok := validIdMap[id]; !ok {
24+
http.Error(w, "container not found", http.StatusUnauthorized)
25+
return
26+
}
27+
1728
containerService, err := h.multiHostService.FindContainer(hostKey(r), id)
1829
if err != nil {
1930
log.Error().Err(err).Msg("error while trying to find container")

internal/web/actions_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func Test_handler_containerActions_unknown_container(t *testing.T) {
7676

7777
rr := httptest.NewRecorder()
7878
handler.ServeHTTP(rr, req)
79-
assert.Equal(t, 404, rr.Code)
79+
assert.Equal(t, 401, rr.Code)
8080
}
8181

8282
func Test_handler_containerActions_start(t *testing.T) {

internal/web/logs.go

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,46 @@ import (
2626
"github.com/docker/docker/pkg/stdcopy"
2727
"github.com/dustin/go-humanize"
2828
"github.com/go-chi/chi/v5"
29+
"github.com/samber/lo"
2930

3031
"github.com/rs/zerolog/log"
3132
)
3233

34+
func (h *handler) validContainerIDsForHost(r *http.Request, host string) (map[string]docker.Container, error) {
35+
usersFilter := h.config.Filter
36+
if h.config.Authorization.Provider != NONE {
37+
user := auth.UserFromContext(r.Context())
38+
if user.ContainerFilter.Exists() {
39+
usersFilter = user.ContainerFilter
40+
}
41+
}
42+
43+
validContainers, err := h.multiHostService.ListContainersForHost(host, usersFilter)
44+
if err != nil {
45+
return nil, err
46+
}
47+
48+
validIdMap := lo.KeyBy(validContainers, func(item docker.Container) string {
49+
return item.ID
50+
})
51+
52+
return validIdMap, nil
53+
}
54+
3355
func (h *handler) downloadLogs(w http.ResponseWriter, r *http.Request) {
3456
id := chi.URLParam(r, "id")
57+
58+
validIdMap, err := h.validContainerIDsForHost(r, hostKey(r))
59+
if err != nil {
60+
http.Error(w, err.Error(), http.StatusInternalServerError)
61+
return
62+
}
63+
64+
if _, ok := validIdMap[id]; !ok {
65+
http.Error(w, "container not found", http.StatusUnauthorized)
66+
return
67+
}
68+
3569
containerService, err := h.multiHostService.FindContainer(hostKey(r), id)
3670
if err != nil {
3771
http.Error(w, err.Error(), http.StatusBadRequest)
@@ -103,6 +137,17 @@ func (h *handler) fetchLogsBetweenDates(w http.ResponseWriter, r *http.Request)
103137
return
104138
}
105139

140+
validIdMap, err := h.validContainerIDsForHost(r, hostKey(r))
141+
if err != nil {
142+
http.Error(w, err.Error(), http.StatusInternalServerError)
143+
return
144+
}
145+
146+
if _, ok := validIdMap[id]; !ok {
147+
http.Error(w, "container not found", http.StatusUnauthorized)
148+
return
149+
}
150+
106151
containerService, err := h.multiHostService.FindContainer(hostKey(r), id)
107152
if err != nil {
108153
http.Error(w, err.Error(), http.StatusNotFound)
@@ -420,8 +465,16 @@ loop:
420465
}
421466
sseWriter.Message(logEvent)
422467
case container := <-newContainers:
423-
events <- &docker.ContainerEvent{ActorID: container.ID, Name: "container-started", Host: container.Host}
424-
go streamLogs(container)
468+
validIdMap, err := h.validContainerIDsForHost(r, container.Host)
469+
if err != nil {
470+
log.Error().Err(err).Msg("error fetching valid container IDs")
471+
continue
472+
}
473+
474+
if _, ok := validIdMap[container.ID]; ok {
475+
events <- &docker.ContainerEvent{ActorID: container.ID, Name: "container-started", Host: container.Host}
476+
go streamLogs(container)
477+
}
425478

426479
case event := <-events:
427480
log.Debug().Str("event", event.Name).Str("container", event.ActorID).Msg("received event")

0 commit comments

Comments
 (0)