http://bugzilla.opensuse.org/show_bug.cgi?id=1038984 Bug ID: 1038984 Summary: [security] rpm-md repository security downgrade Classification: openSUSE Product: openSUSE Distribution Version: Leap 42.2 Hardware: All OS: openSUSE 42.2 Status: NEW Severity: Major Priority: P5 - None Component: libzypp Assignee: zypp-maintainers@forge.provo.novell.com Reporter: boleslaw.tokarski@gmail.com QA Contact: qa-bugs@suse.de Found By: --- Blocker: --- TLL;DR: It's possible to replace a signed rpm-md repository with an unsigned one and the machine using it will not notice. This is a long set of infortunate choices, which degrade repository security: 1. gpgcheck=1 in /etc/zypp/repos.d/ defaults to both repo_gpgcheck=1 and pkg_gpgcheck=1 at configuration parsing. 2. Package downloader is satisfied by either of the conditions enabled - signature of either repository or of the package. Since pkg_gpgcheck is 1 by default, it accepts an unsigned repository. 3. libzypp checks signatures on the downloaded package, and it relies on rpm to do the verification. Since rpm does not find any signature in the package, but the checksums are correct, it returns that the package is fine. 4. Package gets installed Thus an example rpm-md repository, which had the repository signed (and perhaps even packages), like this: [repo] name=An rpm-md repository enabled=1 autorefresh=1 baseurl=http://repo.example.com/ type=rpm-md gpgcheck=1 can be directed (by the way of DNS, IP spoofing, or remote server compromise), to an unsigned repository with unsigned packages. The gpgcheck=1 option suggests that we are ensuring some kind of GPG verification of the package origin, thus we should be safe from using unencrypted HTTP - after all, the package repository contents are not secret, thus no need for encryption. Using HTTPS would make it harder to do IP or DNS spoofing. ad. 1. zypp.conf: ## Signature checking (repodata and rpm packages) ## ## boolean gpgcheck (default: on) ## boolean repo_gpgcheck (default: unset -> according to gpgcheck) ## boolean pkg_gpgcheck (default: unset -> according to gpgcheck) ad. 2. According to https://github.com/openSUSE/zypper/issues/70, in version libzypp-15.3.0 there was a change which allowed to have *either* the rpm-md repository signed, or the package - libzypp commit 4fdccab4b649d23bf5e2e7b33c2bc4dc412d2482: if ( repoInfo().repoGpgCheck() ) { if ( isSigned || !repoInfo().pkgGpgCheck() ) So if pkg_gpgcheck is enabled (it is by default), libzypp will not care about repository being signed or not. ad. 3. zypp/target/rpm/RpmDb.c calls ::rpmVerifySignatures for the downloaded package: qva.qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE); int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.basename().c_str() ); Tracing the call to rpm, rpmVerifySignatures is a wrapper around rpmpkgVerifySigs. which is also called from rpmkeys.c. Basically running: rpmkeys -K $package is an equivalent, as it sets the same flags to rpmpkgVerifySigs. As one can test, rpmkeys -K is pretty happy about packages that don't contain a signature at all - all the checksums pass, so it exits with a 0 return code, the same way rpmVerifySignatures returns the information that the package is OK. --- The problem does not directly affect the yast2 repositories, as zypper pointed to an unsigned yast2 repository prints a warning about missing signature: File 'content' from repository 'openSUSE-42.2_OSS' is unsigned, continue? [yes/no] (no): Ignoring this warning installs an unsigned package, but it's better than not issuing a warning at all, like the rpm-md case. It seems the only workaround for now to make sure the repository signature is verified currently is to explicitly set pkg_gpgcheck=0 for the repository. -- You are receiving this mail because: You are on the CC list for the bug.