mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2026-10-10 04:53:09 +08:00
6d17d37ee7
Security fixes for the transfer-seed feature reviewed on feat/advanced-transfer-seeds. SSRF via redirect (torrent.go): - Source validation only pinned the first hop while http.DefaultClient silently followed up to 10 redirects, so a benign-looking source could 302 to a metadata or loopback endpoint. Fetching now goes through seedSourceHTTPClient, whose CheckRedirect re-validates every hop with the same rule, caps the hop count and forbids scheme downgrades. - Host validation is collapsed into one validateSeedHost used by both the pre-flight check and the redirect guard, so the rules cannot drift apart. - Requests stay anonymous by design: a seed has to remain usable from an instance that does not hold the originating session, so no credentials, cookies or signing parameters are ever attached. Seed content fetching (torrent.go): - Propagate the request context instead of context.Background(), so cancellation actually stops the download. - Stream the body through an io.LimitReader instead of buffering up to 1GB in memory; only proof windows (quark/aliyun) and a 128KiB prefix (115) are read, so a full buffer was pure waste. Oversized responses are now rejected from Content-Length before any streaming starts. Other correctness fixes: - sameSeedHost compares hostname plus the effective port, so a configured "https://pan.example.com" and an embedded "...:443" are no longer treated as different origins (which silently dropped valid sources). - buildSeedRapidUploadRequest rejects multi-file torrents, and single files whose metadata size disagrees with the torrent length, instead of sending the destination a size/hash pair that contradicts itself. Both call sites now handle the nil result instead of dereferencing it. - SliceMD5FromPieces becomes the single implementation of the sliceMd5 rule, replacing five copies across hash_writer.go, torrent.go, generate.go, 189/torrent.go and 189pc/torrent.go. Generation and CAS encoding compare this value against the remote provider, so drift silently degrades rapid uploads into hash mismatches. - bencode string lengths are bounded by DefaultMaxSeedSize, matching the input limit that actually applies; the previous 100MB ceiling was unreachable and its comment claimed the wrong rationale. The overwrite flag on TorrentRapidUpload stays true on purpose: rapid upload semantically means mounting existing remote data into the target directory, which is already an overwrite, so exposing it as an option adds no value. Tests: - pkg/torrent/seed_security_test.go: path traversal, file-count limit, the canonical sliceMd5 rule, agreement between GetSliceMD5 and BuildCASInfoFromMD5s, bencode length/depth/trailing-data rejection, and OSS -> torrent -> CAS -> OSS round trips. - server/handles/torrent_seed_test.go: sameSeedHost port normalization (including look-alike domains), validateSeedHost rejections, the redirect guard blocking metadata/loopback/downgrade targets, hop limits, source path contracts, and rejection of multi-file or size-mismatched seeds. go build ./... passes; go test ./pkg/torrent/... and go test ./server/handles/... pass.