symfony/symfony — pull request #8515 by ebihara (2013-07-18 16:03:48+00:00)
Title: [HttpFoundation] [FrameworkBundle] Introduce Rails-like default response headers to control browser-side security features

Rails 4 provides new `default_headers` to send some security headers by default. Such headers control browser-side security features.

It is also good for Symfony because it provides transparent security to users like output escaping and CSRF protection.

| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | not yet

TODO
----

- [ ] submit changes to the documentation
- [ ] gather feedback for my changes

(NOTE: adding this feature is finished, I think, but we should consider about default configurations as I discuss later)

Security headers?
-----------------

Modern web browsers provide some security features (to mitigate effects of frequent vulnerabilities, or to avoid new attack methods e.g. Clickjacking). To use them, setting via response headers like the followings:

- [X-Content-Type-Options]: disable [MIME-sniffing], sometimes this feature brings some vulnerabilities like XSS, and make refer the response as a certain MIME type specified in the Content-Type header
- [X-XSS-Protection]: control browser-side XSS filter mode (disable / stop-rendering if attack detected (default) / block-rendering if attack detected)
- [X-Frame-Options]: deny rendering within a frame to prevent from [Clickjacking]
- [Content-Security-Policy, X-Content-Security-Policy, X-WebKit-CSP]: configure Content Security Policy to add some restriction (e.g. deny inline JavaScript)
- [Strict-Transport-Security]: enables HTTP-Strict-Transport-Security (HSTS) to indicate "always load via HTTPS" message to the browser
- [X-UA-Compatible]: force rendering mode in IE
- [Access-Control-Allow-Origin]: change [Same-Origin Policy (SOP)] restriction to enable [Cross-Origin Resource Sharing (CROS)]

About browser support situations, you can get information from http://www.browserscope.org/?category=security

[X-Content-Type-Options]: http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx
[MIME-sniffing]: http://mimesniff.spec.whatwg.org/
[X-XSS-Protection]: http://blogs.msdn.com/b/ie/archive/2008/07/02/ie8-security-part-iv-the-xss-filter.aspx
[X-Frame-Options]: http://tools.ietf.org/html/draft-ietf-websec-x-frame-options-00
[Clickjacking]: https://www.owasp.org/index.php/Clickjacking
[Content-Security-Policy, X-Content-Security-Policy, X-WebKit-CSP]: https://www.owasp.org/index.php/Content_Security_Policy
[Strict-Transport-Security]: http://tools.ietf.org/html/rfc6797
[X-UA-Compatible]: http://msdn.microsoft.com/en-us//library/cc288325%28v=vs.85%29.aspx
[Access-Control-Allow-Origin]: https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
[Same-Origin Policy (SOP)]: http://tools.ietf.org/html/rfc6454
[Cross-Origin Resource Sharing (CROS)]: http://www.w3.org/TR/cors/

Configuration
-------------

User can configure default response header like the following:

```
framework:
response:
default_headers:
"X-Content-Type-Options": "nosniff"
"X-XSS-Protection": "1; mode=block"
"X-Frame-Options": "SAMEORIGIN"
"X-Foo": "Bar"
```

Default Configuration
---------------------

I think about the default configuration is very important and we need to discuss since it may affect existing projects. (Currently, only `X-Content-Type-Options: sniff` is defined as default header)

`X-Content-Type-Options: sniff` is almost essential because Symfony always sends a valid Content-Type so it keeps current behaviours.

And also `X-XSS-Protection: 1; mode=block` does not break anything, but in false-negative situation, the end-user will see a white-screen-of-death (by block-mode of XSS filter) instead of corrupt HTML string (by default-mode).

`X-Frame-Options` is the missing protection against Clickjacking but it damages iframe-embed page so we cannot adopt this as default but we should recommend use this.

Content Security Policy is a very powerful feature but it might be difficult for many users to control.

A preferred value of`Strict-Transport-Security`, `X-UA-Compatible` and `Access-Control-Allow-Origin` cannot be decided without user's judgment.

FYI, here is the default configuration of Rails 4:

```
config.action_dispatch.default_headers = {
'X-Frame-Options' => 'SAMEORIGIN',
'X-XSS-Protection' => '1; mode=block',
'X-Content-Type-Options' => 'nosniff'
}
```

References
----------

- https://github.com/rails/rails/pull/7302 (Rails discussion)
- https://www.owasp.org/index.php/List_of_useful_HTTP_headers
- http://recxltd.blogspot.com/2012/03/seven-web-server-http-headers-that.html
- http://homakov.blogspot.com/2012/06/saferweb-with-new-features-come-new.html