Skip to content

Commit a3fc32b

Browse files
committed
security: harden the narinfo route pattern
The narinfo hash was updated in #840 to reflect the upstream definition in NixOS/nix#15004 and so the server should only allow narinfo requests that match this pattern.
1 parent abf888a commit a3fc32b

File tree

2 files changed

+4
-15
lines changed

2 files changed

+4
-15
lines changed

pkg/server/security_test.go

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,6 @@ L:
9797
expectedStatus: http.StatusNotFound, // Not found upstream, but reached it
9898
shouldReachUpstream: true,
9999
},
100-
{
101-
name: "Valid 52-char narinfo hash",
102-
method: http.MethodGet,
103-
path: "/1lid9xrpirkzcpqsxfq02qwiq0yd70chfl860wzsqd1739ih0nri.narinfo",
104-
expectedStatus: http.StatusNotFound,
105-
shouldReachUpstream: true,
106-
},
107100
{
108101
name: "Invalid hash length (31 chars)",
109102
method: http.MethodGet,
@@ -121,8 +114,8 @@ L:
121114
{
122115
name: "Path traversal attempt (alphanumeric but malicious)",
123116
method: http.MethodGet,
124-
path: "/abcdefghijklmnopqrstuvwxyz0123456789.narinfo", // 44 chars
125-
expectedStatus: http.StatusBadRequest, // Rejected by helper.IsValidHash
117+
path: "/aeou456789abcdfghijklmnpqrsvwxy.narinfo", // contains all 4 chars not allowed aeou
118+
expectedStatus: http.StatusNotFound,
126119
shouldReachUpstream: false,
127120
},
128121
{

pkg/server/server.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ import (
2929
"github.com/kalbasit/ncps/pkg/cache/upstream"
3030
"github.com/kalbasit/ncps/pkg/helper"
3131
"github.com/kalbasit/ncps/pkg/nar"
32+
"github.com/kalbasit/ncps/pkg/narinfo"
3233
"github.com/kalbasit/ncps/pkg/storage"
3334
)
3435

3536
const (
3637
routeIndex = "/"
3738
routeNar = "/nar/{hash:[a-z0-9]{32,52}}.nar"
3839
routeNarCompression = "/nar/{hash:[a-z0-9]{32,52}}.nar.{compression:*}"
39-
routeNarInfo = "/{hash:[a-z0-9]{32,52}}.narinfo"
40+
routeNarInfo = "/{hash:" + narinfo.HashPattern + "}.narinfo"
4041
routeCacheInfo = "/nix-cache-info"
4142
routeCachePublicKey = "/pubkey"
4243

@@ -305,11 +306,6 @@ func (s *Server) getNixCachePublicKey(w http.ResponseWriter, r *http.Request) {
305306
func (s *Server) getNarInfo(withBody bool) http.HandlerFunc {
306307
return func(w http.ResponseWriter, r *http.Request) {
307308
hash := chi.URLParam(r, "hash")
308-
if !helper.IsValidHash(hash) {
309-
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
310-
311-
return
312-
}
313309

314310
ctx, span := tracer.Start(
315311
r.Context(),

0 commit comments

Comments
 (0)