openSUSE:Package security guidelines
Daemons
- installation of a package must not activate any daemon. That means for example init scripts must not be insserv'd in %post, xinetd files must contain 'disable = yes'.
- daemons should run under an unprivileged user id. That usually means the package has to create the user in it's %pre section. Daemons should avoid running as root and must not use the 'nobody' user. It's fine to use group 'nogroup' though.
- daemons should be restarted if the package was upgraded so security updates take effect immediately
- daemons that open TCP or UDP ports or otherwise receive input from potentially untrusted networks should receive an audit from the security team prior to inclusion in the distribution.
Setuid Binaries
Packages are not allowed to include setuid/setgid binaries unless the SUSE Security Team has reviewed the source code and granted explicit permission.
To request an audit for setuid binaries, open a bug report assigned to security-team@suse.de
and/or send an e-mail to security@suse.de
.
The bug report should include the exact location of the source code, the affected files and an explanation why the setuid bit is required. If the audit turns out positive, the security team will include permission settings for the new files in the 'permissions' package. The build system will reject packages with setuid binaries that are not listed in the permissions package.
In general having a setuid bit by default requires good reasons. Most of the time it's better to ship without setuid bit but including instructions how to modify /etc/permissions.local instead if needed.
setuid binaries need to be packaged specially. See the %verify_permissions macro for examples.
Packaging setuid binaries
Security-relevant permissions are handled via /etc/permissions*
on openSUSE.
Read the files /etc/permissions*
to learn about the basics.
If you want to create a package with suid programs:
- Add a
Requires(post): permissions
header to your spec file. - In the
%files
section, define the attributes of the files listed in your permissions files as they are defined forpermissions.secure
. Instructrpmverify
to not check ownership or permissions. - Add a
%post
scriptlet that sets your package's permissions according to the system's current security level. - Add a
%verifyscript
scriptlet that checks your package's permissions according to the system's current security level.
Because the above contains a few non-obvious details, here's a stripped down example:
[...] PreReq: permissions [...]
%if 0%{?suse_version} >= 1120 %verifyscript %verify_permissions -e %_bindir/mysuidprogram %endif %post %if 0%{?set_permissions:1} %set_permissions %name %else %run_permissions %endif %files [...] %verify(not user group mode) %attr(0711,root,root) %_bindir/mysuidprogram [...]
To do temporary builds in your home project:
- Use the package-specific permissions that can be defined through files in
/etc/permissions.d/
.
- Create
permissions{,.easy,.secure,.paranoid}
files for your package.permissions
is used if no filepermissions.*
matching the system's current security setting is found. As a rule of thumb,permissions.easy
should contain permissions as installed bymake install
,permissions.paranoid
should remove all suid bits (even if this breaks functionality), andpermissions.secure
can be something in between. - Add these permissions files as sources to the spec file, and have
%install
install them in%buildroot/%_sysconfdir/permissions.d/packagename[.suffix]
. - In order to avoid rpmlint's error messages about disallowed permissions files, create a file
packagename-rpmlintrc
containing the linesetBadness('permissions-unauthorized-file', 333)
, and list it as a Source in your spec file. (Modify the "333" if you have fewer or more than 3 disallowed files.)
Please note that all these workarounds must be removed before the package is submitted to the openSUSE distribution.
World Writable Directories
In general world writable directories should be avoided. If a package desperately needs world writable directories the same rules as for setuid binaries apply.
Group Writable Directories
There is no build check for directories writable by some special group and no review by the security-team needed. However, packagers should be aware that directories inside group writable directories cannot be packaged securely and may allow members of the group to elevate their privileges to root. In other words never package directories inside group writable directories.
Firewall Settings
No package is allowed to modify SuSEfirewall's configuration file. An exception is granted for the yast2 firewall module. Any other application must use the interface offered by the yast2 firewall module to change firewall settings. Changing the firewall settings must always require explicit confirmation of the user.
DBus Services
Programs that offer services via the system DBUS must receive an audit from the security team prior to inclusion in the distribution. In general the same rules apply as for any other daemon.
PolicyKit Privileges
Programs that carry out privileged operations on behalf of the user (such as e.g. changing the clock) should define a PolicyKit privilege which a user is required to possess for a specific action to be carried out. Use of PolicyKit privileges has to be audited by the security team prior to inclusion in the distribution
Passwords
Packages must not be preconfigured with fixed passwords, certificates etc. Instead, the user must be forced to set a password prior to first usage.
Use Of Cryptography
In general packages must not implement their own cryptographic algorithms but should use either of the following implementations:
- mozilla-nss (preferred)
- openssl
- gcrypt
- gnutls
- kernel crypto interface (kernel modules only)
Preferably encryption and hash algorithms should be configurable and set to currently considered safe algorithms (e.g. AES, SHA-3). Use of MD5 or SHA-1 as cryptographic signatures are not safe anymore.
Packages should not ship their own set of trusted x509 certificates. Instead, /etc/ssl/certs should be used as fallback.
Audit Bugs for the Security Team
A number of security related program features require a whitelisting by the SUSE security team, before they can be packaged and submitted to Factory or any [open]SUSE product. Among these are the following situations:
- binaries installed by the package carry a setuid or setgid bit. This allows regular users to run the binary with elevated privileges. These kinds of binaries are difficult to implement correctly in a secure way. Therefore, the security team would like to avoid adding any additional set*id binaries to the distribution. If there is no way around it then a thorough review is necessary.
- new D-Bus services are installed by the package, that can be activated dynamically or via systemd units. D-Bus services often run as root and expose interfaces to regular users. Therefore, these cases are also security sensitive.
- systemd services are required to be disabled by default. Only a small number of packages is currently allowed to be enabled by default right after installing it. Other packages need to be enabled explicitly by the user. New default-enabled systemd services need to be reviewed as well.
- new PAM modules are installed by the package. They also require a security team review. Badly implemented PAM modules may cause user authentication to always succeed or otherwise badly influence security.
- new polkit actions or polkit rules are added. Polkit is an authentication framework that allows to authenticate individual operations instead of just allowing all or nothing. While this sounds (and is) good it still needs to be done right in each implementation. Therefore, this also requires a code review.
- cron jobs are installed in /etc/cron.*. Cron jobs can also easily introduce security issues. Note that by now most new packages are encouraged to use systemd timers instead of classic cron jobs.
- directories installed by the package are world-writable, carry a sticky bit or a setgid bit
- devices files are installed by the package
- sudo drop-in configuration files are installed into /etc/sudoers.d
- certain security sensitive systemd-tmpfiles drop-in configuration files are installed into /usr/lib/tmpfiles.d
The SUSE security team continuously works to extend the coverage of security sensitive package features. Therefore, this list is not exhaustive and new restrictions can become active over time.
If you add one of these items to your package then an rpmlint error will appear. If your package is affected by any of these restrictions and you want to submit the package to openSUSE:Factory or another production project then please open a bug in Bugzilla, assign it to security-team@suse.de and use a summary line that follows this pattern:
AUDIT-0: [package-name]: [topic]
So in a real example it would look like this:
AUDIT-0: mypackage: review of D-Bus service org.mypackage.myservice
In the bug description you should state the rpmlint error message and point to the location of the package in the build service. A member of the security team will then take care of the review and perform the necessary actions. One of the following bug creation templates can be used to create the bug, you only need to fill in the preset summary and description:
Please submit review requests early since reviewing can take a long time (at least a couple of days, mostly a week or two, sometimes longer) and you will be blocked from having your package added to openSUSE:Factory before the review is finished.
Audit Bug Lifecycle
The original audit bug will be used as a tracker bug for all the findings identified by the security team. Individual findings will be tracked as new bugs that block the original bug and have an AUDIT-FIND tag in the bug summary field. Once the audit is finished its tag will be changed from AUDIT-0 to AUDIT-TRACKER to indicate that it is only used as a tracker for the findings and the audit itself is done.
The number suffix in AUDIT-0 provides a rough categorization of priority for the review. Zero is the default and highest priority. AUDIT-1 is for topics that don't require immediate attention. AUDIT-2 or AUDIT-STALE is for reviews that are stuck for one reason or another and cannot currently progress (as seen from the SUSE security team side).
For AUDIT bugs that are solely concerned with backporting whitelistings to other SUSE products (e.g. to SUSE Linux Enterprise), we also rename the tag to AUDIT-WHITELIST. This is an indicator that no in-depth review is going on but mostly a maintenance process.
rpmlint
Errors in Packages
For reference, some examples of the possible rpmlint error messages that can occur in a package are listed in the following table:
Category | Error Messages |
---|---|
Polkit Privileges |
rpmlint-integration-test.x86_64: E: polkit-untracked-privilege (Badness: 10000) org.opensuse.rpmlint-test.test1 (auth_admin:auth_admin:auth_admin_keep) rpmlint-integration-test.x86_64: E: polkit-file-unauthorized (Badness: 10000) /usr/share/polkit-1/rules.d/myrules (file digest sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855) rpmlint-integration-test.x86_64: E: polkit-file-unauthorized (Badness: 10000) /etc/polkit-1/rules.d/90-default-privs.rules (file digest sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855) |
D-Bus Services |
rpmlint-integration-test.x86_64: E: dbus-file-unauthorized (Badness: 10000) /etc/dbus-1/system.d/com.suse.dbus.testing.conf (file digest sha256:fac51ad567667cdba707ac1d9410fea54110b3ee11dcf19a2eba34a1405070ac) rpmlint-integration-test.x86_64: E: dbus-file-digest-mismatch (Badness: 10000) /etc/dbus-1/system.d/rpmlint_mismatch.conf expected sha256:4a5e8e9ca514c73f1dbee55e88c4d75a235473c1d5cef4751d84016833961fdf, has:504c5a60b7173794e565755122ab77beaec9bcf208fb97a40237cb57c67b5a17 |
PAM Modules |
rpmlint-integration-test.x86_64: E: pam-file-unauthorized (Badness: 10000) /usr/lib64/security/mypam.so (file digest sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4 649b934ca495991b7852b855) |
Set*id bits |
rpmlint-integration-test.x86_64: E: permissions-file-setuid-bit (Badness: 10000) /usr/bin/setgidbin is packaged with setuid/setgid bits (02755) rpmlint-integration-test.x86_64: E: permissions-file-setuid-bit (Badness: 10000) /usr/bin/setuidbin is packaged with setuid/setgid bits (04755) |
Rpmlint whitelisting based on file digests
For some whitelistings the SUSE security team takes file contents into account. This means that a whitelisting will not only apply to a certain filename a package installs, but also to the exact content that file has. The purpose of this is for the security team to become aware of changes in sensitive items that are either introduced upstream or by packagers.
If the content of an already whitelisted file changes you will get an error message like this:
rpmlint-integration-test.x86_64: E: dbus-file-digest-mismatch (Badness: 10000) /etc/dbus-1/system.d/rpmlint_mismatch.conf expected sha256:4a5e8e9ca514c73f1dbee55e88c4d75a235473c1d5cef4751d84016833961fdf, has:504c5a60b7173794e565755122ab77beaec9bcf208fb97a40237cb57c67b5a17
In this case please open up a new follow-up AUDIT bug and the security team will review the changes and whitelist the new file digest if all is well. These follow-up audits usually will be quicker than the initial audits.
To avoid unnecessary administration if non-functional changes are introduces to whitelisted files, the whitelisting checks support normalization of XML and shell style configuration files. As part of the normalization whitespace and comment lines are removed from the file and the hash digest is calculated for the filtered file content. This means that changes in said whitespace or comments will not trigger an rpmlint error, but only actual changes in content.
Rpmlint whitelisting errors in home and devel Projects
The security related rpmlint errors are supposed to protect openSUSE:Factory from packages that are more likely to introduce security issues. We don't want to block you, however, while developing a package in a home or devel project or if you don't intend to currently submit a package to openSUSE:Factory. Therefore the badness values for packaging artifacts that are not whitelisted will be low when building in home and devel projects but will be high when building in the openSUSE:Factory project.
Remember, however, that your package will not successfully build in the openSUSE:Factory project until a review has been performed and a whitelisting has been submitted by the security team. This can take a longer time. So create AUDIT bugs early on if you plan to submit such a package to Factory.
How the Whitelisting Process Works
Once you have opened an AUDIT bug for the security team roughly the following will happen:
- a member of the security team will confirm your request and give you some initial information.
- when a security engineer is working on the bug, findings will be documented by it as the review goes along. If any critical security concerns or issues are found then the request will be declined. Sometimes you will be asked to improve certain aspects of the package for better security. In the best case you need to do nothing else and the review passes.
- when the review has passed, the security engineer will submit a whitelisting for your package to make the rpmlint error go away.
So when will the whitelisting become effective? The whitelisting is contained in certain OBS packages depending on the type of whitelisting:
- for polkit privileges the whitelisting is in package Base:System/polkit-default-privs
- for D-Bus services, PAM modules and anything not explicitly listed here the whitelisting is in package devel:openSUSE:Factory:rpmlint/rpmlint
- for setuid binaries the whitelisting is in package Base:System/permissions
- for default-enabled systemd services the whitelisting is in package Base:System/systemd-presets-branding-openSUSE for openSUSE and in systemd-presets-branding-SLE for SUSE enterprise.
The security engineer that is working on the AUDIT bug will make a submission to the appropriate package for openSUSE:Factory. Once this submission arrives in the OBS, an automated message is also posted in the AUDIT bug. The review and testing process in OBS can take a couple of days before the whitelisting is accepted to openSUSE:Factory. You can still submit your affected package to openSUSE:Factory, too. For this to work you should note in the submission comment that the submission should be handled in the same staging project as the whitelisting submission. Example comment:
Please handle this submission together with sr#123456 which contains the whitelisting for this package.
This way your submission will be built against the whitelisting submission in the same staging project and can successfully build. The whitelisting update and your package update can then happen together.
Once the whitelisting is accepted to Factory you can build your package successfully against the openSUSE:Factory standard repository. If you want to build against the openSUSE:Factory snapshot repository then you will need to wait for a new Tumbleweed snapshot to be released that contains the whitelisting update. You can determine this by following the Factory mailing list or by looking into the Changes files on the download server.
When you are backporting features to older openSUSE or SUSE distributions then it can happen that you will be needing a whitelisting backported, too. In this case you need to inform the responsible security engineer about it and the whitelisting will also be backported by way of a maintenance update. You can create an AUDIT-WHITELIST bug for us to keep track of the process.
Fixing Builds of Older Distributions in your Devel Project
Once there is a whitelisting in place for your package and it successfully builds against Factory you might notice that builds of your devel package against Repositories for older existing distributions are still failing. This is only logical, because in the older distributions no whitelisting for your security related feature is in place and in most cases also shouldn't be. There's two things you can do about this:
- you can simply disable the repositories for the older distributions, thereby not having them building at all anymore.
- you can ask the security-team to backport the whitelisting to the older codestreams. This should only be the exception, however.