summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGab Virebent <gabriel1@virebent.art>2026-07-03 15:51:07 +0200
committerGab Virebent <gabriel1@virebent.art>2026-07-03 15:51:07 +0200
commit4fd6b4fefa7243f68fae7e24df3da46ee1a8e356 (patch)
tree45d41d62c2b5ddb0a4a85e4a429597c8d31d8d89
parent25fb52dc5c587acca2f4457d5c6f7b8032b7829c (diff)
downloadnymdrop-4fd6b4fefa7243f68fae7e24df3da46ee1a8e356.tar.gz
nymdrop-4fd6b4fefa7243f68fae7e24df3da46ee1a8e356.tar.xz
nymdrop-4fd6b4fefa7243f68fae7e24df3da46ee1a8e356.zip
Fix payload cap: double base64 inflation broke files near the old 10MB limit
The old 10MB cap was checked against the wire body, but two base64 layers sit between the raw file and that body: crypto.js base64-encodes the file before AEAD encryption, then nym.Client.Send base64-encodes the ciphertext again to embed it in the JSON sent to the local nym-client over its control WebSocket. A file at exactly the old cap produced a wire body just over the limit after the first layer, and would have blown nym-client's own hardcoded 16MB WebSocket message limit after the second, surfacing as an opaque 500. Lower the wire-body cap to 11MB, which keeps the second base64 layer with real margin under nym-client's 16MB ceiling. Effective safe raw file size is now roughly 8MB, not 10MB. Reported by Ch1ffr3punk on nym.forum, reproduced with an exact 10MB file.
-rw-r--r--internal/handler/submit.go2
-rw-r--r--internal/relay/relay.go13
2 files changed, 13 insertions, 2 deletions
diff --git a/internal/handler/submit.go b/internal/handler/submit.go
index 2822488..712d6a5 100644
--- a/internal/handler/submit.go
+++ b/internal/handler/submit.go
@@ -29,7 +29,7 @@ func (s *Submit) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
- r.Body = http.MaxBytesReader(w, r.Body, 10*1024*1024)
+ r.Body = http.MaxBytesReader(w, r.Body, 11*1024*1024) // wire size, see relay.maxPayloadBytes
defer r.Body.Close()
if err := s.relay.Forward(r.Body); err != nil {
diff --git a/internal/relay/relay.go b/internal/relay/relay.go
index 9cd0366..9a17fab 100644
--- a/internal/relay/relay.go
+++ b/internal/relay/relay.go
@@ -8,7 +8,18 @@ import (
"nymdrop/internal/nym"
)
-const maxPayloadBytes = 10 * 1024 * 1024 // 10 MB
+// Two base64 layers stack between the raw file and the wire: the client
+// base64-encodes the file into the plaintext before encrypting (see
+// static/crypto.js, ~4/3 inflation), then nym.Client.Send base64-encodes
+// the whole ciphertext again to embed it in the JSON message sent to the
+// local nym-client over its control WebSocket (~4/3 again). The combined
+// ~1.78x inflation is bounded above by nym-client's own hardcoded 16MB
+// WebSocket message limit, not by anything in this codebase, so this
+// buffer (and the nginx/http-layer cap) must stay well under 16MB / 1.78
+// once the second layer is applied. 11MB here keeps the second-layer
+// base64 (~14.7MB) with real margin below the 16MB nym-client ceiling,
+// which works out to a safe raw file size of roughly 8MB, not 10MB.
+const maxPayloadBytes = 11 * 1024 * 1024 // 11 MB wire (first base64 layer only)
// Relay receives ciphertext and forwards it through Nym. Nothing is written to disk.
type Relay struct {