Today the Django team is issuing multiple releases --
Django 1.2.6 and Django 1.3.1 -- to remedy security issues
reported to us. Additionally, this announcement contains
advisories for several other issues which, while not
requiring changes to Django itself, will be of concern
to users of Django.

All users are encouraged to upgrade Django, and to implement
the recommendations in these advisories, immediately.

Session manipulation

Django's session framework, django.contrib.sessions, is
configurable to use any of multiple backends for storage of
session data. One such backend, provided with Django itself,
integrates with Django's cache framework to use the cache as
storage for session data.

When configured in this fashion using memory-based sessions
and caching, Django sessions are stored directly in the root
namespace of the cache, using session identifiers as keys.

This results in a potential attack when coupled with an
application storing user-supplied data in the cache; if an
attacker can cause data to be cached using a key which is
also a valid session identifier, Django's session framework
will treat that data -- so long as it is a dictionary-like
object -- as the session, thus allowing arbitrary data to be
inserted into a session so long as the attacker knows the
session key.

Denial of service attack via URLField

Django's model system includes a field type -- URLField --
which validates that the supplied value is a valid URL, and if
the boolean keyword argument verify_exists is true, attempts
to validate that the supplied URL also resolves, by issuing a
request to it.

By default, the underlying socket libraries in Python do not
have a timeout. This can manifest as a security problem in
three different ways:

An attacker can supply a slow-to-respond URL. Each request
will tie up a server process for a period of time; if the
attacker is able to make enough requests, they can tie up
all available server processes.

An attacker can supply a URL under his or her control, and
which will simply hold an open connection indefinitely. Due
to the lack of timeout, the Django process attempting to
verify the URL will similarly spin indefinitely. Repeating
this can easily tie up all available server processes.

An attacker can supply a URL under his or her control
which not only keeps the connection open, but also sends an
unending stream of random garbage data. This data will
cause the memory usage of the Django process (which will
hold the response in memory) to grow without bound, thus
consuming not only server processes but also server
memory.

URLField redirection

The regular expression which validates URLs is used to check
the supplied URL before issuing a check to verify that it
exists, but if that URL issues a redirect in response to the
request, no validation of the resulting redirected URL is
performed, including basic checks for supported protocols
(HTTP, HTTPS, and FTP).

This creates a small window for an attacker to gain knowledge
of, for example, server layout; a redirect to a file:// URL,
for example, will tell an attacker whether a given file exists
locally on the server.

Additionally, although the initial request issued by Django
uses the HEAD method for HTTP/HTTPS, the request to the target
of the redirect is issued using GET. This may create further
issues for systems which implicitly trust GET requests from
the local machine/network.

Host header cache poisoning

In several places, Django itself -- independent of the
developer -- generates full URLs (for example, when issuing
HTTP redirects). Currently this uses the value of the HTTP
Host header from the request to construct the URL, which opens
a potential cache-poisoning vector: an attacker can submit
a request with a Host header of his or her choice, receive a
response which constructs URLs using that Host header, and --
if that response is cached -- further requests will be served
out of cache using URLs containing the attacker's host of
choice.

Today the Django team is issuing multiple releases --
Django 1.2.6 and Django 1.3.1 -- to remedy security issues
reported to us. Additionally, this announcement contains
advisories for several other issues which, while not
requiring changes to Django itself, will be of concern
to users of Django.

All users are encouraged to upgrade Django, and to implement
the recommendations in these advisories, immediately.

Session manipulation

Django's session framework, django.contrib.sessions, is
configurable to use any of multiple backends for storage of
session data. One such backend, provided with Django itself,
integrates with Django's cache framework to use the cache as
storage for session data.

When configured in this fashion using memory-based sessions
and caching, Django sessions are stored directly in the root
namespace of the cache, using session identifiers as keys.

This results in a potential attack when coupled with an
application storing user-supplied data in the cache; if an
attacker can cause data to be cached using a key which is
also a valid session identifier, Django's session framework
will treat that data -- so long as it is a dictionary-like
object -- as the session, thus allowing arbitrary data to be
inserted into a session so long as the attacker knows the
session key.

Denial of service attack via URLField

Django's model system includes a field type -- URLField --
which validates that the supplied value is a valid URL, and if
the boolean keyword argument verify_exists is true, attempts
to validate that the supplied URL also resolves, by issuing a
request to it.

By default, the underlying socket libraries in Python do not
have a timeout. This can manifest as a security problem in
three different ways:

An attacker can supply a slow-to-respond URL. Each request
will tie up a server process for a period of time; if the
attacker is able to make enough requests, they can tie up
all available server processes.

An attacker can supply a URL under his or her control, and
which will simply hold an open connection indefinitely. Due
to the lack of timeout, the Django process attempting to
verify the URL will similarly spin indefinitely. Repeating
this can easily tie up all available server processes.

An attacker can supply a URL under his or her control
which not only keeps the connection open, but also sends an
unending stream of random garbage data. This data will
cause the memory usage of the Django process (which will
hold the response in memory) to grow without bound, thus
consuming not only server processes but also server
memory.

URLField redirection

The regular expression which validates URLs is used to check
the supplied URL before issuing a check to verify that it
exists, but if that URL issues a redirect in response to the
request, no validation of the resulting redirected URL is
performed, including basic checks for supported protocols
(HTTP, HTTPS, and FTP).

This creates a small window for an attacker to gain knowledge
of, for example, server layout; a redirect to a file:// URL,
for example, will tell an attacker whether a given file exists
locally on the server.

Additionally, although the initial request issued by Django
uses the HEAD method for HTTP/HTTPS, the request to the target
of the redirect is issued using GET. This may create further
issues for systems which implicitly trust GET requests from
the local machine/network.

Host header cache poisoning

In several places, Django itself -- independent of the
developer -- generates full URLs (for example, when issuing
HTTP redirects). Currently this uses the value of the HTTP
Host header from the request to construct the URL, which opens
a potential cache-poisoning vector: an attacker can submit
a request with a Host header of his or her choice, receive a
response which constructs URLs using that Host header, and --
if that response is cached -- further requests will be served
out of cache using URLs containing the attacker's host of
choice.

These security releases fix four issues: one potential phishing
vector, one denial-of-service vector, an information leakage issue,
and a range of XML vulnerabilities.

Host header poisoning

an attacker could cause Django to generate and display URLs that
link to arbitrary domains. This could be used as part of a phishing
attack. These releases fix this problem by introducing a new
setting, ALLOWED_HOSTS, which specifies a whitelist of domains your
site is known to respond to.

Important: by default Django 1.3.6 and 1.4.4 set ALLOWED_HOSTS to
allow all hosts. This means that to actually fix the security
vulnerability you should define this setting yourself immediately
after upgrading.

Formset denial-of-service

an attacker can abuse Django's tracking of the number of forms in
a formset to cause a denial-of-service attack. This has been fixed
by adding a default maximum number of forms of 1,000. You can still
manually specify a bigger max_num, if you wish, but 1,000 should be
enough for anyone.

XML attacks

Django's serialization framework was vulnerable to attacks via XML
entity expansion and external references; this is now fixed.
However, if you're parsing arbitrary XML in other parts of your
application, we recommend you look into the defusedxml Python
packages which remedy this anywhere you parse XML, not just via
Django's serialization framework.

Data leakage via admin history log

Django's admin interface could expose supposedly-hidden
information via its history log. This has been fixed.