123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- ========================
- 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
- ``DENY`` for every outgoing ``HttpResponse``. If you want any other value for
- this header instead, set the :setting:`X_FRAME_OPTIONS` setting::
- X_FRAME_OPTIONS = "SAMEORIGIN"
- 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.")
- .. note::
- If you want to submit a form or access a session cookie within a frame or
- iframe, you may need to modify the :setting:`CSRF_COOKIE_SAMESITE` or
- :setting:`SESSION_COOKIE_SAMESITE` settings.
- 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
- `modern browsers`_.
- .. _modern browsers: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options#browser_compatibility
|