Skip to content

fix(updater): reject non-https GenericProvider origins - #579

Merged
kdroidFilter merged 1 commit into
nucleus-2.5from
security/updater-require-https
Aug 19, 2026
Merged

fix(updater): reject non-https GenericProvider origins#579
kdroidFilter merged 1 commit into
nucleus-2.5from
security/updater-require-https

Conversation

@kdroidFilter

Copy link
Copy Markdown
Collaborator

Security fix — F-5 (audit 2026-08-19)

Severity: Medium · Module: updater-runtime

Problem

GenericProvider(baseUrl) performed no scheme validation:

public class GenericProvider(public val baseUrl: String) : UpdateProvider

So GenericProvider("http://updates.example.com") drives the entire update — metadata manifest, checksums, artifact and the detached .asc — over plaintext http. On that channel the SHA-512 recorded in latest*.yml offers no protection, because an on-path attacker who can rewrite the artifact can rewrite the manifest that vouches for it. GitHubProvider already hardcodes https://; this was the one origin an application could point anywhere.

Fix

The base URL is validated at construction (init): https is required, and plain http is permitted only for loopback hosts (localhost, 127.0.0.0/8, ::1) so local integration tests — e.g. the delta RangeHttpServer, which serves fixtures over http://127.0.0.1 — keep working without TLS. Any other http/ftp/… origin throws IllegalArgumentException immediately, rather than silently downgrading security at the first network call.

Test

GenericProviderTest gains cases: public http rejected, non-http scheme rejected, loopback http allowed. Existing tests already use https only.

Verified locally: :updater-runtime:ktlintCheck :updater-runtime:detekt :updater-runtime:test all pass.

🤖 Generated with Claude Code

GenericProvider accepted any baseUrl with no scheme check, so
GenericProvider("http://updates.example.com") ran the whole update —
manifest, checksums, artifact and .asc — over plaintext, where the SHA-512
in the manifest offers no protection because an on-path attacker controls
the manifest too. GitHubProvider already hardcodes https; only this
extension point was exposed.

The base URL is now validated at construction: https is required, and
plain http is allowed only for loopback hosts (localhost / 127.0.0.0/8 /
::1) so local integration tests such as the delta RangeHttpServer keep
working without TLS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kdroidFilter
kdroidFilter merged commit a1a1d6d into nucleus-2.5 Aug 19, 2026
8 checks passed
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.

1 participant