It seems that zypper downloads as root

Apt used to download as root but now uses a user like _apt or something OpenBSD style.

Are there any plans for zypper to download as a limited user to reduce the attack surface or am I missing something like libcurl dropping privileges?

What is the attack surface? Installing packages require elevated privileges. How does downloading of a package increase the attack surface when the installation needs to be done as root or sudo?

1 Like

A compromised mirror or TLS server (DNS issues could expand that list) can compromise zypper getting an immediate root shell instead of needing to gain privileges. Ideally it would be chrooted giving little access to execute anything meaning it couldn’t raise privileges.

Care to elaborate how a curl download could be turned into invoking a shell?

Buffer overflow for example

We are talking about RPM packages that contain pre- and post-transaction scripts that are by definition executed with root privileges during package installation. So if the download can get compromised, the whole package can be exchanged by an attacker with far wider reaching consequences. That would leave only the package signature as the last and only line of defense.

I think this whole discussion is going nowhere.

5 Likes

But it isn’t the package that needs to be compromised just the TCP connection or TLS negotiation and an exploit in zypper or what it calls is all that is needed. Dropping privileges mitigates the immediate root shell and likely turns it into a denial of service instead or owning the box.

I must not have communicated very well.

I am not talking about the downloaded files themselves being compromised but the code handling the transport of the files and potentially signature parsing.

Once you have downloaded and verified the files then processing them as root is fine but until that point then there is a lot of C code and not just C++ using only safe constructs that is being executed as root and it would be far safer if it was not.

I fully understood that. Yet my argument is that whatever theoretical risk there is if the connection is compromised and if there is actually an existing leak like your mentioned buffer overflow, that is IMHO a very remote risk compared with that same compromised connection being able to smuggle in a compromised RPM that can be manipulated with very little effort to execute any code with root privileges in its pre- or post-transaction scripts.

A buffer overflow in a system administration tool like zypper is always a large security risk. But to the best of my knowledge that has never happened during the lifetime of libzypp (about 20 years).

Sure, one can always make things a lot more complicated for a theoretical risk; but this is where the law of diminishing return comes in. And real-life DoS when the security measures prevent users from legitimate uses of their tools (this is why I got rid of AppArmor many years ago, and why I flatly refuse to even touch stuff such as SELinux; been there, done that, got burned badly, won’t do it again).

Just consider all the things that can go wrong with a change like you proposed. The permissions for such a new user account need to be set up correctly in all the right places (and constantly maintained); migrations need to be considered (and for sure there will be a gazillion users who have weird setups carried over from ancient systems over half a dozen of migrations). All that stuff needs to be tested thoroughly, and somebody (for sure not me) will have to deal with the resulting bug reports and with angry business customers.

If you volunteer for that aspect (and keep doing that), fine; feel free to make a suggestion to the libzypp team.

But in my (admittedly limited - just 26 years) experience of dealing with such stuff, those who make such grand suggestions are never those who are also willing to carry the burden.

4 Likes

Taking over a connection is far more difficult than abusing one connection often with many attempts to cause a buffer overflow and rop slide.

You have some fair points but not having a buffer overflow in zypper in 20 years is not one of them as the eco system may not be written to the same standards as zypper itself. The point is that all the download code zypper calls seemingly runs as root (unless libcurl does something about it but it seems not). I don’t know why Linux persisted with OpenSSL instead of LibreSSL or Boring SSL but they did and so any of the many OpenSSL exploits would result in an almost immediate root shell under zypper and that is just one part of the download chain.

I don’t really see why separating out the download part (e.g. seteuid to a download directory of the same user or an suid curl binary) is so complex but perhaps due to the parallelism feature. You are right that I wouldn’t be stepping up with a PR any time soon due to being very busy. Especially as I have never coded in C++ and much prefer Ada SPARK.

p.s. If Linux ever gets pledge support then that is much nicer than using Selinux or Apparmor as it is tightly coupled to the program logic itself.

quod erat demonstrandum.

2 Likes

Is it be implement the download as user a bigger problem then discuss if there could be a problem download as root?

When something run as root there is attack surface.

1 Like

Read what I wrote above.

3 Likes

It is a significant risk that clearrly hasn’t been understood repeatedly. I hope going nowhere simply means I haven’t the time to make it reasonably secure, which is fine.

Void Linux has the same problem but atleast they recognise it. Xorg ignored OpenBSDs patches for years. Tcpdump refused OpenBSDs patches. Probably no one noticed using tcpdump on Linux but people surely have been compromised as a result.

In candore decus

This here is a user forum!

As long as you do not create a bug report no developer will know that there is (or might be?) something to fix.

And mind creating a bug report does not imply that you provide a solution in form of any code.

2 Likes

Explain it. What is the actual threat you think you have? Show examples. Show in the zypper code that those examples exist.

Just throwing out buzzwords doesn’t explain anything. Just saying ‘buffer overflow’ doesn’t explain anything. Just saying ‘it could happen and do this’ does not explain anything. Just saying ‘well curl does it this way’ doesn’t make a case because zypper is not curl and they operate very differently. Going on tangents about technologies that are not in use does not help the discussion.

You haven’t actually made a case at all. You just threw some terms around, said other projects did something and just assumed that was enough.

5 Likes

I don’t know all of which of these such as libxml are in the download/remote connection path but any of those with CVEs should demonstrate the biggest problem.

