Permalink
Browse files

Added docs.

  • Loading branch information...
1 parent 0039217 commit 4821a04cbfc2a5ef21469c064b09a81f595ef908 @carljm committed May 30, 2011
Showing with 920 additions and 11 deletions.
  1. +1 −0 .gitignore
  2. +3 −0 AUTHORS.rst
  3. +2 −0 MANIFEST.in
  4. +25 −6 README.rst
  5. +0 −4 TODO.rst
  6. +130 −0 doc/Makefile
  7. +1 −0 doc/changelog.rst
  8. +129 −0 doc/checksecure.rst
  9. +225 −0 doc/conf.py
  10. +1 −0 doc/credits.rst
  11. +24 −0 doc/index.rst
  12. +170 −0 doc/make.bat
  13. +98 −0 doc/middleware.rst
  14. +10 −0 doc/philosophy.rst
  15. +99 −0 doc/settings.rst
  16. +1 −0 doc/todo.rst
  17. +1 −1 setup.py
View
@@ -2,3 +2,4 @@
htmlcov/
*.egg
django_secure*.egg-info
+doc/_build/
View
@@ -1 +1,4 @@
+Contributors
+============
+
Carl Meyer <carl@oddbird.net>
View
@@ -3,3 +3,5 @@ include CHANGES.rst
include LICENSE.txt
include README.rst
include TODO.rst
+recursive-include doc *.rst *.py *.bat
+include doc/Makefile
View
@@ -2,8 +2,14 @@
django-secure
=============
-Utilities for running a secure Django site (where all URLs in the site should
-be accessed over an HTTPS connection).
+Helping you remember to do the stupid little things to improve your Django
+site's security.
+
+Inspired by Mozilla's `Secure Coding Guidelines`_, and intended for sites that
+are entirely or mostly served over SSL (which should include anything with
+user logins).
+
+.. _Secure Coding Guidelines: https://wiki.mozilla.org/WebAppSec/Secure_Coding_Guidelines
Quickstart
==========
@@ -39,11 +45,14 @@ Usage
``MIDDLEWARE_CLASSES`` setting (where depends on your other middlewares, but
near the beginning of the list is probably a good choice).
-* Set the ``SECURE_SSL_REDIRECT`` setting to True if all non-SSL requests
+* Set the ``SECURE_SSL_REDIRECT`` setting to ``True`` if all non-SSL requests
should be permanently redirected to SSL.
-* Set the ``SECURE_STS_SECONDS`` setting to an integer number of seconds, if
- you want to use `Strict Transport Security`_.
+* Set the ``SECURE_HSTS_SECONDS`` setting to an integer number of seconds, if
+ you want to use `HTTP Strict Transport Security`_.
+
+* Set the ``SECURE_FRAME_DENY`` setting to ``True``, if you want to prevent
+ framing of your pages and protect them from `clickjacking`_.
* Set ``SESSION_COOKIE_SECURE`` and ``SESSION_COOKIE_HTTPONLY`` to ``True`` if
you are using ``django.contrib.sessions``. These settings are not part of
@@ -53,7 +62,17 @@ Usage
* Run ``python manage.py checksecure`` to verify that your settings are
properly configured for serving a secure SSL site.
-.. _Strict Transport Security: http://en.wikipedia.org/wiki/Strict_Transport_Security
+.. _HTTP Strict Transport Security: http://en.wikipedia.org/wiki/Strict_Transport_Security
+
+.. _clickjacking: http://www.sectheory.com/clickjacking.htm
+
+.. warning::
+ If ``checksecure`` gives you the all-clear, all it means is that you're now
+ taking advantage of a tiny selection of simple and easy security
+ wins. That's great, but it doesn't mean your site or your codebase is
+ secure: only a competent security audit can tell you that.
+
+.. end-here
Documentation
-------------
View
@@ -1,6 +1,2 @@
TODO
====
-
-* checksecure management command (SESSION_COOKIE_SECURE,
- SESSION_COOKIE_HTTPONLY, SECURE_STS_SECONDS, SECURE_SSL_REDIRECT,
- SECURE_FRAME_DENY, SecurityMiddleware)
View
@@ -0,0 +1,130 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-secure.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-secure.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/django-secure"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-secure"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ make -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
View
@@ -0,0 +1 @@
+.. include:: ../CHANGES.rst
View
@@ -0,0 +1,129 @@
+The ``checksecure`` management command
+======================================
+
+The ``checksecure`` management command is a "linter" for simple improvements
+you could make to your site's security configuration. It just runs a list of
+check functions. Each check function can return a set of warnings, or the
+empty set if it finds nothing to warn about.
+
+.. contents:: :local:
+
+When to run it
+--------------
+
+You can run it in your local development checkout. Your local dev settings
+module may not be configured for SSL, so you may want to point it at a
+different settings module, either by setting the ``DJANGO_SETTINGS_MODULE``
+environment variable, or by passing the ``--settings`` option::
+
+ django-admin.py checksecure --settings=production_settings
+
+Or you could run it directly on a production or staging deployment to verify that the correct settings are in use.
+
+You could even make it part of your integration test suite, if you want. The
+:py:func:`djangosecure.check.run_checks` function runs all configured checks
+and returns the complete set of warnings; you could write a simple test that
+asserts that the returned value is empty.
+
+.. _built-in-checks:
+
+Built-in checks
+---------------
+
+The following check functions are built-in to django-secure, and will run by
+default
+
+.. py:currentmodule:: djangosecure.check.djangosecure
+
+.. py:function:: check_security_middleware
+
+ Warns if :doc:`middleware` is not in your ``MIDDLEWARE_CLASSES``.
+
+.. py:function:: check_sts
+
+ Warns if :ref:`SECURE_HSTS_SECONDS` is not set to a non-zero value.
+
+.. py:function:: check_frame_deny
+
+ Warns if :ref:`SECURE_FRAME_DENY` is not ``True``.
+
+.. py:function:: check_ssl_redirect
+
+ Warns if :ref:`SECURE_SSL_REDIRECT` is not ``True``.
+
+.. py:currentmodule:: djangosecure.check.sessions
+
+.. py:function:: check_session_cookie_secure
+
+ Warns if you appear to be using Django's `session framework`_ and the
+ `SESSION_COOKIE_SECURE`_ setting is not ``True``. This setting marks
+ Django's session cookie as a secure cookie, which instructs browsers not to
+ send it along with any insecure requests. Since it's trivial for a packet
+ sniffer (e.g. `Firesheep`_) to hijack a user's session if the session cookie
+ is sent unencrypted, there's really no good excuse not to have this on. (It
+ will prevent you from using sessions on insecure requests; that's a good
+ thing).
+
+.. _Firesheep: http://codebutler.com/firesheep
+
+.. _session framework: https://docs.djangoproject.com/en/dev/topics/http/sessions/
+
+.. _SESSION_COOKIE_SECURE: https://docs.djangoproject.com/en/dev/topics/http/sessions/#session-cookie-secure
+
+.. py:function:: check_session_cookie_httponly
+
+ Warns if you appear to be using Django's `session framework`_ and the
+ `SESSION_COOKIE_HTTPONLY`_ setting is not ``True``. This setting marks
+ Django's session cookie as "HTTPOnly", meaning (in supporting browsers) its
+ value can't be accessed from client-side scripts. Turning this on makes it
+ less trivial for an attacker to escalate a cross-site scripting
+ vulnerability into full hijacking of a user's session. There's not much
+ excuse for leaving this off, either: if your code depends on reading session
+ cookies from Javascript, you're probably doing it wrong.
+
+
+.. _SESSION_COOKIE_HTTPONLY: https://docs.djangoproject.com/en/dev/topics/http/sessions/#session-cookie-httponly
+
+Suggestions for additional built-in checks (or better, patches implementing
+them) are welcome!
+
+
+Modifying the list of check functions
+-------------------------------------
+
+By default, all of the :ref:`built-in checks <built-in-checks>` are run when
+you run ``./manage.py checksecure``. However, some of these checks may not be
+appropriate for your particular deployment configuration. For instance, if you
+do your HTTP->HTTPS redirection in a loadbalancer, it'd be irritating for
+``checksecure`` to constantly warn you about not having enabled
+:ref:`SECURE_SSL_REDIRECT`. You can customize the list of checks by setting the
+:ref:`SECURE_CHECKS` setting; you can just copy the default value and remove a
+check or two; you can also write your own :ref:`custom checks <custom-checks>`.
+
+.. _custom-checks:
+
+Writing custom check functions
+------------------------------
+
+A ``checksecure`` check function can be any Python function that takes no
+arguments and returns a Python iterable of warnings (an empty iterable if it
+finds nothing to warn about).
+
+Optionally, the function can have a ``messages`` attribute, which is a
+dictionary mapping short warning codes returned by the function (which will be
+displayed by ``checksecure`` if run with ``--verbosity=0``) to longer
+explanations which will be displayed by ``checksecure`` when running at its
+default verbosity level. For instance::
+
+ from django.conf import settings
+
+ def check_dont_let_the_bad_guys_in():
+ if settings.LET_THE_BAD_GUYS_IN:
+ return ["BAD_GUYS_LET_IN"]
+ return []
+
+ check_dont_let_the_bad_guys_in.messages = {
+ "BAD_GUYS_LET_IN": (
+ "Longer explanation of why it's a bad idea to let the bad guys in, "
+ "and how to correct the situation.")
+ }
Oops, something went wrong.

0 comments on commit 4821a04

Please sign in to comment.