Chapter 14. Hardening the Dashboard service
The Dashboard service (horizon) gives users a self-service portal for provisioning their own resources within the limits set by administrators. Manage the security of the Dashboard service with the same sensitivity as the OpenStack APIs.
14.1. Debugging the Dashboard service
The default value for the DEBUG
parameter is False
. Keep the default value in your production environment. Change this setting only during investigation. When you change the value of the DEBUG
parameter to True
, Django can output stack straces to browser users that contain sensitive web server state information.
When the value of the DEBUG
parameter is True
, the ALLOWED_HOSTS
settings are also disabled. For more information on configuring ALLOWED_HOSTS
, see Configure ALLOWED_HOSTS.
14.2. Selecting a domain name
It is a best practice to deploy the Dashboard service (horizon) to a second level domain, as opposed to a shared domain on any level. Examples of each are provided below:
-
Second level domain:
https://example.com
-
Shared subdomain:
https://example.public-url.com
Deploying the Dashboard service to a dedicated second level domain isolates cookies and security tokens from other domains, based on browsers' same-origin
policy. When deployed on a subdomain, the security of the Dashboard service is equivalent to the least secure application deployed on the same second-level domain.
You can further mitigate this risk by avoiding a cookie-backed session store, and configuring HTTP Strict Transport Security (HSTS) (described in this guide).
Deploying the Dashboard service on a bare domain, like https://example/
, is unsupported.
14.3. Configure ALLOWED_HOSTS
Horizon is built on the python Django web framework, which requires protection against security threats associated with misleading HTTP Host headers. To apply this protection, configure the ALLOWED_HOSTS
setting to use the FQDN that is served by the OpenStack dashboard.
When you configure the ALLOWED_HOSTS
setting, any HTTP request with a Host header that does not match the values in this list is denied, and an error is raised.
Procedure
Under
parameter_defaults
in your templates, set the value of theHorizonAllowedHosts
parameter:parameter_defaults: HorizonAllowedHosts: <value>
Replace
<value>
with the FQDN that is served by the OpenStack dashboard.- Deploy the overcloud with the modified template, and all other templates required for your environment.
14.4. Cross Site Scripting (XSS)
The OpenStack Dashboard accepts the entire Unicode character set in most fields. Malicious actors can attempt to use this extensibility to test for cross-site scripting (XSS) vulnerabilities. The OpenStack Dashboard service (horizon) has tools that harden against XSS vulnerabilites. It is important to ensure the correct use of these tools in custom dashboards. When you perform an audit against custom dashboards, pay attention to the following:
-
The
mark_safe
function. -
is_safe
- when used with custom template tags. -
The
safe
template tag. - Anywhere auto escape is turned off, and any JavaScript which might evaluate improperly escaped data.
14.5. Cross Site Request Forgery (CSRF)
Dashboards that use multiple JavaScript instances should be audited for vulnerabilities such as inappropriate use of the @csrf_exempt
decorator. Evaluate any dashboard that does not follow recommended security settings before lowering CORS (Cross Origin Resource Sharing) restrictions. Configure your web server to send a restrictive CORS header with each response. Allow only the dashboard domain and protocol, for example:Access-Control-Allow-Origin: https://example.com/
. You should never allow the wild card origin.
14.6. Allow iframe embedding
The DISALLOW_IFRAME_EMBED
setting disallows Dashboard from being embedded within an iframe. Legacy browsers can still be vulnerable to Cross-Frame Scripting (XFS) vulnerabilities, so this option adds extra security hardening for deployments that do not require iframes. The setting is set to True
by default, however it can be disabled using an environment file, if needed.
Procedure
- You can allow iframe embedding using the following parameter:
parameter_defaults: ControllerExtraConfig: horizon::disallow_iframe_embed: false
These settings should only be set to False
once the potential security impacts are fully understood.
14.7. Using HTTPS encryption for Dashboard traffic
It is recommended you use HTTPS to encrypt Dashboard traffic. You can do this by configuring it to use a valid, trusted certificate from a recognized certificate authority (CA). Private organization-issued certificates are only appropriate when the root of trust is pre-installed in all user browsers.
Configure HTTP requests to the dashboard domain to redirect to the fully qualified HTTPS URL.
See Chapter 7, Enabling SSL/TLS on overcloud public endpoints. for more information.
14.8. HTTP Strict Transport Security (HSTS)
HTTP Strict Transport Security (HSTS) prevents browsers from making subsequent insecure connections after they have initially made a secure connection. If you have deployed your HTTP services on a public or an untrusted zone, HSTS is especially important.
For director-based deployments, this setting is enabled by default in the /usr/share/openstack-tripleo-heat-templates/deployment/horizon/horizon-container-puppet.yaml
file:
horizon::enable_secure_proxy_ssl_header: true
Verification
After the overcloud is deployed, check the local_settings
file for Red Hat OpenStack Dashboard (horizon) for verification.
Use
ssh
to connect to a controller:$ ssh tripleo-admin@controller-0
Check that the
SECURE_PROXY_SSL_HEADER
parameter has a value of('HTTP_X_FORWARDED_PROTO', 'https')
:sudo egrep ^SECURE_PROXY_SSL_HEADER /var/lib/config-data/puppet-generated/horizon/etc/openstack-dashboard/local_settings SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
14.9. Front-end caching
It is not recommended to use front-end caching tools with the Dashboard, as it renders dynamic content resulting directly from OpenStack API requests. As a result, front-end caching layers such as varnish
can prevent the correct content from being displayed. The Dashboard uses Django, which serves static media directly served from the web service and already benefits from web host caching.
14.10. Session backend
For director-based deployments, the default session backend for horizon is django.contrib.sessions.backends.cache
, which is combined with memcached. This approach is preferred to local-memory cache for performance reasons, is safer for highly-available and load balanced installs, and has the ability to share cache over multiple servers, while still treating it as a single cache.
You can review these settings in director’s horizon.yaml
file:
horizon::cache_backend: django.core.cache.backends.memcached.MemcachedCache horizon::django_session_engine: 'django.contrib.sessions.backends.cache'
14.11. Reviewing the secret key
The Dashboard depends on a shared SECRET_KEY
setting for some security functions. The secret key should be a randomly generated string at least 64 characters long, which must be shared across all active dashboard instances. Compromise of this key might allow a remote attacker to execute arbitrary code. Rotating this key invalidates existing user sessions and caching. Do not commit this key to public repositories.
For director deployments, this setting is managed as the HorizonSecret
value.
14.12. Configuring session cookies
The Dashboard session cookies can be open to interaction by browser technologies, such as JavaScript. For director deployments with TLS everywhere, you can harden this behavior using the HorizonSecureCookies
setting.
Never configure CSRF or session cookies to use a wildcard domain with a leading dot.
14.13. Validating password complexity
The OpenStack Dashboard (horizon) can use a password validation check to enforce password complexity.
Procedure
- Specify a regular expression for password validation, as well as help text to be displayed for failed tests. The following example requires users to create a password of between 8 to 18 characters in length:
parameter_defaults: HorizonPasswordValidator: '^.{8,18}$' HorizonPasswordValidatorHelp: 'Password must be between 8 and 18 characters.'
-
Apply this change to your deployment. Save the settings as a file called
horizon_password.yaml
, and then pass it to theovercloud deploy
command as follows. The<full environment>
indicates that you must still include all of your original deployment parameters. For example:
openstack overcloud deploy --templates \ -e <full environment> -e horizon_password.yaml
14.14. Enforce the administrator password check
The following setting is set to True
by default, however it can be disabled using an environment file, if needed.
These settings should only be set to False
once the potential security impacts are fully understood.
Procedure
The ENFORCE_PASSWORD_CHECK
setting in Dashboard’s local_settings.py
file displays an Admin Password field on the Change Password form, which helps verify that an administrator is initiating the password change.
-
You can disable
ENFORCE_PASSWORD_CHECK
using an environment file:
parameter_defaults: ControllerExtraConfig: horizon::enforce_password_check: false
14.15. Disable password reveal
The disable_password_reveal
parameter is set to True
by default, however it can be disabled using an environment file, if needed. The password reveal button allows a user at the Dashboard to view the password they are about to enter.
Procedure
-
Under the
ControllerExtraConfig
parameter, includehorizon::disable_password_reveal: false
. Save this to a heat environment file and include it with your deployment command.
Example
parameter_defaults: ControllerExtraConfig: horizon::disable_password_reveal: false
These settings should only be set to False
once the potential security impacts are fully understood.
14.16. Displaying a logon banner for the Dashboard
Regulated industries such as HIPAA, PCI-DSS, and the US Government require you to display a user logon banner. The Red Hat OpenStack Platform (RHOSP) dashboard (horizon) uses a default theme (RCUE), which is stored inside the horizon container.
Within the custom Dashboard container, you can create a logon banner by manually editing the /usr/share/openstack-dashboard/openstack_dashboard/themes/rcue/templates/auth/login.html
file:
Procedure
Enter the required logon banner just before the
{% include 'auth/_login.html' %}
section. HTML tags are allowed:<snip> <div class="container"> <div class="row-fluid"> <div class="span12"> <div id="brand"> <img src="../../static/themes/rcue/images/RHOSP-Login-Logo.svg"> </div><!--/#brand--> </div><!--/.span*--> <!-- Start of Logon Banner --> <p>Authentication to this information system reflects acceptance of user monitoring agreement.</p> <!-- End of Logon Banner --> {% include 'auth/_login.html' %} </div><!--/.row-fluid→ </div><!--/.container--> {% block js %} {% include "horizon/_scripts.html" %} {% endblock %} </body> </html>
The above example produces a dashboard similar to the following:
Additional resources
14.17. Limiting the size of file uploads
You can optionally configure the dashboard to limit the size of file uploads; this setting might be a requirement for various security hardening policies.
LimitRequestBody
- This value (in bytes) limits the maximum size of a file that you can transfer using the Dashboard, such as images and other large files.
This setting has not been formally tested by Red Hat. It is recommended that you thoroughly test the effect of this setting before deploying it to your production environment.
File uploads will fail if the value is too small.
For example, this setting limits each file upload to a maximum size of 10 GB (10737418240
). You will need to adjust this value to suit your deployment.
/var/lib/config-data/puppet-generated/horizon/etc/httpd/conf/httpd.conf
<Directory /> LimitRequestBody 10737418240 </Directory>
/var/lib/config-data/puppet-generated/horizon/etc/httpd/conf.d/10-horizon_vhost.conf
<Directory "/var/www"> LimitRequestBody 10737418240 </Directory>
/var/lib/config-data/puppet-generated/horizon/etc/httpd/conf.d/15-horizon_ssl_vhost.conf
<Directory "/var/www"> LimitRequestBody 10737418240 </Directory>
These configuration files are managed by Puppet, so any unmanaged changes are overwritten whenever you run the openstack overcloud deploy
process.