flask-xsrf 1.0.2
flask extension for defending against cross-site request forgery attacks (xsrf/csrf), by protecting flask endpoints with uniquely generated tokens for each request.
License: MIT

flask-xsrf
----------

`flask <http://flask.pocoo.org>`__ extension for defending against
*cross-site request forgery attacks*
`(xsrf/csrf) <https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)>`__,
by protecting flask request endpoints with uniquely generated tokens for
each request.

+-----------+------------+----------+
| FLASK     | PYTHON     | XSRF     |
+===========+============+==========+
| |flask|   | |python|   | |csrf|   |
+-----------+------------+----------+

**BUILD BADGES**

+---------------+--------------------+---------------------------------------------+
| ``branch``    | ``service``        | ``status``                                  |
+===============+====================+=============================================+
| ``master``    | ``ci-build``       | |travis-ci (build-status): master|          |
+---------------+--------------------+---------------------------------------------+
| ``develop``   | ``ci-build``       | |travis-ci (build-status): develop|         |
+---------------+--------------------+---------------------------------------------+
| ``master``    | ``coveralls.io``   | |coveralls.io (coverage-status): master|    |
+---------------+--------------------+---------------------------------------------+
| ``develop``   | ``coveralls.io``   | |coveralls.io (coverage-status): develop|   |
+---------------+--------------------+---------------------------------------------+
| ``master``    | ``landscape.io``   | |landscape (code-health): master|           |
+---------------+--------------------+---------------------------------------------+
| ``develop``   | ``landscape.io``   | |landscape: (code-health): develop|         |
+---------------+--------------------+---------------------------------------------+

**RELEASE BADGES**

+---------------+------------------------+-----------------------------+
| ``service``   | ``title``              | ``status``                  |
+===============+========================+=============================+
| ``github``    | ``tags``               | |github tags|               |
+---------------+------------------------+-----------------------------+
| ``github``    | ``releases: all``      | |github releases: all|      |
+---------------+------------------------+-----------------------------+
| ``github``    | ``releases: latest``   | |github releases: latest|   |
+---------------+------------------------+-----------------------------+
| ``pypi``      | ``releases: latest``   | |pypi releases: latest|     |
+---------------+------------------------+-----------------------------+
| ``pypi``      | ``downloads``          | |pypi - downloads|          |
+---------------+------------------------+-----------------------------+
| ``pypi``      | ``dl: month``          | |PyPI|                      |
+---------------+------------------------+-----------------------------+
| ``pypi``      | ``dl: week``           | |PyPI|                      |
+---------------+------------------------+-----------------------------+
| ``pypi``      | ``dl: day``            | |PyPI|                      |
+---------------+------------------------+-----------------------------+

**REFERENCE / LINKS**

-  `package (pypi) <http://packages.python.org/flask-xsrf>`__
-  `docs (readthedocs) <https://readthedocs.org/projects/flask-xsrf/>`__
-  `wiki
   (github) <https://github.com/gregorynicholas/flask-xsrf/wiki>`__
-  `source (github) <http://github.com/gregorynicholas/flask-xsrf>`__
-  `releases
   (github) <https://github.com/gregorynicholas/flask-xsrf/releases>`__
-  `changelog
   notes <https://github.com/gregorynicholas/flask-xsrf/blob/master/CHANGES.md>`__
-  `build-status
   (travis-ci) <http://travis-ci.org/gregorynicholas/flask-xsrf>`__
-  `coverage-status
   (coveralls) <https://coveralls.io/github/gregorynicholas/flask-xsrf>`__
-  `contributing
   notes <http://github.com/gregorynicholas/flask-xsrf/wiki>`__
-  `issues
   (github) <https://github.com/gregorynicholas/flask-xsrf/issues>`__

HOW IT WORKS
~~~~~~~~~~~~

-  

**FEATURES**

-  **timeout** - optionally, you can specify a default time window for
   valid tokens

USAGE
~~~~~

**REQUIREMENTS**

+--------------+---------------+
| python       | flask         |
+==============+===============+
| ``2.7.6+``   | ``0.11.0+``   |
+--------------+---------------+

**INSTALLATION**

install with pip (usually recommended to specify a specific version):

.. code:: sh

    $ pip install flask-xsrf
    $ pip install flask-xsrf==1.0.3

**IMPLEMENTATION**

implementation of the library with your flask app breaks down into four
steps.

1: add a ``secret_key`` to your flask app config object:

.. code:: py

    from flask import Flask

    flask_app = Flask(__name__)
    flask_app.secret_key = '<:session_secret_key>'
    flask_app.config['session_cookie_secure'] = True
    flask_app.config['remember_cookie_name'] = 'testdomain.com'
    flask_app.config['remember_cookie_duration_in_days'] = 1

2: create an instance of an ``XSRFTokenHandler`` object, and specify a
method/callable which will be used as a getter by the token handler to
get a ``user_id``. optionally, you can assign auto-generated id's for
anonymous requests. lastly, you may specify a default ``timeout``, in
number of seconds, to expire tokens after a specific the amount of time:

.. code:: py

    from flask import Response
    from flask import session
    import flask_xsrf as xsrf

    @flask_app.before_request
    def before_request():
      if 'user_id' not in session:
        session['user_id'] = 'random_generated_anonymous_id'

    def get_user_id():
      return session.get('user_id')

    xsrf_handler = xsrf.XSRFTokenHandler(
      user_fn=get_user_id, secret='xsrf_secret', timeout=3600)

