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
	 Emett Speer
					Emett Speer