ldd /usr/bin/zypper
        linux-vdso.so.1 (0x00007fada59e5000)
        libzypp.so.1735 => /lib64/libzypp.so.1735 (0x00007fada5000000)
        libreadline.so.8 => /lib64/libreadline.so.8 (0x00007fada596d000)
        libaugeas.so.0 => /lib64/libaugeas.so.0 (0x00007fada591e000)
        libxml2.so.2 => /lib64/libxml2.so.2 (0x00007fada4e9a000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fada4a00000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fada58ee000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fada4807000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fada59e7000)
        libz.so.1 => /lib64/glibc-hwcaps/x86-64-v3/libz.so.1.2.13 (0x00007fada58d4000)
        liblzma.so.5 => /lib64/glibc-hwcaps/x86-64-v3/liblzma.so.5.8.1 (0x00007fada589a000)
        libbz2.so.1 => /lib64/glibc-hwcaps/x86-64-v3/libbz2.so.1.0.6 (0x00007fada587f000)
        libzstd.so.1 => /lib64/glibc-hwcaps/x86-64-v3/libzstd.so.1.5.7 (0x00007fada4de6000)
        librpm.so.10 => /lib64/librpm.so.10 (0x00007fada4d66000)
        librpmio.so.10 => /lib64/librpmio.so.10 (0x00007fada5845000)
        libboost_thread.so.1.86.0 => /lib64/glibc-hwcaps/x86-64-v3/libboost_thread.so.1.86.0 (0x00007fada55e2000)
        libyaml-cpp.so.0.8 => /lib64/libyaml-cpp.so.0.8 (0x00007fada4d1a000)
        libudev.so.1 => /lib64/libudev.so.1 (0x00007fada559e000)
        libgpgme.so.11 => /lib64/libgpgme.so.11 (0x00007fada4cc2000)
        libcurl.so.4 => /lib64/libcurl.so.4 (0x00007fada472f000)
        libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007fada45db000)
        libcrypto.so.3 => /lib64/glibc-hwcaps/x86-64-v3/libcrypto.so.3.5.0 (0x00007fada3e00000)
        libsigc-2.0.so.0 => /lib64/libsigc-2.0.so.0 (0x00007fada4cb9000)
        libzck.so.1 => /lib64/libzck.so.1 (0x00007fada45bb000)
        libtinfo.so.6 => /lib64/libtinfo.so.6 (0x00007fada457a000)
        libfa.so.1 => /lib64/libfa.so.1 (0x00007fada4ca6000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fada4492000)
        libacl.so.1 => /lib64/libacl.so.1 (0x00007fada4489000)
        libcap.so.2 => /lib64/libcap.so.2 (0x00007fada447d000)
        libpopt.so.0 => /lib64/libpopt.so.0 (0x00007fada446e000)
        liblua5.4.so.5 => /lib64/liblua5.4.so.5 (0x00007fada3dbe000)
        libgcrypt.so.20 => /lib64/glibc-hwcaps/x86-64-v3/libgcrypt.so.20.7.1 (0x00007fada3c13000)
        libassuan.so.9 => /lib64/libassuan.so.9 (0x00007fada3bfe000)
        libgpg-error.so.0 => /lib64/libgpg-error.so.0 (0x00007fada3bd2000)
        libnghttp2.so.14 => /lib64/libnghttp2.so.14 (0x00007fada3ba6000)
        libidn2.so.0 => /lib64/libidn2.so.0 (0x00007fada3b84000)
        libssh.so.4 => /lib64/libssh.so.4 (0x00007fada3b05000)
        libpsl.so.5 => /lib64/libpsl.so.5 (0x00007fada3af1000)
        libssl.so.3 => /lib64/glibc-hwcaps/x86-64-v3/libssl.so.3.5.0 (0x00007fada39d0000)
        libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007fada397c000)
        libldap.so.2 => /lib64/libldap.so.2 (0x00007fada3919000)
        liblber.so.2 => /lib64/liblber.so.2 (0x00007fada3908000)
        libbrotlidec.so.1 => /lib64/glibc-hwcaps/x86-64-v3/libbrotlidec.so.1.1.0 (0x00007fada38fa000)
        libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x00007fada3842000)
        libjitterentropy.so.3 => /lib64/libjitterentropy.so.3 (0x00007fada4463000)
        libunistring.so.5 => /lib64/libunistring.so.5 (0x00007fada365b000)
        libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007fada358c000)
        libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007fada3574000)
        libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007fada356e000)
        libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007fada355f000)
        libsasl2.so.3 => /lib64/libsasl2.so.3 (0x00007fada3540000)
        libbrotlicommon.so.1 => /lib64/glibc-hwcaps/x86-64-v3/libbrotlicommon.so.1.1.0 (0x00007fada351d000)
        libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007fada3516000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fada3505000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fada34d3000)

https://www.cve.org/CVERecord?id=CVE-2015-7547

https://curl.se/docs/security.html

A list of dynamically linked libraries is not a explanation. Issues with linked libraries are solved by patching those libraries.

You seem to be incapable of actually explaining the problem you seem to think exists, instead relying on some terms and a list of libraries with a handwavy ‘see there’s probably a problem there.’

Linking later to a CVE that was patched like 10 years ago doesn’t help, but illustrates that it is solved by patching the affected software.

2 Likes

I though it was a quite well known technique and I had already outlined the problem but perhaps the signal to noise ratio was too low. Security is about defence in depth unless secure languages like Ada SPARK are used well and even then it is preferable.

If someone exploits that CVE (1 of many as I looked for 2 minutes) and gains a shell then it inherits the rights of the process exploited. In zyppers case that is root and total system compromise. If the download or e.g. libresolv (which has an attack surface due to making conections) was ran as another user with e.g. only access to the download folder then the spawned shell would not be able to execute anything and can’t do much at all. Note that a user with access to execute many binaries is basically guaranteed to be able to raise privileges so limited user rights coupled with next to no filesystem access is essential.

This technique is called privilege dropping and is conducted by apt with the _apt user, dovecot, ssh and apache etc. . SSH and Dovecot use chroot but I don’t actually know how apt restricts filesystem access.