Authenticate blob reads before lookup, return 404 for missing content, and apply access checks to existing blobs. Add a regression for authenticated missing downloads.
- commit
- ee5b53dfaa40c7343483de0e7e48c97c51ef0856
- parent
- 8e028746d76883d0ed66942e1c609cfc14d3b102
- author
- Dami <dami.etoile@gmail.com>
| M | internal/ | 12 | +++++++----- |
| A | internal/ | 17 | +++++++++++++++++ |
@@ -215,16 +215,14 @@ func (s *Service) blob(w http.ResponseWriter, r *http.Request) {
215215 s.fail(w, http.StatusMethodNotAllowed, errors.New("method not allowed"))216216 return217217 }218+ var pubkey string218219 if s.config.CanRead != nil {219- pubkey, err := s.authorize(r, ActionGet)220+ var err error221+ pubkey, err = s.authorize(r, ActionGet)220222 if err != nil {221223 s.fail(w, http.StatusUnauthorized, err)222224 return223225 }224- if !s.config.CanRead(r.Context(), sha, []string{pubkey}) {225- s.fail(w, http.StatusForbidden, errors.New("restricted: read access denied"))226- return227- }228226 }229227 entry, err := s.lookup(r.Context(), sha)230228 if errors.Is(err, sql.ErrNoRows) {@@ -235,6 +233,10 @@ func (s *Service) blob(w http.ResponseWriter, r *http.Request) {
235233 s.fail(w, http.StatusInternalServerError, err)236234 return237235 }236+ if s.config.CanRead != nil && !s.config.CanRead(r.Context(), sha, []string{pubkey}) {237+ s.fail(w, http.StatusForbidden, errors.New("restricted: read access denied"))238+ return239+ }238240 if s.blocked(r.Context(), sha) {239241 s.fail(w, http.StatusForbidden, ErrBlocked)240242 return@@ -0,0 +1,17 @@
1+package daemon2+3+import (4+ "net/http"5+ "strings"6+ "testing"7+)8+9+func TestBlobGetMissingReturnsNotFoundAfterAuthentication(t *testing.T) {10+ _, tenant := testTenant(t)11+ missing := strings.Repeat("a", 64)12+13+ response := getArtifact(t, tenant, "/"+missing, testOwnerSecret)14+ if response.Code != http.StatusNotFound {15+ t.Fatalf("missing authenticated blob status = %d, want %d: %s", response.Code, http.StatusNotFound, response.Body.String())16+ }17+}