*NOTE: currently, usage of the ``session`` is required (`see TODO notes
below <#todo>`__).*

3: decorate ``GET`` request-handlers to send a generated token:

.. code:: py

    @flask_app.route('/test', methods=['GET'])
    @xsrf_handler.send_token()
    def test_get():
      return Response('success')

4: decorate ``POST`` request-handlers to receive, validate sent tokens:

.. code:: py

    @flask_app.route('/test', methods=['POST'])
    @xsrf_handler.handle_token()
    def test_post():
      return Response('success')

 ##### TO SUMMARIZE

that's all there is to it. please feel free to contact me
gn@gregorynicholas.com or to `submit an issue on
github <https://github.com/gregorynicholas/flask-xsrf/issues>`__ for any
questions or help. however, creating a fork and submitting pull-requests
are much preferred. contributions will be very much appreciated.

CONTRIBUTING
~~~~~~~~~~~~

**STAR, FORK THIS PROJECT**

+--------------------+--------------------+
| ``github forks``   | ``github stars``   |
+====================+====================+
| |github forks|     | |github stars|     |
+--------------------+--------------------+

TODOs
^^^^^

-  add feature: enable checking of referer headers / client ip-address
-  remove hard-coded dependency / usage of ``session``.
-  add feature: enable storage of tokens in cookie.

   -  this might help ease implementation, as the client would not have
      to manually manage passing of tokens to server.

.. |flask| image:: https://cloud.githubusercontent.com/assets/407650/15803510/2d4f594a-2a96-11e6-86e0-802592e17aca.png
   :target: http://flask.pocoo.org
.. |python| image:: https://cloud.githubusercontent.com/assets/407650/15803508/24d88944-2a96-11e6-9912-c696d9fc3912.png
   :target: http://www.python.org
.. |csrf| image:: https://cloud.githubusercontent.com/assets/407650/15803506/1c76e002-2a96-11e6-881e-969ef407839a.png
   :target: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
.. |travis-ci (build-status): master| image:: https://secure.travis-ci.org/gregorynicholas/flask-xsrf.svg?branch=master
   :target: https://travis-ci.org/gregorynicholas/flask-xsrf/builds
.. |travis-ci (build-status): develop| image:: https://secure.travis-ci.org/gregorynicholas/flask-xsrf.svg?branch=develop
   :target: https://travis-ci.org/gregorynicholas/flask-xsrf/builds
.. |coveralls.io (coverage-status): master| image:: https://coveralls.io/repos/github/gregorynicholas/flask-xsrf/badge.svg?branch=master
   :target: https://coveralls.io/github/gregorynicholas/flask-xsrf?branch=master
.. |coveralls.io (coverage-status): develop| image:: https://coveralls.io/repos/github/gregorynicholas/flask-xsrf/badge.svg?branch=develop
   :target: https://coveralls.io/github/gregorynicholas/flask-xsrf?branch=develop
.. |landscape (code-health): master| image:: https://landscape.io/github/gregorynicholas/flask-xsrf/master/landscape.svg?style=flat-square
   :target: https://landscape.io/github/gregorynicholas/flask-xsrf/master
.. |landscape: (code-health): develop| image:: https://landscape.io/github/gregorynicholas/flask-xsrf/develop/landscape.svg?style=flat-square
   :target: https://landscape.io/github/gregorynicholas/flask-xsrf/develop
.. |github tags| image:: https://img.shields.io/github/tag/gregorynicholas/flask-xsrf.svg?maxAge=2592000?style=flat-square
   :target: https://github.com/gregorynicholas/flask-xsrf/tags
.. |github releases: all| image:: https://img.shields.io/github/downloads/atom/atom/total.svg?maxAge=2592000?style=flat-square
   :target: https://github.com/gregorynicholas/flask-xsrf/releases
.. |github releases: latest| image:: https://img.shields.io/github/downloads/gregorynicholas/flask-xsrf/1.0.2/total.svg?maxAge=2592000?style=flat-square
   :target: https://github.com/gregorynicholas/flask-xsrf/releases/latest
.. |pypi releases: latest| image:: https://img.shields.io/pypi/v/flask-xsrf.svg
   :target: https://pypi.python.org/pypi/flask-xsrf
.. |pypi - downloads| image:: https://img.shields.io/pypi/dm/flask-xsrf.svg
   :target: https://pypi.python.org/pypi/flask-xsrf
.. |PyPI| image:: https://img.shields.io/pypi/dm/Django.svg?maxAge=2592000?style=flat-square
   :target: https://github.com/gregorynicholas/flask-xsrf
.. |PyPI| image:: https://img.shields.io/pypi/dw/Django.svg?maxAge=2592000?style=flat-square
   :target: https://github.com/gregorynicholas/flask-xsrf
.. |PyPI| image:: https://img.shields.io/pypi/dd/Django.svg?maxAge=2592000?style=flat-square
   :target: https://github.com/gregorynicholas/flask-xsrf
.. |github forks| image:: https://img.shields.io/github/forks/gregorynicholas/flask-xsrf.svg?style=social&label=Fork&maxAge=2592000?style=flat-square
   :target: https://github.com/gregorynicholas/flask-xsrf/fork
.. |github stars| image:: https://img.shields.io/github/stars/gregorynicholas/flask-xsrf.svg?style=social&label=Star&maxAge=2592000?style=flat-square
   :target: https://github.com/gregorynicholas/flask-xsrf/stargazers