Besides a lot of the performance work that was lately done as well as the stability and architectural improvements we work on, we are also striving to make ownCloud even more secure by improving our API as well as introducing new hardening features. In this blog post I am going to feature some of these changes.
- “data/.htaccess” is updated after each update
- SabreDAV web interface has been removed
- Trusted domains are now a hard requirement
- Failed login log entries supports reverse proxy settings
- Request ID supports mod_unique_id
- “From link” download functionality has been removed
- Security-related headers can now be sent by the web server
- Enhancement of root certificate handling
- OC_User_HTTP backend replaced by user_webdavauth
- Random-number generator returns all base64 characters
- OC.generateUrl encodes parameters now automatically
- Code checker checks for strict comparisons in PHP code
- Constructor of OC\Files\View prevents directory traversals
- Stricter Content-Security-Policy and more choices for developers
- New security guidance and tips & tricks
Please notice that this is only a preliminary list of the most important user visible security changes. There are obviously a ton of other changes that I didn’t cover in this blog post. Furthermore, as usual with any development version, the final build may not contain any of these features if we experience any major problems with it in the testing phase.
#”data/.htaccess” is updated after each update
In a default ownCloud setup the primary storage is stored on the filesystem pretty similar to the way they are stored in
the internal ownCloud filesystem. So if a user
carla uploads a file
invoice.xls to a folder
customers it is likely
to be stored under
/var/www/owncloud/data/carla/files/customers/invoice.xls. That said, this is simplified as there are
scenarios where this is not the case such as shared folders. The data will however still be in the data directory just in
While we generally recommend to move the “data” directory outside of the web root (i.e.
realize that this is not always a possibility especially considering shared hosting environments. Thus ownCloud allows
having this data also in a potential insecure location. As a protection against data leakage (as anybody could access the
files using a web browser otherwise) we ship the following
.htaccess folder disallowing access to these folders via the
As you can see we are effectively forbidding access to this directory using appropriate
.htaccess rules for Apache 2.2
as well as it’s successor 2.4. However, older versions of ownCloud come with
.htaccess files that do miss these
directives for Apache 2.4 or rely on components such as having the Apache 2.4 compatibility module
“mod_access_compat” installed. If an administrator updated
an older ownCloud instance to a newer Apache server there would be thus the potential risk of data leakage.
However, the administrative interface of ownCloud will since quite some version warn administrators if the
data directory is
exposed to the public due to a configuration problem. However, as software provider we have to take our users’ security
very seriously and thus automatically help administrators as much as possible to secure their instance.
With ownCloud 8.1 the existing
.htaccess file in the
data directory will thus for enhanced security get updated after
each update. Administrators are encouraged to not perform any custom modifications to these files and for an even more
secure experience move the
data folder outside of the web root.
#SabreDAV web interface has been removed
The SabreDAV web interface at
remote.php/webdav/ was primarily used as a debugging tool by developers allowing us to
test our integration with SabreDAV without actually starting a WebDAV client or craft requests ourselves. For end-users
the actual use-case of this endpoint was rather limited.
With ownCloud 8.1 we have updated our used SabreDAV version to 2.1 which comes with a new browser plugin. This new browser plugin has added much more functionalities such as displaying the specific attributes of a file (which are user-controllable), while this indeed is super nifty for debugging purposes the potential risk of a Social Engineering attempt using this interface was from our opinion too big so that we decided to not activate the SabreDAV file browser plugin anymore.
Furthermore, in the past we have discovered some potential vulnerabilities within the file browser plugin and further analysis by us has found some other problems. (fruux/sabre-dav#610, fruux/sabe-dav#611)
This does not mean that SabreDAV is insecure or – beware – a bad library, it just implies that with a solution such as ownCloud we are facing challenges that smaller projects do not face and every line of code increases the overall attack vector.
#Trusted domains are now a hard requirement
trusted_domains setting of ownCloud are with ownCloud 8.1 a new hard-requirement. In previous versions it was possible
to remove the configuration switch and it would accept any hostname as valid. We experienced a lot of misuse of this
configuration as there was initial a confusion about the setting resulting in users of ownCloud spreading wrong information
and dangerous tips and tricks.
In a nutshell: A trusted domain is a domain that the ownCloud server accepts connections at. So if you host “demo.owncloud.org” the trusted domain will be “demo.owncloud.org” and not every client address.
To protect our users it is thus not possible anymore to omit the “trusted_domain” setting. For a more throughout details about the trusted domains setting I recommend reading my post “A tale about trusted_domains”.
#Failed login log entries supports reverse proxy settings
The fact that ownCloud supports reverse proxies properly is often not known by administrators. Thus in most scenarios the IP address of the proxy server is used by the ownCloud for logging and audit purposes. It is however possible to configure a proxy mode that allows reading the IP address from specified headers. In such cases the actual client IP address is then logged.
In the sample configuration (
config/config.sample.php) the following relevant switches can be found:
In above configuration the server would read the
X-Forwarded-For header and then the
Forwarded-For header if a
request originates from one of the defined
198.51.100.128) and use this as client IP
address. A request not fulfilling those will just use the
$_SERVER['REMOTE_ADDR'] address provided by PHP.
Given these changes and the fact we were able to modify the failed login entry line a little bit, older ownCloud releases would create an entry such as the following:
With ownCloud 8.1
$remoteAddr will now get resolved to the proxy address and thus the
X-Forwarded-For entry is not
This is not the only case where ownCloud 8.1 will be able to properly use the client address and in reverse proxy environments it is highly recommended to configure these settings.
#Request ID supports mod_unique_id
Each request to an ownCloud instance gets a request ID associated which is used for example for logging purposes. Until now the request ID was simply a random identifier. With ownCloud 8.1 we will officially support “mod_unique_id”, this means the request ID will not longer be generated by the ownCloud server but by the Apache server instead. To enable this feature “mod_unique_id” just needs to be enabled.
This allows administrators to better correlate any log information with the ownCloud logs making it easier to track any potential security incident over bigger setups. Furthermore “mod_unique_id” is in proper setup environments guaranteeing uniqueness while the default ownCloud request ID may get reused. (as it only guarantees randomness when generating)
#”From link” download functionality has been removed
The “Download from link” feature has been in ownCloud for a long time and allowed users to specify an URL and ownCloud would connect to the given URL, download the site and store it in the users’ folder. This was especially useful when one had to download huge remote files such as ISOs and the current local network bandwidth was not sufficient to achieve this.
This feature has been removed in 8.1 since we realized that in quite some deployment scenarios, especially when it comes to huge company networks, it is not really desired to have such a feature. Often this would allow users to gain more insights into the network architecture or access to sensitive internal services if the deployment was not properly protected against such scenarios. Thus we decided that the low amount of users that actually use this feature are not worth potentially making all other deployments potentially insecure.
As our modular and unique application approach allows developers to create a huge bandwidth of applications there are already third-party applications such as “ocDownloader (NG)” filling the gap. Using third-party applications users that require such features can easily get those while the “core” code of ownCloud can stay slim and allows us core developers to focus on it’s stability.
#Security-related headers can now be sent by the web server
When operating a web application it is often desirable to have the basic HTTP security headers enabled to prevent security pitfalls. Some of these basic security headers are served by ownCloud already in a default environment. These includes:
X-XSS-Protection: 1; mode=block
- Enforces the browsers to enable their browser side Cross-Site-Scripting filter.
- Instructs search machines to not index these page.
- Prevents to embed the ownCloud instance within an iframe from other domains to prevent Clickjacking and other similar attacks.
However, these headers are added by the applications code in PHP and thus not served on static resources and rely on the fact that there is no way to bypass the intended response code path.
For optimal security administrators are encouraged to serve these basic HTTP headers by the web server to enforce them on
response. To do this Apache has to be configured to use the
.htaccess file as well as the following Apache modules needs
to be enabled:
Administrators can verify whether this security change is active by accessing a static resource served by the web server and verify that above mentioned security headers are shipped. This can for example be done via cURL using the CLI, in the following example the first accessed server would take advantage of this enhancement while the second would. The difference has been marked using a diff:
This changes also applies to the HTTPS enforcement of ownCloud that now has to happen on the web server layer and not anymore in the ownCloud configuration. While this is slightly less comfortable it ensures an overall better security level.
#Enhancement of root certificate handling
Proper HTTPS requests with PHP are hard. First all of the offered APIs are somewhat lacking and cumbersome to use. Secondly, and even more important, most hosts are improperly setup and missing the proper certificate chain. And if they offer one it is often very likely to be terribly outdated.
Very often we received bug reports by users experiencing problems with their ownCloud instance which in the end were triggered by their distributions and PHP settings. In the end this problems became very hard to debug and thus we decided to ship a root certificate bundle with ownCloud itself.
The root certificate chain contains the certificates shipped by Mozilla and we regularly sync it with the upstream certificates.
It can be found under
config/ca-bundle.crt and in case administrators want to include a custom root certificate they can
insert it into this file. To take effect on all user accounts an ownCloud update is required though since all user root
certificates needs to get regenerated as well.
This also fixes a problem in older ownCloud releases with regard to the personal certificate handling, if a user had imported custom SSL certificates only those were used and not the system certificates since with the API imposed by PHP it was only possible to specify a custom root certificate chain. If the chain of the user was used the official root certificates were not existent leading to a lot of other problems.
#OC_User_HTTP backend replaced by user_webdavauth
ownCloud supports by default a lot of external user databases, such as FTP, LDAP, IMAP and a HTTP backend authenticating via Basic Auth.
The HTTP backend
OC_User_HTTP has been deprecated with ownCloud 8.1 as it offers the same functionality as the
“user_webdavauth” application shipped with ownCloud as well. Even more, the latter one can easily be configured via web
interface and does not require adjusting the configuration file itself.
Administrators using the
OC_User_HTTP backend are encouraged to migrate to the “user_webdavauth” application. This can
be done by removing the entry from the configuration file and then enabling the “WebDAV authentication” application and
configure it in the admin interface:
#Random-number generator returns all base64 characters
While this is more of a nitpick than a security hardening the documentation of our cryptographically secure pseudo-random
number generator (CSPRNG) claimed to return a string containing all base64 characters. This was however not exactly the
case as the equals sign (
=) got silently dropped.
This is however especially important for developers as any generated random-number now needs to be properly encoded if used in URLs. One common occurrence is the CSRF token within applications that do not use AJAX requests on CSRF protected routes.
One should note that it is best practice to always ensure that all parameters are properly encoded before using it to prevent problems with unexpected data.
#OC.generateUrl encodes parameters now automatically
As we experienced some problems with developers using not properly encoded data such as the above mentioned CSRF token
OC.generateUrl function to properly encode any passed input, the following example explains
the problem pretty good:
With ownCloud 8.1 this will return the following URL:
older releases will instead return
/index.php/apps/myApp/accounts/MyAccountId"><script>alert(1)</script>. In quite some
cases this can unwillingly lead to either simply broken applications or even worse an actual bug with security implications.
Developers that rely on this behaviour can still achieve this by modifying the third
options parameter and disabling
the escaping as following:
#Code checker checks for strict comparisons in PHP code
While our coding guidelines already a longer time enforces the usage of strict comparisons within our code-base we can now enforce this using the built-in code checker in ownCloud. In fact it is now able to throw warnings when it encounters an usage of non-strict comparisons.
To understand the PHP strict comparison problem it is required to understand that PHP tries to make the life of developers
as easy as possible and thus even allows you to loosely compare strings with an integer. So a string with the value of
would equal an integer with a value of
While in the first sight this behaviour seems desirable and useful there are a few very big caveats. For once it is what
happens when PHP tries to cast a string into a number. It will simply result in a
0. In the following example the code
would return “Correct password!” even if the user provided an invalid numerical password as PHP tries to convert the
password into an integer.
To avoid this developers are advocated to use strict comparisons using
!== to avoid this potential pitfalls.
Using one of those both operators will prevent PHP from trying to cast the parameter to another type and perform a strict
A full list of the PHP type comparison behaviour can be found on php.net.
#Constructor of OC\Files\View prevents directory traversals
We’re aiming hard to have a “security by default” and “defense-in-depth” model in our code-base. Thus the internal ownCloud
filesystem is built to prevent directory traversals by forbidding potential dangerous character sequences such as
..\. This check was however only performed on the single methods and not on the constructor of the class.
A view represents something like a chroot within ownCloud, developers can instantiate a view on folders and users cannot escape from it or access data from without it. When an view was however initially constructed there was no check for those malicious characters.
This has lead to potential issues in the past when developers misused the class and to prevent future problems we have applied the same security to the constructor now as we do for the single methods.
#Stricter Content-Security-Policy and more choices for developers
Content-Security-Policy (CSP) is one of the most useful and powerful web features introduced in the recent years to the web. Basically with CSP applications can instruct the browser to follow a specified security model, this can include to not execute any inline scripts or not load remote resources.
Using a CSP compliant browser (mainly everything that is not IE) allows applications to maintain your very owns data’s security even if a Cross-Site-Scripting bug exists. With earlier versions of ownCloud there was a policy that applied to the whole instance. This had the disadvantage that the whole application received permissions it would probably not even require. Thus with ownCloud 8.1 we tightened the default policy, the policy as of today is:
- If no policy applies forbid the action.
script-src 'self' 'unsafe-eval'
- Execute only scripts served from the same domain and allow
- Execute only scripts served from the same domain and allow
style-src 'self' 'unsafe-inline'
- Execute only style sheets served from the same domain. Inline CSS is allowed.
- Load only images served from the same domain.
- Load only fonts served from the same domain.
- Allow the browser to only perform actions such as AJAX requests against the same domain.
- Load only videos and audio elements served from the same domain.
However, as a developer using the AppFramework it is now possible to modify the policy, in the following example the policy would now also allow loading of images and media elements from any domain:
Applications not using the AppFramework will still be subject to the policy used by older ownCloud versions.
#New security guidance and tips & tricks
It’s easy to introduce security problems or have a system improperly configured, thus for ownCloud 8.1 we will have a new “Tips & tricks” section giving tips to administrators how to properly configure their instances. This offers advises going from monitoring, performance tuning, over to theming and of course hardening and security guidance:
Furthermore the security warnings will now be more precise and show even more hints to administrators where applicable:
Security is hard and an always ongoing process and I am sure that with future releases we will be able to improve us even more. We are also always welcoming and looking for new contributors of any sort. If you think you can actively help us to make ownCloud even more secure you are more than welcome in “#owncloud-security” on the freenode IRC network.