Opened 6 years ago

Closed 5 years ago

Last modified 3 years ago

#30426 closed New feature (fixed)

Make security headers default.

Reported by: Adam Johnson Owned by: Adam Johnson
Component: Core (Other) Version: dev
Severity: Normal Keywords:
Cc: Florian Apolloner Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Adam Johnson)

Following my security headers talk at DjangoCon Europe and its related blog post ( https://adamj.eu/tech/2019/04/10/how-to-score-a+-for-security-headers-on-your-django-website/ ), I'd like to make Django use more of these security headers by default on new projects. They're always harder to roll out on existing projects than to just bake in to the new project template.

On current master, running python manage.py check --deploy on a fresh project created with startproject yields these warnings:

System check identified some issues:

WARNINGS:
?: (security.W004) You have not set a value for the SECURE_HSTS_SECONDS setting. If your entire site is served only over SSL, you may want to consider setting a value and enabling HTTP Strict Transport Security. Be sure to read the documentation first; enabling HSTS carelessly can cause serious, irreversible problems.
?: (security.W006) Your SECURE_CONTENT_TYPE_NOSNIFF setting is not set to True, so your pages will not be served with an 'X-Content-Type-Options: nosniff' header. You should consider enabling this header to prevent the browser from identifying content types incorrectly.
?: (security.W007) Your SECURE_BROWSER_XSS_FILTER setting is not set to True, so your pages will not be served with an 'X-XSS-Protection: 1; mode=block' header. You should consider enabling this header to activate the browser's XSS filtering and help prevent XSS attacks.
?: (security.W008) Your SECURE_SSL_REDIRECT setting is not set to True. Unless your site should be available over both SSL and non-SSL connections, you may want to either set this setting True or configure a load balancer or reverse-proxy server to redirect all connections to HTTPS.
?: (security.W012) SESSION_COOKIE_SECURE is not set to True. Using a secure-only session cookie makes it more difficult for network traffic sniffers to hijack user sessions.
?: (security.W016) You have 'django.middleware.csrf.CsrfViewMiddleware' in your MIDDLEWARE, but you have not set CSRF_COOKIE_SECURE to True. Using a secure-only CSRF cookie makes it more difficult for network traffic sniffers to steal the CSRF token.
?: (security.W018) You should not have DEBUG set to True in deployment.
?: (security.W019) You have 'django.middleware.clickjacking.XFrameOptionsMiddleware' in your MIDDLEWARE, but X_FRAME_OPTIONS is not set to 'DENY'. The default is 'SAMEORIGIN', but unless there is a good reason for your site to serve other parts of itself in a frame, you should change it to 'DENY'.
?: (security.W020) ALLOWED_HOSTS must not be empty in deployment.

System check identified 9 issues (0 silenced).

Three of these come from security headers that we could activate by default in the settings SECURE_CONTENT_TYPE_NOSNIFF, SECURE_BROWSER_XSS_FILTER, and X_FRAME_OPTIONS.

I'd like to propose making them default in the startproject settings and even changing their global defaults (through a deprecation period) so they are activated by default.

Change History (23)

comment:1 by Adam Johnson, 6 years ago

Description: modified (diff)

comment:2 by Adam Johnson, 6 years ago

Has patch: set
Owner: changed from nobody to Adam Johnson
Status: newassigned

comment:3 by Carlton Gibson, 6 years ago

Triage Stage: UnreviewedAccepted

Hi Adam.

I see no problem with changing the template.

Maybe people will have comments on changing the defaults. (But let's put that to the test.)

Thanks.

comment:4 by Claude Paroz, 6 years ago

Could you just sum up what would be the possible downside of this?

comment:5 by Adam Johnson, 6 years ago

I don't think there are many downsides to changing the template. We already ask developers to learn about these flags before production in manage.py check --deploy, so having them visible and on by default pushes this earlier in development and reduces the risk of writing incompatible, less secure code to begin with, on new projects.

Changing the defaults via the deprecation timeline risks breaking sites (sometimes subtly) for each of these headers, since they disable some (bad) browser behaviour. We can probably force users to explicitly set the flags in their settings file in the version before the default is switched. I think there's a precedent but can't remember which setting.

comment:6 by Claude Paroz, 6 years ago

If this is only breaking sites in case of "bad" behavior, I guess we can live with a backwards incompatibility note in the release notes.

in reply to:  6 comment:7 by Florian Apolloner, 6 years ago

Replying to Claude Paroz:

If this is only breaking sites in case of "bad" behavior, I guess we can live with a backwards incompatibility note in the release notes.

It's not even technically backwards incompatible since you only get those settings when creating a new project, Adam did not set it in the global defaults.

comment:8 by Florian Apolloner, 6 years ago

Cc: Florian Apolloner added

comment:9 by Claude Paroz, 6 years ago

I was referring to the last sentence of the ticket description:

and even changing their global defaults (through a deprecation period) so they are activated by default.

If they are safe defaults, I would be in favor of changing the global defaults for these settings. I think we generally strive to make the project settings template as short as possible.

comment:10 by Mariusz Felisiak, 5 years ago

Needs documentation: set
Patch needs improvement: set
Summary: Make security headers defaultMake security headers default.
Version: 2.2master

I agree that we can change global default values for these 3 settings (release notes and changes in docs are required).

PR

comment:11 by Claude Paroz, 5 years ago

Any rationale about adding the defaults to the project template instead of changing the default values. I think release notes could warn about the changed defaults.

comment:12 by Florian Apolloner, 5 years ago

Simply because it is not backwards compatible.

comment:13 by Claude Paroz, 5 years ago

Of course, but it's not like we never made incompatible changes :-) (with proper release notes).
I think that so-called "safe defaults" belong to the global settings file. I vote for keeping the project settings file as slim as possible by default. But I can understand other opinions too, for sure.

comment:14 by Florian Apolloner, 5 years ago

Sure and I am fully in favor of making them a global default, I am just not sure if we can argue it given our policies… So if you all think that we should do it, I am +1 (with a rather prominent note in the release notes). That said I think only the X_FRAME_OPTIONS change would be relevant at all because I cannot imagine how one would rely on the behavior of the others to do something useful :)

Version 0, edited 5 years ago by Florian Apolloner (next)

comment:15 by Ran Benita, 5 years ago

From a recent blog post by Adam, and the linked blog and further links down it sounds like the X-Xss-Protection header is deprecated or removed in modern browsers, and maybe even harmful. So maybe this one should not be enabled by default, and maybe even the security.W007 check should be removed?

comment:16 by Adam Johnson, 5 years ago

Yes Ran - hadn't quite thought that through yet. I made a new ticket #30680 to deal with that, left open for discussion right now.

comment:17 by Mariusz Felisiak <felisiak.mariusz@…>, 5 years ago

In 04681597:

Refs #30426 -- Changed default SECURE_CONTENT_TYPE_NOSNIFF to True.

comment:18 by Claude Paroz, 5 years ago

Looks like the remaining question is about X_FRAME_OPTIONS:

  • Make it DENY by default in global settings with a backwards incompatibility note in release notes
  • Make it DENY in the default project settings template (better for compatibility, but clutters the project settings file and doesn't do anything for existing projects)

comment:19 by Adam Johnson, 5 years ago

It seems the consensus is to make it DENY by default with a warning - any objections?

comment:20 by Claude Paroz, 5 years ago

Needs documentation: unset
Patch needs improvement: unset

The PR to set DENY by default.

comment:21 by Mariusz Felisiak <felisiak.mariusz@…>, 5 years ago

Resolution: fixed
Status: assignedclosed

In 05d0eca6:

Fixed #30426 -- Changed X_FRAME_OPTIONS setting default to DENY.

comment:22 by Carlton Gibson <carlton.gibson@…>, 5 years ago

In 1edbb6c1:

Refs #30426 -- Moved release notes into separate security section.

comment:23 by GitHub <noreply@…>, 3 years ago

In f0ba799e:

Refs #30426 -- Updated XFrameOptionsMiddleware docstring.

Follow up to 05d0eca635853564c57e639ac5590674a7de2ed6.

Note: See TracTickets for help on using tickets.
Back to Top