Skip to content

Commit 86b7536

Browse files
jadolgclaude
andauthored
Fix security issues: error leakage, missing headers, TLS version, auth error exposure (#215)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent ee1ff39 commit 86b7536

File tree

3 files changed

+19
-5
lines changed

3 files changed

+19
-5
lines changed

Caddyfile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
dockerimagesave.yourdomain.org {
22
reverse_proxy dockerimagesave:8080
33
header Access-Control-Allow-Methods "GET, OPTIONS"
4-
header Access-Control-Allow-Headers "*"
4+
header Access-Control-Allow-Headers "Content-Type, Accept, Range, Content-Disposition"
55
header Access-Control-Allow-Origin "*"
6+
header X-Content-Type-Options "nosniff"
7+
header X-Frame-Options "DENY"
8+
header Referrer-Policy "strict-origin-when-cross-origin"
69
log {
710
output file /logs/access.log {
811
roll_size 1gb

registry.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"crypto/tls"
45
"encoding/base64"
56
"encoding/json"
67
"fmt"
@@ -10,6 +11,8 @@ import (
1011
"os"
1112
"strings"
1213
"time"
14+
15+
log "github.com/sirupsen/logrus"
1316
)
1417

1518
const bearerPrefix = "Bearer "
@@ -127,7 +130,14 @@ func ParseImageReference(ref string) ImageReference {
127130
// NewRegistryClient creates a new registry client
128131
func NewRegistryClient() *RegistryClient {
129132
return &RegistryClient{
130-
httpClient: &http.Client{Timeout: 300 * time.Second},
133+
httpClient: &http.Client{
134+
Timeout: 300 * time.Second,
135+
Transport: &http.Transport{
136+
TLSClientConfig: &tls.Config{
137+
MinVersion: tls.VersionTLS12,
138+
},
139+
},
140+
},
131141
}
132142
}
133143

@@ -217,7 +227,8 @@ func (c *RegistryClient) fetchToken(realm, service, scope string, creds Registry
217227

218228
if resp.StatusCode != http.StatusOK {
219229
body, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))
220-
return "", fmt.Errorf("authentication failed: %d - %s", resp.StatusCode, string(body))
230+
log.WithField("response_body", string(body)).WithField("status_code", resp.StatusCode).Debug("Authentication request failed")
231+
return "", fmt.Errorf("authentication failed with status %d", resp.StatusCode)
221232
}
222233

223234
var tokenResp struct {

server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func (s *Server) imageHandler(w http.ResponseWriter, r *http.Request) {
153153
"image": imageName,
154154
}).WithError(err).Error("Failed to download image")
155155
errorsTotalMetric.Inc()
156-
writeJSONError(w, fmt.Sprintf("failed to download image: %v", err), http.StatusInternalServerError)
156+
writeJSONError(w, "failed to download image", http.StatusInternalServerError)
157157
return
158158
}
159159
imagePath := result.(string)
@@ -171,7 +171,7 @@ func (s *Server) platformsHandler(w http.ResponseWriter, r *http.Request) {
171171
platforms, err := GetImagePlatforms(imageName)
172172
if err != nil {
173173
log.WithField("image", imageName).WithError(err).Error("Failed to get platforms")
174-
writeJSONError(w, fmt.Sprintf("failed to get platforms: %v", err), http.StatusInternalServerError)
174+
writeJSONError(w, "failed to get platforms", http.StatusInternalServerError)
175175
return
176176
}
177177
if platforms == nil {

0 commit comments

Comments
 (0)