Broke dashboard chapeter into section_ files
Change-Id: Iac71b5acfb3fdd8556316a3f316fa91c6a876d69 Closes-Bug: #1458022
This commit is contained in:
@@ -22,228 +22,20 @@
|
|||||||
and has good <link
|
and has good <link
|
||||||
xlink:href="http://docs.openstack.org/developer/horizon/topics/deployment.html"
|
xlink:href="http://docs.openstack.org/developer/horizon/topics/deployment.html"
|
||||||
>deployment and configuration documentation</link>.</para>
|
>deployment and configuration documentation</link>.</para>
|
||||||
<section xml:id="dashboard-basic-web-server-configuration">
|
<xi:include href="section_dashboard-basic-web-server-configuration.xml"/>
|
||||||
<title>Basic web server configuration</title>
|
<xi:include href="section_dashboard-https.xml"/>
|
||||||
<para>The dashboard should be deployed as a Web Services Gateway
|
<xi:include href="section_dashboard-http-strict-transport-security-hsts.xml"/>
|
||||||
Interface (WSGI) application behind an HTTPS proxy such as
|
<xi:include href="section_dashboard-front-end-caching.xml"/>
|
||||||
Apache or nginx. If Apache is not already in use, we recommend
|
<xi:include href="section_dashboard-domain-names.xml"/>
|
||||||
nginx since it is lightweight and easier to configure
|
<xi:include href="section_dashboard-static-media.xml"/>
|
||||||
correctly.</para>
|
<xi:include href="section_dashboard-secret-key.xml"/>
|
||||||
<para>When using nginx, we recommend <link
|
<xi:include href="section_dashboard-session-back-end.xml"/>
|
||||||
xlink:href="http://docs.gunicorn.org/en/latest/deploy.html"
|
<xi:include href="section_dashboard-allowed-hosts.xml"/>
|
||||||
>gunicorn</link> as the WSGI host with an appropriate number
|
<xi:include href="section_dashboard-cross-site-request-forgery-csrf.xml"/>
|
||||||
of synchronous workers. When using Apache, we recommend
|
<xi:include href="section_dashboard-cookies.xml"/>
|
||||||
<literal>mod_wsgi</literal> to host the dashboard.</para>
|
<xi:include href="section_dashboard-cross-site-scripting-xss.xml"/>
|
||||||
</section>
|
<xi:include href="section_dashboard-cross-origin-resource-sharing-cors.xml"/>
|
||||||
<section xml:id="dashboard-https">
|
<xi:include href="section_dashboard-horizon-image-upload.xml"/>
|
||||||
<title>HTTPS</title>
|
<xi:include href="section_dashboard-upgrading.xml"/>
|
||||||
<para>
|
<xi:include href="section_dashboard-debug.xml"/>
|
||||||
Deploy the dashboard behind a secure
|
|
||||||
<glossterm>HTTPS</glossterm> server by using 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.</para>
|
|
||||||
<para>Configure HTTP requests to the dashboard domain to redirect
|
|
||||||
to the fully qualified HTTPS URL.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-http-strict-transport-security-hsts">
|
|
||||||
<title>HTTP Strict Transport Security (HSTS)</title>
|
|
||||||
<para>It is highly recommended to use HTTP Strict Transport
|
|
||||||
Security (HSTS).</para>
|
|
||||||
<note>
|
|
||||||
<para>If you are using an HTTPS proxy in front of your web
|
|
||||||
server, rather than using an HTTP server with HTTPS
|
|
||||||
functionality, modify the <literal>SECURE_PROXY_SSL_HEADER</literal>
|
|
||||||
variable. Refer to the <link
|
|
||||||
xlink:href="https://docs.djangoproject.com/"
|
|
||||||
>Django documentation</link> for information about modifying the
|
|
||||||
<literal>SECURE_PROXY_SSL_HEADER</literal> variable.</para>
|
|
||||||
</note>
|
|
||||||
<para>See the chapter on PKI/SSL Everywhere for more specific
|
|
||||||
recommendations and server configurations for HTTPS
|
|
||||||
configurations, including the configuration of HSTS.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-front-end-caching">
|
|
||||||
<title>Front end caching</title>
|
|
||||||
<para>Since the dashboard is rendering dynamic content passed directly
|
|
||||||
from OpenStack API requests, we do not recommend front end
|
|
||||||
caching layers such as varnish. In Django, static media is
|
|
||||||
directly served from Apache or nginx and already benefits from
|
|
||||||
web host caching.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-domain-names">
|
|
||||||
<title>Domain names</title>
|
|
||||||
<para>Many organizations typically deploy web applications at
|
|
||||||
subdomains of an overarching organization domain. It is natural
|
|
||||||
for users to expect a domain of the form
|
|
||||||
<uri>openstack.example.org</uri>. In this context, there are
|
|
||||||
often many other applications deployed in the same second-level
|
|
||||||
namespace, often serving user-controlled content. This name
|
|
||||||
structure is convenient and simplifies name server
|
|
||||||
maintenance.</para>
|
|
||||||
<para>We strongly recommend deploying horizon to a
|
|
||||||
<emphasis>second-level domain</emphasis>, such as
|
|
||||||
<uri>https://example.com</uri>, and advise against deploying
|
|
||||||
horizon on a <emphasis>shared subdomain</emphasis> of any level,
|
|
||||||
for example <uri>https://openstack.example.org</uri> or
|
|
||||||
<uri>https://horizon.openstack.example.org</uri>. We also
|
|
||||||
advise against deploying to bare internal domains like
|
|
||||||
<uri>https://horizon/</uri>. These recommendations are based on the
|
|
||||||
limitations of browser same-origin-policy.</para>
|
|
||||||
<para>Recommendations given in this guide cannot effectively guard against
|
|
||||||
known attacks if you deploy the dashboard in a domain that also hosts
|
|
||||||
user-generated content, even when this content resides on a separate
|
|
||||||
sub-domain. User-generated content can consist of scripts, images, or uploads
|
|
||||||
of any type. Most major web presences, including googleusercontent.com,
|
|
||||||
fbcdn.com, github.io, and twimg.co, use this approach to segregate
|
|
||||||
user-generated content from cookies and security tokens.</para>
|
|
||||||
<para>If you do not follow this recommendation regarding
|
|
||||||
second-level domains, avoid a cookie-backed session store and
|
|
||||||
employ HTTP Strict Transport Security (HSTS). When deployed on
|
|
||||||
a subdomain, the dashboard's security is equivalent to the least secure
|
|
||||||
application deployed on the same second-level domain.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-static-media">
|
|
||||||
<title>Static media</title>
|
|
||||||
<para>The dashboard's static media should be deployed to a subdomain
|
|
||||||
of the dashboard domain and served by the web server. The use of
|
|
||||||
an external content delivery network (CDN) is also acceptable.
|
|
||||||
This subdomain should not set cookies or serve user-provided
|
|
||||||
content. The media should also be served with HTTPS.</para>
|
|
||||||
<para>Django media settings are documented in the <link
|
|
||||||
xlink:href="https://docs.djangoproject.com/"
|
|
||||||
>Django documentation</link>.</para>
|
|
||||||
<para>Dashboard's default configuration uses <link
|
|
||||||
xlink:href="http://django-compressor.readthedocs.org/"
|
|
||||||
>django_compressor</link> to compress and minify CSS and
|
|
||||||
JavaScript content before serving it. This process should be
|
|
||||||
statically done before deploying the dashboard, rather than using
|
|
||||||
the default in-request dynamic compression and copying the
|
|
||||||
resulting files along with deployed code or to the CDN server.
|
|
||||||
Compression should be done in a non-production build
|
|
||||||
environment. If this is not practical, we recommend disabling
|
|
||||||
resource compression entirely. Online compression dependencies
|
|
||||||
(less, Node.js) should not be installed on production
|
|
||||||
machines.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-secret-key">
|
|
||||||
<title>Secret key</title>
|
|
||||||
<para>The dashboard depends on a shared <option>SECRET_KEY</option>
|
|
||||||
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 may 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.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-session-back-end">
|
|
||||||
<title>Session back end</title>
|
|
||||||
<para>Horizon's default session back end
|
|
||||||
(<literal>django.contrib.sessions.backends.signed_cookies</literal>)
|
|
||||||
stores user data in <emphasis>signed</emphasis> but
|
|
||||||
<emphasis>unencrypted </emphasis>cookies stored in the
|
|
||||||
browser. This approach allows the most simple session back-end
|
|
||||||
scaling since each dashboard instance is stateless, but it comes
|
|
||||||
at the cost of <emphasis>storing sensitive access tokens in the
|
|
||||||
client browser</emphasis> and transmitting them with every
|
|
||||||
request. This back end ensures that session data has not been
|
|
||||||
tampered with, but the data itself is not encrypted other than
|
|
||||||
the encryption provided by HTTPS.</para>
|
|
||||||
<para>If your architecture allows it, we recommend using
|
|
||||||
<literal>django.contrib.sessions.backends.cache</literal> as
|
|
||||||
your session back end with memcache as the cache. Memcache must
|
|
||||||
not be exposed publicly, and should communicate over a secured
|
|
||||||
private channel. If you choose to use the signed cookies
|
|
||||||
back end, refer to the Django documentation understand the
|
|
||||||
security trade-offs.</para>
|
|
||||||
<para>For further details, see the <link
|
|
||||||
xlink:href="https://docs.djangoproject.com/"
|
|
||||||
>Django documentation</link>.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-allowed-hosts">
|
|
||||||
<title>Allowed hosts</title>
|
|
||||||
<para>Configure the <option>ALLOWED_HOSTS</option> setting with
|
|
||||||
the domain or domains where the dashboard is available. Failure
|
|
||||||
to configure this setting (especially if not following the
|
|
||||||
recommendation above regarding second level domains) opens the
|
|
||||||
dashboard to a number of serious attacks. Wild card domains
|
|
||||||
should be avoided.</para>
|
|
||||||
<para>For further details, see the <link
|
|
||||||
xlink:href="https://docs.djangoproject.com/"
|
|
||||||
>Django documentation</link>.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-cross-site-request-forgery-csrf">
|
|
||||||
<title>Cross Site Request Forgery (CSRF)</title>
|
|
||||||
<para>Django has dedicated middleware for cross-site request forgery (CSRF).
|
|
||||||
For further details, see the <link xlink:href="https://docs.djangoproject.com/">
|
|
||||||
Django documentation</link>.</para>
|
|
||||||
<para>Dashboard is designed to discourage developers from
|
|
||||||
introducing cross-site scripting vulnerabilities with custom
|
|
||||||
dashboards. However, it is important to audit custom dashboards,
|
|
||||||
especially ones that are JavaScript-heavy for inappropriate use
|
|
||||||
of the <literal>@csrf_exempt</literal> decorator. Dashboards
|
|
||||||
which do not follow these recommended security settings should
|
|
||||||
be carefully evaluated before restrictions are relaxed.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-cookies">
|
|
||||||
<title>Cookies</title>
|
|
||||||
<para>Session Cookies should be set to HTTPONLY:</para>
|
|
||||||
<programlisting>SESSION_COOKIE_HTTPONLY = True</programlisting>
|
|
||||||
<para>Never configure CSRF or session cookies to have a wild card
|
|
||||||
domain with a leading dot. Horizon's session and CSRF cookie
|
|
||||||
should be secured when deployed with HTTPS:</para>
|
|
||||||
<programlisting>CSRF_COOKIE_SECURE = True
|
|
||||||
SESSION_COOKIE_SECURE = True</programlisting>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-cross-site-scripting-xss">
|
|
||||||
<title>Cross Site Scripting (XSS)</title>
|
|
||||||
<para>Unlike many similar systems, the OpenStack dashboard allows the
|
|
||||||
entire Unicode character set in most fields. This means
|
|
||||||
developers have less latitude to make escaping mistakes that
|
|
||||||
open attack vectors for cross-site scripting (XSS).</para>
|
|
||||||
<para>Dashboard provides tools for developers to avoid creating
|
|
||||||
XSS vulnerabilities, but they only work if developers use them
|
|
||||||
correctly. Audit any custom dashboards, paying particular
|
|
||||||
attention to use of the <literal>mark_safe</literal> function,
|
|
||||||
use of <literal>is_safe</literal> with
|
|
||||||
custom template tags, the <literal>safe</literal> template tag, anywhere
|
|
||||||
auto escape
|
|
||||||
is turned off, and any JavaScript which might evaluate
|
|
||||||
improperly escaped data.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-cross-origin-resource-sharing-cors">
|
|
||||||
<title>Cross Origin Resource Sharing (CORS)</title>
|
|
||||||
<para>Configure your web server to send a restrictive CORS header
|
|
||||||
with each response, allowing only the dashboard domain and
|
|
||||||
protocol:</para>
|
|
||||||
<programlisting>Access-Control-Allow-Origin: https://example.com/</programlisting>
|
|
||||||
<para>Never allow the wild card origin.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-horizon-image-upload">
|
|
||||||
<title>Horizon image upload</title>
|
|
||||||
<para>We recommend that implementers <link
|
|
||||||
xlink:href="http://docs.openstack.org/developer/horizon/topics/deployment.html#file-uploads"
|
|
||||||
>disable HORIZON_IMAGES_ALLOW_UPLOAD</link> unless they have
|
|
||||||
implemented a plan to prevent resource exhaustion and denial of
|
|
||||||
service.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-upgrading">
|
|
||||||
<title>Upgrading</title>
|
|
||||||
<para>Django security releases are generally well tested and
|
|
||||||
aggressively backwards compatible. In almost all cases, new
|
|
||||||
major releases of Django are also fully backwards compatible
|
|
||||||
with previous releases. Dashboard implementers are strongly
|
|
||||||
encouraged to run the latest stable release of Django with
|
|
||||||
up-to-date security releases.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="dashboard-debug">
|
|
||||||
<title>Debug</title>
|
|
||||||
|
|
||||||
<para>We recommend that the <option>DEBUG</option> setting
|
|
||||||
is set to <literal>False</literal> in production environments.
|
|
||||||
If <option>DEBUG</option> is set to True,
|
|
||||||
Django will display stack traces and sensitive web server
|
|
||||||
state information when exceptions are thrown.</para>
|
|
||||||
</section>
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|||||||
18
security-guide/section_dashboard-allowed-hosts.xml
Normal file
18
security-guide/section_dashboard-allowed-hosts.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-allowed-hosts">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>Allowed hosts</title>
|
||||||
|
<para>Configure the <option>ALLOWED_HOSTS</option> setting with
|
||||||
|
the domain or domains where the dashboard is available. Failure
|
||||||
|
to configure this setting (especially if not following the
|
||||||
|
recommendation above regarding second level domains) opens the
|
||||||
|
dashboard to a number of serious attacks. Wild card domains
|
||||||
|
should be avoided.</para>
|
||||||
|
<para>For further details, see the <link
|
||||||
|
xlink:href="https://docs.djangoproject.com/"
|
||||||
|
>Django documentation</link>.</para>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-basic-web-server-configuration">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>Basic web server configuration</title>
|
||||||
|
<para>The dashboard should be deployed as a Web Services Gateway
|
||||||
|
Interface (WSGI) application behind an HTTPS proxy such as
|
||||||
|
Apache or nginx. If Apache is not already in use, we recommend
|
||||||
|
nginx since it is lightweight and easier to configure
|
||||||
|
correctly.</para>
|
||||||
|
<para>When using nginx, we recommend <link
|
||||||
|
xlink:href="http://docs.gunicorn.org/en/latest/deploy.html"
|
||||||
|
>gunicorn</link> as the WSGI host with an appropriate number
|
||||||
|
of synchronous workers. When using Apache, we recommend
|
||||||
|
<literal>mod_wsgi</literal> to host the dashboard.</para>
|
||||||
|
</section>
|
||||||
16
security-guide/section_dashboard-cookies.xml
Normal file
16
security-guide/section_dashboard-cookies.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-cookies">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>Cookies</title>
|
||||||
|
<para>Session Cookies should be set to HTTPONLY:</para>
|
||||||
|
<programlisting>SESSION_COOKIE_HTTPONLY = True</programlisting>
|
||||||
|
<para>Never configure CSRF or session cookies to have a wild card
|
||||||
|
domain with a leading dot. Horizon's session and CSRF cookie
|
||||||
|
should be secured when deployed with HTTPS:</para>
|
||||||
|
<programlisting>CSRF_COOKIE_SECURE = True
|
||||||
|
SESSION_COOKIE_SECURE = True</programlisting>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-cross-origin-resource-sharing-cors">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>Cross Origin Resource Sharing (CORS)</title>
|
||||||
|
<para>Configure your web server to send a restrictive CORS header
|
||||||
|
with each response, allowing only the dashboard domain and
|
||||||
|
protocol:</para>
|
||||||
|
<programlisting>Access-Control-Allow-Origin: https://example.com/</programlisting>
|
||||||
|
<para>Never allow the wild card origin.</para>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-cross-site-request-forgery-csrf">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>Cross Site Request Forgery (CSRF)</title>
|
||||||
|
<para>Django has dedicated middleware for cross-site request forgery (CSRF).
|
||||||
|
For further details, see the <link xlink:href="https://docs.djangoproject.com/">
|
||||||
|
Django documentation</link>.</para>
|
||||||
|
<para>Dashboard is designed to discourage developers from
|
||||||
|
introducing cross-site scripting vulnerabilities with custom
|
||||||
|
dashboards. However, it is important to audit custom dashboards,
|
||||||
|
especially ones that are JavaScript-heavy for inappropriate use
|
||||||
|
of the <literal>@csrf_exempt</literal> decorator. Dashboards
|
||||||
|
which do not follow these recommended security settings should
|
||||||
|
be carefully evaluated before restrictions are relaxed.</para>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-cross-site-scripting-xss">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>Cross Site Scripting (XSS)</title>
|
||||||
|
<para>Unlike many similar systems, the OpenStack dashboard allows the
|
||||||
|
entire Unicode character set in most fields. This means
|
||||||
|
developers have less latitude to make escaping mistakes that
|
||||||
|
open attack vectors for cross-site scripting (XSS).</para>
|
||||||
|
<para>Dashboard provides tools for developers to avoid creating
|
||||||
|
XSS vulnerabilities, but they only work if developers use them
|
||||||
|
correctly. Audit any custom dashboards, paying particular
|
||||||
|
attention to use of the <literal>mark_safe</literal> function,
|
||||||
|
use of <literal>is_safe</literal> with
|
||||||
|
custom template tags, the <literal>safe</literal> template tag, anywhere
|
||||||
|
auto escape
|
||||||
|
is turned off, and any JavaScript which might evaluate
|
||||||
|
improperly escaped data.</para>
|
||||||
|
</section>
|
||||||
14
security-guide/section_dashboard-debug.xml
Normal file
14
security-guide/section_dashboard-debug.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-debug">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>Debug</title>
|
||||||
|
<para>We recommend that the <option>DEBUG</option> setting
|
||||||
|
is set to <literal>False</literal> in production environments.
|
||||||
|
If <option>DEBUG</option> is set to True,
|
||||||
|
Django will display stack traces and sensitive web server
|
||||||
|
state information when exceptions are thrown.</para>
|
||||||
|
</section>
|
||||||
37
security-guide/section_dashboard-domain-names.xml
Normal file
37
security-guide/section_dashboard-domain-names.xml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-domain-names">
|
||||||
|
<title>Domain names</title>
|
||||||
|
<para>Many organizations typically deploy web applications at
|
||||||
|
subdomains of an overarching organization domain. It is natural
|
||||||
|
for users to expect a domain of the form
|
||||||
|
<uri>openstack.example.org</uri>. In this context, there are
|
||||||
|
often many other applications deployed in the same second-level
|
||||||
|
namespace, often serving user-controlled content. This name
|
||||||
|
structure is convenient and simplifies name server
|
||||||
|
maintenance.</para>
|
||||||
|
<para>We strongly recommend deploying horizon to a
|
||||||
|
<emphasis>second-level domain</emphasis>, such as
|
||||||
|
<uri>https://example.com</uri>, and advise against deploying
|
||||||
|
horizon on a <emphasis>shared subdomain</emphasis> of any level,
|
||||||
|
for example <uri>https://openstack.example.org</uri> or
|
||||||
|
<uri>https://horizon.openstack.example.org</uri>. We also
|
||||||
|
advise against deploying to bare internal domains like
|
||||||
|
<uri>https://horizon/</uri>. These recommendations are based on the
|
||||||
|
limitations of browser same-origin-policy.</para>
|
||||||
|
<para>Recommendations given in this guide cannot effectively guard against
|
||||||
|
known attacks if you deploy the dashboard in a domain that also hosts
|
||||||
|
user-generated content, even when this content resides on a separate
|
||||||
|
sub-domain. User-generated content can consist of scripts, images, or uploads
|
||||||
|
of any type. Most major web presences, including googleusercontent.com,
|
||||||
|
fbcdn.com, github.io, and twimg.co, use this approach to segregate
|
||||||
|
user-generated content from cookies and security tokens.</para>
|
||||||
|
<para>If you do not follow this recommendation regarding
|
||||||
|
second-level domains, avoid a cookie-backed session store and
|
||||||
|
employ HTTP Strict Transport Security (HSTS). When deployed on
|
||||||
|
a subdomain, the dashboard's security is equivalent to the least secure
|
||||||
|
application deployed on the same second-level domain.</para>
|
||||||
|
</section>
|
||||||
14
security-guide/section_dashboard-front-end-caching.xml
Normal file
14
security-guide/section_dashboard-front-end-caching.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-front-end-caching">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>Front end caching</title>
|
||||||
|
<para>Since the dashboard is rendering dynamic content passed directly
|
||||||
|
from OpenStack API requests, we do not recommend front end
|
||||||
|
caching layers such as varnish. In Django, static media is
|
||||||
|
directly served from Apache or nginx and already benefits from
|
||||||
|
web host caching.</para>
|
||||||
|
</section>
|
||||||
14
security-guide/section_dashboard-horizon-image-upload.xml
Normal file
14
security-guide/section_dashboard-horizon-image-upload.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-horizon-image-upload">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>Horizon image upload</title>
|
||||||
|
<para>We recommend that implementers <link
|
||||||
|
xlink:href="http://docs.openstack.org/developer/horizon/topics/deployment.html#file-uploads"
|
||||||
|
>disable HORIZON_IMAGES_ALLOW_UPLOAD</link> unless they have
|
||||||
|
implemented a plan to prevent resource exhaustion and denial of
|
||||||
|
service.</para>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-http-strict-transport-security-hsts">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>HTTP Strict Transport Security (HSTS)</title>
|
||||||
|
<para>It is highly recommended to use HTTP Strict Transport
|
||||||
|
Security (HSTS).</para>
|
||||||
|
<note>
|
||||||
|
<para>If you are using an HTTPS proxy in front of your web
|
||||||
|
server, rather than using an HTTP server with HTTPS
|
||||||
|
functionality, modify the <literal>SECURE_PROXY_SSL_HEADER</literal>
|
||||||
|
variable. Refer to the <link
|
||||||
|
xlink:href="https://docs.djangoproject.com/"
|
||||||
|
>Django documentation</link> for information about modifying the
|
||||||
|
<literal>SECURE_PROXY_SSL_HEADER</literal> variable.</para>
|
||||||
|
</note>
|
||||||
|
<para>See the chapter on PKI/SSL Everywhere for more specific
|
||||||
|
recommendations and server configurations for HTTPS
|
||||||
|
configurations, including the configuration of HSTS.</para>
|
||||||
|
</section>
|
||||||
18
security-guide/section_dashboard-https.xml
Normal file
18
security-guide/section_dashboard-https.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-https">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>HTTPS</title>
|
||||||
|
<para>
|
||||||
|
Deploy the dashboard behind a secure
|
||||||
|
<glossterm>HTTPS</glossterm> server by using 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.</para>
|
||||||
|
<para>Configure HTTP requests to the dashboard domain to redirect
|
||||||
|
to the fully qualified HTTPS URL.</para>
|
||||||
|
</section>
|
||||||
16
security-guide/section_dashboard-secret-key.xml
Normal file
16
security-guide/section_dashboard-secret-key.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-secret-key">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>Secret key</title>
|
||||||
|
<para>The dashboard depends on a shared <option>SECRET_KEY</option>
|
||||||
|
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 may 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.</para>
|
||||||
|
</section>
|
||||||
30
security-guide/section_dashboard-session-back-end.xml
Normal file
30
security-guide/section_dashboard-session-back-end.xml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-session-back-end">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>Session back end</title>
|
||||||
|
<para>Horizon's default session back end
|
||||||
|
(<literal>django.contrib.sessions.backends.signed_cookies</literal>)
|
||||||
|
stores user data in <emphasis>signed</emphasis> but
|
||||||
|
<emphasis>unencrypted </emphasis>cookies stored in the
|
||||||
|
browser. This approach allows the most simple session back-end
|
||||||
|
scaling since each dashboard instance is stateless, but it comes
|
||||||
|
at the cost of <emphasis>storing sensitive access tokens in the
|
||||||
|
client browser</emphasis> and transmitting them with every
|
||||||
|
request. This back end ensures that session data has not been
|
||||||
|
tampered with, but the data itself is not encrypted other than
|
||||||
|
the encryption provided by HTTPS.</para>
|
||||||
|
<para>If your architecture allows it, we recommend using
|
||||||
|
<literal>django.contrib.sessions.backends.cache</literal> as
|
||||||
|
your session back end with memcache as the cache. Memcache must
|
||||||
|
not be exposed publicly, and should communicate over a secured
|
||||||
|
private channel. If you choose to use the signed cookies
|
||||||
|
back end, refer to the Django documentation understand the
|
||||||
|
security trade-offs.</para>
|
||||||
|
<para>For further details, see the <link
|
||||||
|
xlink:href="https://docs.djangoproject.com/"
|
||||||
|
>Django documentation</link>.</para>
|
||||||
|
</section>
|
||||||
29
security-guide/section_dashboard-static-media.xml
Normal file
29
security-guide/section_dashboard-static-media.xml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-static-media">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>Static media</title>
|
||||||
|
<para>The dashboard's static media should be deployed to a subdomain
|
||||||
|
of the dashboard domain and served by the web server. The use of
|
||||||
|
an external content delivery network (CDN) is also acceptable.
|
||||||
|
This subdomain should not set cookies or serve user-provided
|
||||||
|
content. The media should also be served with HTTPS.</para>
|
||||||
|
<para>Django media settings are documented in the <link
|
||||||
|
xlink:href="https://docs.djangoproject.com/"
|
||||||
|
>Django documentation</link>.</para>
|
||||||
|
<para>Dashboard's default configuration uses <link
|
||||||
|
xlink:href="http://django-compressor.readthedocs.org/"
|
||||||
|
>django_compressor</link> to compress and minify CSS and
|
||||||
|
JavaScript content before serving it. This process should be
|
||||||
|
statically done before deploying the dashboard, rather than using
|
||||||
|
the default in-request dynamic compression and copying the
|
||||||
|
resulting files along with deployed code or to the CDN server.
|
||||||
|
Compression should be done in a non-production build
|
||||||
|
environment. If this is not practical, we recommend disabling
|
||||||
|
resource compression entirely. Online compression dependencies
|
||||||
|
(less, Node.js) should not be installed on production
|
||||||
|
machines.</para>
|
||||||
|
</section>
|
||||||
15
security-guide/section_dashboard-upgrading.xml
Normal file
15
security-guide/section_dashboard-upgrading.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="dashboard-upgrading">
|
||||||
|
<?dbhtml stop-chunking?>
|
||||||
|
<title>Upgrading</title>
|
||||||
|
<para>Django security releases are generally well tested and
|
||||||
|
aggressively backwards compatible. In almost all cases, new
|
||||||
|
major releases of Django are also fully backwards compatible
|
||||||
|
with previous releases. Dashboard implementers are strongly
|
||||||
|
encouraged to run the latest stable release of Django with
|
||||||
|
up-to-date security releases.</para>
|
||||||
|
</section>
|
||||||
Reference in New Issue
Block a user