public function onRespond(FilterResponseEvent $event) {
								$response = $event->getResponse();
								// ...
								// Prevent browsers from sniffing a response and picking a MIME type
								// different from the declared content-type, since that can lead to
								// XSS and other vulnerabilities.
								// https://www.owasp.org/index.php/List_of_useful_HTTP_headers
								$response->headers->set('X-Content-Type-Options', 'nosniff', FALSE);
								// ...
							}
						
							# Various header fixes.
							<IfModule mod_headers.c>
								# Disable content sniffing, since it's an attack vector.
								Header always set X-Content-Type-Options nosniff
								# Disable Proxy header, since it's an attack vector.
								RequestHeader unset Proxy
							</IfModule>
						
							public function onRespond(FilterResponseEvent $event) {
								$response = $event->getResponse();
								// ...
								$response->headers->set('X-Frame-Options', 'SAMEORIGIN', FALSE);
								// ...
							}
						| Source | Destination | Referrer | 
|---|---|---|
| https://example.com/page-one | https://example.com/page-two | https://example.com/page-one | 
| https://example.com/page-one | https://google.com/ | https://example.com | 
| https://example.com/page-one | http://example.com/page-two | NULL | 
| https://example.com/page-one | http://google.com/ | NULL | 
							services:
								my_module.response_listener:
									class: Drupal\my_module\EventSubscriber\ResponseSubscriber
									arguments: ['@config.factory']
									tags:
										- { name: event_subscriber }
						
							namespace Drupal\my_module\EventSubscriber;
							use Symfony\Component\EventDispatcher\EventSubscriberInterface;
							use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
							class ResponseSubscriber implements EventSubscriberInterface {
								public static function getSubscribedEvents() {
									$events[KernelEvents::RESPONSE] = ['onKernelResponse'];
									return $events;
								}
								public function onKernelResponse(FilterResponseEvent $event) {
									if (!$event->isMasterRequest()) {
										return;
									}
									$response = $event->getResponse();
									$response->headers->set('HeaderName', 'header-value');
								}
							}
						
							SSLEngine On
							SSLCertificateFile    example.crt
							SSLCertificateKeyFile example.key
							# Set HSTS header for six months
							<IfModule mod_headers.c>
									Header always set Strict-Transport-Security "max-age=15552000"
							</IfModule>
						
Fascinating thread from a leader in HTTPS ecosystem — providing HPKP capability to unvetted web developers was a mistake, in retrospect. https://t.co/qUjaXym7uT
— SwiftOnSecurity (@SwiftOnSecurity) 24 Aug 2017

tl;dr the people who standardized HPKP say don't use it, it sounds like a cool hedge, but the risk incredible long-term for theoretical gain
— SwiftOnSecurity (@SwiftOnSecurity) 24 Aug 2017

But pinning is terrible - and harms the ecosystem more than helps, as we've seen. It was a bad thing to standardize 😔
— Ryan Sleevi (@sleevi_) 24 Aug 2017

Interesting. I should buy you some scotch so I can learn more.
— Mark Nottingham (@mnot) 24 Aug 2017

No scotch needed to get me to apologize for my sins and the painful lessons learned. I actively discourage it now, even w/ ecosystem risk
— Ryan Sleevi (@sleevi_) 24 Aug 2017

But pinning your own key is a still a footgun. I know of several who pinned to keys they couldn't legit get certs for when needed
— Ryan Sleevi (@sleevi_) 24 Aug 2017
 
					 
					
							Content-Security-Policy:
								default-src 'self';
								script-src 'self' 'unsafe-inline' code.jquery.com www.google.com www.google-analytics.com;
								style-src 'self' 'unsafe-inline' netdna.bootstrapcdn.com www.google.com ajax.googleapis.com;
								img-src 'self' s3.amazonaws.com www.google-analytics.com stats.g.doubleclick.net;
								connect-src 'self' www.drupal.org www.google-analytics.com;
								report-uri https://gapple.report-uri.io/r/default/csp/enforce;
						
							Content-Security-Policy:
								default-src *;
								script-src * 'unsafe-inline';
								style-src * 'unsafe-inline';
								report-uri https://gapple.report-uri.io/r/default/csp/enforce;
							Content-Security-Policy-Report-Only:
								default-src 'self';
								report-uri https://gapple.report-uri.io/r/default/csp/reportOnly;
						
								Content-Security-Policy:
									default-src 'self';
									script-src assets.example.com;
									style-src assets.example.com;
									img-src assets.example.com files.example.com;
									connect-src 'self';
							
								testlib:
									version: "1.x"
									css:
										theme:
											https://example.com/css/testlib.css: {}
									js:
										http://example.com/js/testlib.js: {}
							
							<!-- Google Analytics -->
							<script>
								(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
									(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
										m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
								})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
			
								ga('create', 'UA-XXXXX-Y', 'auto');
								ga('send', 'pageview');
							</script>
							<!-- End Google Analytics -->
							
							<!-- Google Analytics -->
							<script>
								window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
								ga('create', 'UA-XXXXX-Y', 'auto');
								ga('send', 'pageview');
							</script>
							<script async src='https://www.google-analytics.com/analytics.js'></script>
							<!-- End Google Analytics -->
						
							Locate this session at the DrupalCon Vienna website
							https://events.drupal.org/vienna2017/sessions/using-your-headers-better-security
						
							Take the survey!
							https://www.surveymonkey.com/r/drupalconvienna