A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/django/django/commit/818e70344e7193f6ebc73c82ed574e6ce3c91afc below:

[1.2.X] Fixed a security issue in the CSRF componenent. Disclosure … · django/django@818e703 · GitHub

File tree Expand file treeCollapse file tree 3 files changed

+50

-51

lines changed

Filter options

Expand file treeCollapse file tree 3 files changed

+50

-51

lines changed Original file line number Diff line number Diff line change

@@ -97,6 +97,7 @@ def _reject(self, request, reason):

97 97

return _get_failure_view()(request, reason=reason)

98 98 99 99

def process_view(self, request, callback, callback_args, callback_kwargs):

100 + 100 101

if getattr(request, 'csrf_processing_done', False):

101 102

return None

102 103

@@ -130,31 +131,6 @@ def process_view(self, request, callback, callback_args, callback_kwargs):

130 131

# any branches that call reject()

131 132

return self._accept(request)

132 133 133 -

if request.is_ajax():

134 -

# .is_ajax() is based on the presence of X-Requested-With. In

135 -

# the context of a browser, this can only be sent if using

136 -

# XmlHttpRequest. Browsers implement careful policies for

137 -

# XmlHttpRequest:

138 -

#

139 -

# * Normally, only same-domain requests are allowed.

140 -

#

141 -

# * Some browsers (e.g. Firefox 3.5 and later) relax this

142 -

# carefully:

143 -

#

144 -

# * if it is a 'simple' GET or POST request (which can

145 -

# include no custom headers), it is allowed to be cross

146 -

# domain. These requests will not be recognized as AJAX.

147 -

#

148 -

# * if a 'preflight' check with the server confirms that the

149 -

# server is expecting and allows the request, cross domain

150 -

# requests even with custom headers are allowed. These

151 -

# requests will be recognized as AJAX, but can only get

152 -

# through when the developer has specifically opted in to

153 -

# allowing the cross-domain POST request.

154 -

#

155 -

# So in all cases, it is safe to allow these requests through.

156 -

return self._accept(request)

157 - 158 134

if request.is_secure():

159 135

# Strict referer checking for HTTPS

160 136

referer = request.META.get('HTTP_REFERER')

@@ -185,7 +161,11 @@ def process_view(self, request, callback, callback_args, callback_kwargs):

185 161

csrf_token = request.META["CSRF_COOKIE"]

186 162 187 163

# check incoming token

188 -

request_csrf_token = request.POST.get('csrfmiddlewaretoken', None)

164 +

request_csrf_token = request.POST.get('csrfmiddlewaretoken', "")

165 +

if request_csrf_token == "":

166 +

# Fall back to X-CSRFToken, to make things easier for AJAX

167 +

request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')

168 + 189 169

if request_csrf_token != csrf_token:

190 170

if cookie_is_new:

191 171

# probably a problem setting the CSRF cookie

Original file line number Diff line number Diff line change

@@ -81,6 +81,47 @@ The utility script ``extras/csrf_migration_helper.py`` can help to automate the

81 81

finding of code and templates that may need to be upgraded. It contains full

82 82

help on how to use it.

83 83 84 +

AJAX

85 +

----

86 + 87 +

While the above method can be used for AJAX POST requests, it has some

88 +

inconveniences: you have to remember to pass the CSRF token in as POST data with

89 +

every POST request. For this reason, there is an alternative method: on each

90 +

XMLHttpRequest, set a custom `X-CSRFToken` header to the value of the CSRF

91 +

token. This is often easier, because many javascript frameworks provide hooks

92 +

that allow headers to be set on every request. In jQuery, you can use the

93 +

``beforeSend`` hook as follows:

94 + 95 +

.. code-block:: javascript

96 + 97 +

$.ajaxSetup({

98 +

beforeSend: function(xhr, settings) {

99 +

function getCookie(name) {

100 +

var cookieValue = null;

101 +

if (document.cookie && document.cookie != '') {

102 +

var cookies = document.cookie.split(';');

103 +

for (var i = 0; i < cookies.length; i++) {

104 +

var cookie = jQuery.trim(cookies[i]);

105 +

// Does this cookie string begin with the name we want?

106 +

if (cookie.substring(0, name.length + 1) == (name + '=')) {

107 +

cookieValue = decodeURIComponent(cookie.substring(name.length + 1));

108 +

break;

109 +

}

110 +

}

111 +

}

112 +

return cookieValue;

113 +

}

114 +

if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {

115 +

// Only send the token to relative URLs i.e. locally.

116 +

xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));

117 +

}

118 +

}

119 +

});

120 + 121 +

Adding this to a javascript file that is included on your site will ensure that

122 +

AJAX POST requests that are made via jQuery will not be caught by the CSRF

123 +

protection.

124 + 84 125

The decorator method

85 126

--------------------

86 127

@@ -262,10 +303,6 @@ in the same module. These disable the view protection mechanism

262 303

(``CsrfResponseMiddleware``) respectively. They can be used individually if

263 304

required.

264 305 265 -

You don't have to worry about doing this for most AJAX views. Any request sent

266 -

with "X-Requested-With: XMLHttpRequest" is automatically exempt. (See the `How

267 -

it works`_ section.)

268 - 269 306

Subdomains

270 307

----------

271 308

@@ -343,24 +380,6 @@ request ought to be harmless.

343 380

response, and only pages that are served as 'text/html' or

344 381

'application/xml+xhtml' are modified.

345 382 346 -

AJAX

347 -

----

348 - 349 -

The middleware tries to be smart about requests that come in via AJAX. Most

350 -

modern JavaScript toolkits send an "X-Requested-With: XMLHttpRequest" HTTP

351 -

header; these requests are detected and automatically *not* handled by this

352 -

middleware. We can do this safely because, in the context of a browser, the

353 -

header can only be added by using ``XMLHttpRequest``, and browsers already

354 -

implement a same-domain policy for ``XMLHttpRequest``.

355 - 356 -

For the more recent browsers that relax this same-domain policy, custom headers

357 -

like "X-Requested-With" are only allowed after the browser has done a

358 -

'preflight' check to the server to see if the cross-domain request is allowed,

359 -

using a strictly 'opt in' mechanism, so the exception for AJAX is still safe—if

360 -

the developer has specifically opted in to allowing cross-site AJAX POST

361 -

requests on a specific URL, they obviously don't want the middleware to disallow

362 -

exactly that.

363 - 364 383

.. _9.1.1 Safe Methods, HTTP 1.1, RFC 2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

365 384 366 385

Caching

Original file line number Diff line number Diff line change

@@ -275,12 +275,12 @@ def test_process_request_csrf_cookie_no_token_exempt_view(self):

275 275

req2 = CsrfMiddleware().process_view(req, csrf_exempt(post_form_view), (), {})

276 276

self.assertEquals(None, req2)

277 277 278 -

def test_ajax_exemption(self):

278 +

def test_csrf_token_in_header(self):

279 279

"""

280 -

Check that AJAX requests are automatically exempted.

280 +

Check that we can pass in the token in a header instead of in the form

281 281

"""

282 282

req = self._get_POST_csrf_cookie_request()

283 -

req.META['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'

283 +

req.META['HTTP_X_CSRFTOKEN'] = self._csrf_id

284 284

req2 = CsrfMiddleware().process_view(req, post_form_view, (), {})

285 285

self.assertEquals(None, req2)

286 286

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4