Files
OpenList/pkg
PIKACHUIM 6d17d37ee7 fix(seed): harden seed source fetching and unify rapid-upload hash rules
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.
2026-09-12 22:22:12 +08:00
..
2022-09-02 21:36:47 +08:00
2022-09-14 15:13:02 +08:00
2022-12-05 16:07:36 +08:00