Skip to content

[HttpKernel] [FrameworkBundle] Introduce Rails-like default response headers to control browser-side security features #8515

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

co3k
Copy link
Contributor

@co3k co3k commented Jul 18, 2013

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:

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

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 ofStrict-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

@co3k
Copy link
Contributor Author

co3k commented Jul 18, 2013

Additional informations:

I strongly think we should add X-Content-Type-Options: nosniff in default, otherwise we will get headache by browser-fault vulnerabilities which is caused by inappropriate MIME-sniffing.

I know good (bad?) example about such a vulnerability, the CVE-2013-1297, is NOT fixed in IE9 and IE10. (In IE6, IE7 and IE8, this vuln has been fixed by MS13-037)

The reporter, Yousuke Hasegawa, says "In Internet Explorer 9 and 10, attacker can read remote JSON array yet." in his blog entry (sadly there are no English informations).

This attack is that the vulnerable IE reads remote JSON content as VBScript by using <script src="..." language="vbscript">...</script> so this problem is avoidable by using X-Content-Type-Options (disable MIME-sniffing).

And according to Hasegawa, "About IE9 and IE10 needs X-Content-Type-Options to avoid this problem, Microsoft says this behavior is based on its specification."

I think CVE-2013-1297 itself is not really big problem, in my opinion, a truly big problem is Microsoft looks like standing "the response with a valid Content-Type, as a matter of course, it must send X-Content-Type-Options too"... If so, bad, this is bad, but this problem is really exist, so adding X-Content-Type-Options is -- our duty :(

Nonetheless, for the good web frameworks or applications like symfony, there is no reason for relying MIME-type sniffing because they always send a valid Content-Type.

@lsmith77
Copy link
Contributor

@Seldaek you probably have some comments on this.

@@ -42,6 +45,9 @@ public function onKernelResponse(FilterResponseEvent $event)
}

$response = $event->getResponse();
foreach ($this->defaultHeaders as $key => $value) {
$response->headers->set($key, $value, false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will replace any custom header set in the controller.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, this method call sets false as the third argument ($replace), and it is already tested the existing header wouldn't be overwritten.

@stof
Copy link
Member

stof commented Jul 18, 2013

NelmioSecurityBundle already allows setting these security headers for you, and it provides a semantic configuration instead of asking the developer to know the exact syntax of each header in the config file.

and for the CORS header, NelmioCorsBundle allows configuring it fully (which cannot be done by hardcoding some header values in the config file).

Thus, your default config for X-Content-Type-Options: nosniff is missleading: if the user configures a different header, it will not be set anymore as the headers will be set in the config so the default value is not used anymore.

@co3k
Copy link
Contributor Author

co3k commented Jul 18, 2013

Oh I didn't know about the NelmioSecurityBundle bundle. It seems better than my implementation (give the code a once-over), but it doesn't provide X-Content-Type-Options yet.

Adding some supports for X-Content-Type-Options and if any to the NelmioSecurityBundle and we recommend use this might be well? But I hope making the situation that many users benefit from these headers by default without knowing details of the headers, because it is not knowledge requirement of every web-programmer (in ideal).

My default header config misleading. You're right. But it is difficult problem because this configuration shouldn't overwrite user defined headers, of course...

@Seldaek
Copy link
Member

Seldaek commented Jul 25, 2013

@ebihara there is a PR open on NelmioSecurityBundle for CSP support, which one merged will make the bundle cover most things you mentionned here. As for X-Content-Type-Options, I wouldn't be against a pull request to add it to the bundle as well. I don't know if this really belongs in the framework itself because having smart defaults that fit everyone is a bit hard. It's good to make it easy to enable these features, but I don't necessarily agree that forcing them on everyone is a good thing.

@fabpot
Copy link
Member

fabpot commented Jul 25, 2013

As there is already a good bundle that covers most of these things and because @Seldaek is fine with adding some missing stuf, I'm closing this PR in favor of improving the bundle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants