Skip to content

Harden the receiver against a review of the Go and Python ports - #62

Merged
thomasdarimont merged 4 commits into
mainfrom
gh-61-fix-review-findings
Oct 29, 2026
Merged

thomasdarimont merged 4 commits into
mainfrom
gh-61-fix-review-findings

Conversation

@thomasdarimont

Copy link
Copy Markdown
Collaborator

A code review of the sibling libraries found weaknesses that the Java receiver shares. The URI policy took any host name starting with "127." for loopback and so allowed plain http for it; it now accepts only localhost and names under it, 127.0.0.0/8 and ::1 (also IPv4-mapped), the same rule as the Go library. The poll endpoint is held to that policy before the access token is sent to it, configured or taken from the stream, with a new SsfPoller.setUriPolicy. Response bodies read from the transmitter are bounded, 4 MiB by default, through JdkSsfHttpClient.setMaxResponseSize and the Spring Boot property easyssf.receiver.http.max-response-size.

A polled SET listed under a key other than its jti is reported as invalid_request under that key instead of handled. A polling thread ends as soon as it is no longer the poller's thread, so a stop() that timed out on a handler no longer leaves it running next to a restart. SsfStreamRegistrar.start() is idempotent, stop() joins the registration and a registration that completes after stop() publishes nothing. The stream client checks the issuer of every stream the transmitter returns, not only of a created one.

Fixes #61

A code review of the sibling libraries found weaknesses that the Java
receiver shares. The URI policy took any host name starting with "127."
for loopback and so allowed plain http for it; it now accepts only
localhost and names under it, 127.0.0.0/8 and ::1 (also IPv4-mapped),
the same rule as the Go library. The poll endpoint is held to that
policy before the access token is sent to it, configured or taken from
the stream, with a new SsfPoller.setUriPolicy. Response bodies read
from the transmitter are bounded, 4 MiB by default, through
JdkSsfHttpClient.setMaxResponseSize and the Spring Boot property
easyssf.receiver.http.max-response-size.

A polled SET listed under a key other than its jti is reported as
invalid_request under that key instead of handled. A polling thread
ends as soon as it is no longer the poller's thread, so a stop() that
timed out on a handler no longer leaves it running next to a restart.
SsfStreamRegistrar.start() is idempotent, stop() joins the registration
and a registration that completes after stop() publishes nothing. The
stream client checks the issuer of every stream the transmitter
returns, not only of a created one.

Fixes #61

Signed-off-by: Thomas Darimont <thomas.darimont@googlemail.com>
The acknowledgements the poller flushes on stop() went through the
shared request method without the endpoint check, so an endpoint that
had moved to plain http meanwhile would have received the access token.
The check now sits in that method, where every poll request passes.

The stream registrar checked that it was still the current registration
and then published, with stop() free to run in between. Publication and
the hand-over of the thread now exclude each other under a lock of
their own, so a registration either publishes before stop() goes on,
and the stream it published is the one stop() deletes, or not at all.

Signed-off-by: Thomas Darimont <thomas.darimont@googlemail.com>
Signed-off-by: Thomas Darimont <thomas.darimont@googlemail.com>
Signed-off-by: Thomas Darimont <thomas.darimont@googlemail.com>
@thomasdarimont
thomasdarimont merged commit b18b62f into main Oct 29, 2026
10 checks passed
@thomasdarimont
thomasdarimont deleted the gh-61-fix-review-findings branch October 29, 2026 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Harden the receiver against a review of the Go and Python ports

1 participant