mirror of
https://github.com/django/django.git
synced 2025-03-03 13:34:26 +00:00
This patch does not remove all occurrences of the words in question. Rather, I went through all of the occurrences of the words listed below, and judged if they a) suggested the reader had some kind of knowledge/experience, and b) if they added anything of value (including tone of voice, etc). I left most of the words alone. I looked at the following words: - simply/simple - easy/easier/easiest - obvious - just - merely - straightforward - ridiculous Thanks to Carlton Gibson for guidance on how to approach this issue, and to Tim Bell for providing the idea. But the enormous lion's share of thanks go to Adam Johnson for his patient and helpful review.
131 lines
4.6 KiB
Plaintext
131 lines
4.6 KiB
Plaintext
========================
|
|
Clickjacking Protection
|
|
========================
|
|
|
|
.. module:: django.middleware.clickjacking
|
|
:synopsis: Protects against Clickjacking
|
|
|
|
The clickjacking middleware and decorators provide easy-to-use protection
|
|
against `clickjacking`_. This type of attack occurs when a malicious site
|
|
tricks a user into clicking on a concealed element of another site which they
|
|
have loaded in a hidden frame or iframe.
|
|
|
|
.. _clickjacking: https://en.wikipedia.org/wiki/Clickjacking
|
|
|
|
An example of clickjacking
|
|
==========================
|
|
|
|
Suppose an online store has a page where a logged in user can click "Buy Now" to
|
|
purchase an item. A user has chosen to stay logged into the store all the time
|
|
for convenience. An attacker site might create an "I Like Ponies" button on one
|
|
of their own pages, and load the store's page in a transparent iframe such that
|
|
the "Buy Now" button is invisibly overlaid on the "I Like Ponies" button. If the
|
|
user visits the attacker's site, clicking "I Like Ponies" will cause an
|
|
inadvertent click on the "Buy Now" button and an unknowing purchase of the item.
|
|
|
|
.. _clickjacking-prevention:
|
|
|
|
Preventing clickjacking
|
|
=======================
|
|
|
|
Modern browsers honor the `X-Frame-Options`_ HTTP header that indicates whether
|
|
or not a resource is allowed to load within a frame or iframe. If the response
|
|
contains the header with a value of ``SAMEORIGIN`` then the browser will only
|
|
load the resource in a frame if the request originated from the same site. If
|
|
the header is set to ``DENY`` then the browser will block the resource from
|
|
loading in a frame no matter which site made the request.
|
|
|
|
.. _X-Frame-Options: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
|
|
|
|
Django provides a few ways to include this header in responses from your site:
|
|
|
|
#. A middleware that sets the header in all responses.
|
|
|
|
#. A set of view decorators that can be used to override the middleware or to
|
|
only set the header for certain views.
|
|
|
|
The ``X-Frame-Options`` HTTP header will only be set by the middleware or view
|
|
decorators if it is not already present in the response.
|
|
|
|
How to use it
|
|
=============
|
|
|
|
Setting ``X-Frame-Options`` for all responses
|
|
---------------------------------------------
|
|
|
|
To set the same ``X-Frame-Options`` value for all responses in your site, put
|
|
``'django.middleware.clickjacking.XFrameOptionsMiddleware'`` to
|
|
:setting:`MIDDLEWARE`::
|
|
|
|
MIDDLEWARE = [
|
|
...
|
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
|
...
|
|
]
|
|
|
|
This middleware is enabled in the settings file generated by
|
|
:djadmin:`startproject`.
|
|
|
|
By default, the middleware will set the ``X-Frame-Options`` header to
|
|
``SAMEORIGIN`` for every outgoing ``HttpResponse``. If you want ``DENY``
|
|
instead, set the :setting:`X_FRAME_OPTIONS` setting::
|
|
|
|
X_FRAME_OPTIONS = 'DENY'
|
|
|
|
When using the middleware there may be some views where you do **not** want the
|
|
``X-Frame-Options`` header set. For those cases, you can use a view decorator
|
|
that tells the middleware not to set the header::
|
|
|
|
from django.http import HttpResponse
|
|
from django.views.decorators.clickjacking import xframe_options_exempt
|
|
|
|
@xframe_options_exempt
|
|
def ok_to_load_in_a_frame(request):
|
|
return HttpResponse("This page is safe to load in a frame on any site.")
|
|
|
|
|
|
Setting ``X-Frame-Options`` per view
|
|
------------------------------------
|
|
|
|
To set the ``X-Frame-Options`` header on a per view basis, Django provides these
|
|
decorators::
|
|
|
|
from django.http import HttpResponse
|
|
from django.views.decorators.clickjacking import xframe_options_deny
|
|
from django.views.decorators.clickjacking import xframe_options_sameorigin
|
|
|
|
@xframe_options_deny
|
|
def view_one(request):
|
|
return HttpResponse("I won't display in any frame!")
|
|
|
|
@xframe_options_sameorigin
|
|
def view_two(request):
|
|
return HttpResponse("Display in a frame if it's from the same origin as me.")
|
|
|
|
Note that you can use the decorators in conjunction with the middleware. Use of
|
|
a decorator overrides the middleware.
|
|
|
|
Limitations
|
|
===========
|
|
|
|
The ``X-Frame-Options`` header will only protect against clickjacking in a
|
|
modern browser. Older browsers will quietly ignore the header and need `other
|
|
clickjacking prevention techniques`_.
|
|
|
|
Browsers that support ``X-Frame-Options``
|
|
-----------------------------------------
|
|
|
|
* Internet Explorer 8+
|
|
* Firefox 3.6.9+
|
|
* Opera 10.5+
|
|
* Safari 4+
|
|
* Chrome 4.1+
|
|
|
|
See also
|
|
--------
|
|
|
|
A `complete list`_ of browsers supporting ``X-Frame-Options``.
|
|
|
|
.. _complete list: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options#Browser_compatibility
|
|
.. _other clickjacking prevention techniques: https://en.wikipedia.org/wiki/Clickjacking#Prevention
|