Outbound HTTP client layout: strict protections are not available as an *http.Client
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 15/100
- Loại issue
- Tái cấu trúc
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- go
- Lĩnh vực
- networking, security
Hướng nghiên cứu
Start with StrictHTTPClient.Do in http/client and SafeHttpTransport below it, then the adapter in jsonld/ldutils.go (#4617). The design also touches the raw clients in pki/validator.go:104 and core/http_client.go:131. The proposal is a design for a per-hop RoundTripper and a new NewHTTPClient constructor, with open questions on otelhttp ordering, so settle the design with maintainers before writing code. Done means the proposed constructor exists and jsonld uses it.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Problem
All strict-mode protections for outbound HTTP live on http/client.StrictHTTPClient, which applies them per request in Do: the public-URL check (core.ParsePublicURLAllowIP), the User-Agent header, and the 1 MiB response body limit. The timeout and redirect policy sit on the *http.Client inside it, and the SSRF dial guard and TLS 1.2 floor sit on SafeHttpTransport below that. StrictHTTPClient is not an *http.Client and does not expose the one it wraps.
That is fine for code we write ourselves (auth, discovery, vcr, vdr/didweb all call client.New* and use Do). It is a problem for every library or generated client that insists on a *http.Client:
jsonld/ldutils.go: json-gold'sDefaultDocumentLoadertakes a*http.Client. Until #4617 it gotnil, meaninghttp.DefaultClient: no timeout, no SSRF guard, no body limit. #4617 fixes it by wrapping the wholeStrictHTTPClientas anhttp.RoundTripperinside a second, outerhttp.Client. This works, but the outer client'sTimeoutandCheckRedirectare dead config, and the adapter bends theRoundTrippercontract (it follows redirects and buffers the body insideRoundTrip).pki/validator.go:104: CRL fetching builds a rawhttp.Clientonhttp.DefaultTransport. CRL distribution points come from certificates we did not issue, so this is an outbound fetch to URLs we do not control, with no SSRF guard, no body limit and no strict-mode URL check. Only the timeout is set.crypto/storage/external/client.go:96: rawhttp.Clientonhttp.DefaultTransport. This one targets an operator-configured internal address, so the strict client would be wrong for it, but it also means there is no single place that says "this is the client for trusted internal targets".core/http_client.go:131(CreateHTTPInternalClient): rawhttp.Client, used for CLI-to-node calls. Same category as the previous one.
The comment on SafeHttpTransport already warns not to build raw clients on it, but the package offers no alternative when a *http.Client is required, so people either bypass the protections or write an adapter like the one in #4617.
Proposal
Move the per-request protections from StrictHTTPClient.Do into an http.RoundTripper in http/client, so they apply per hop and a real *http.Client can be built on it:
- A
strictTransportthat wrapsSafeHttpTransport(or the caching or custom-TLS variant) and does, per hop: the public-URL check, set User-Agent, and limit the response body. Redirect targets are then checked by the transport on every hop as well, which makes the currentcheckRedirectre-check redundant but harmless. client.New*keep returning*StrictHTTPClientso the existing call sites do not change.StrictHTTPClient.Dobecomes a thin call to the inner client.- A new constructor, for example
client.NewHTTPClient(timeout, options...) *http.Client, that returns the inner client directly for libraries that need one. Timeout andCheckRedirectare set on that client, so there is one place to configure them. jsonlddrops its private adapter and usesNewHTTPClient.pkiswitches CRL fetching to it (with a response size option sized for CRLs; some are several MB).- Document in
http/clientwhich constructor to use for which target class: public internet (strict), operator-configured internal services (no SSRF guard, but still timeout and body limit), and CLI-to-node.
Response limit semantics
The response limit is a buffer-and-error, not a streaming cap: Do reads up to limit+1 bytes into memory and fails the request on overflow. It never truncates, because a silently shortened body (DER, a JSON-LD context) can parse into something smaller than intended. The transport must keep that: RoundTrip reads the body, errors on overflow, and returns an in-memory body on success. http.Client.Do then surfaces the error exactly as StrictHTTPClient.Do does today, so callers never see a response object on overflow.
Two consequences: http.Client wraps transport errors in *url.Error, so tests comparing error strings change (errors.Is/errors.As keep working), and redirect hops are limited as well, which is stricter than today. A lazy limiting body would allow streaming but moves the error from Do to the first read, which is a behaviour change for every existing caller, so it is out of scope here.
Non-goals
- Changing behaviour for the existing
client.New*callers. - Touching the generated OpenAPI clients; they take an
HttpRequestDoerinterface and already acceptStrictHTTPClient. - Unifying the two internal-target clients (
crypto/storage/external,core.CreateHTTPInternalClient); documenting which constructor they should use is enough.
Open questions
- Tracing:
getTransportwraps inotelhttptoday. The strict transport should sit inside the otel wrapper so a rejected URL still produces a span, or outside so it does not; decide which.
Related
- #4617 (JSON-LD remote context timeout) introduced the adapter this issue wants to retire.
- #4615 (the underlying bug).
- Ngôn ngữ chính
- Go
- Star
- 29
- Fork
- 24
- Merge trung bình
- 2 ngày 18 giờ
- Pull request đã merge (30 ngày)
- 45
Chuẩn bị môi trường
- Có Dockerfile hoặc tệp Docker Compose
- Không có mẫu pull request
- Không có hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của nuts-foundation/nuts-node
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
nuts-foundation/nuts-node#4450 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug discuss
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
nuts-foundation/nuts-node#4436 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
auth bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
nuts-foundation/nuts-node#4435 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
nuts-foundation/nuts-node#4321 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
nuts-foundation/nuts-node#4230 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của nuts-foundation/nuts-node
Issue tương tự
-
[BUG] deploy.restart_policy without condition drops the restart policyCó thể đã có người làm @akshat-lakhera đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
docker/compose#14383 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
AvengeMedia/dank-greeter#39 · 1 bình luận ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
dokku/dokku-datastore#367 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug]: ap gateway image build cannot find local policies on WindowsCó thể đã có người làm @Jayzilva đã nhận hôm nay. Đang mởAspect/Configuration Severity/Major
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 83/100
wso2/api-platform#3912 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 2 ngày