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 | ||||
|       xlink:href="http://docs.openstack.org/developer/horizon/topics/deployment.html" | ||||
|       >deployment and configuration documentation</link>.</para> | ||||
|   <section xml:id="dashboard-basic-web-server-configuration"> | ||||
|     <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> | ||||
|   <section xml:id="dashboard-https"> | ||||
|     <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> | ||||
|   <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> | ||||
|   <xi:include href="section_dashboard-basic-web-server-configuration.xml"/> | ||||
|   <xi:include href="section_dashboard-https.xml"/> | ||||
|   <xi:include href="section_dashboard-http-strict-transport-security-hsts.xml"/> | ||||
|   <xi:include href="section_dashboard-front-end-caching.xml"/> | ||||
|   <xi:include href="section_dashboard-domain-names.xml"/> | ||||
|   <xi:include href="section_dashboard-static-media.xml"/> | ||||
|   <xi:include href="section_dashboard-secret-key.xml"/> | ||||
|   <xi:include href="section_dashboard-session-back-end.xml"/> | ||||
|   <xi:include href="section_dashboard-allowed-hosts.xml"/> | ||||
|   <xi:include href="section_dashboard-cross-site-request-forgery-csrf.xml"/> | ||||
|   <xi:include href="section_dashboard-cookies.xml"/> | ||||
|   <xi:include href="section_dashboard-cross-site-scripting-xss.xml"/> | ||||
|   <xi:include href="section_dashboard-cross-origin-resource-sharing-cors.xml"/> | ||||
|   <xi:include href="section_dashboard-horizon-image-upload.xml"/> | ||||
|   <xi:include href="section_dashboard-upgrading.xml"/> | ||||
|   <xi:include href="section_dashboard-debug.xml"/> | ||||
| </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