OK, I'll bite:
For the first issue, my problem revolved around this code:
@property def POST(self): # Ensure that request.POST uses our request
parsing. if not _hasattr(self, '_data'): self._load_data_and_files() if
is_form_media_type(self.content_type): return self._data return
QueryDict('', encoding=self._request._encoding)
The second `if` asks whether the payload is form media type, and, if so,
returns the parsed content, otherwise it returns a blank QueryDict. In
my case, the content-type was set to application/json. It parsed
successfully and self._data was still populated when the code reached
the second if. However, the second if rejected the content and skipped
to returning the empty QueryDict, which then resulted in payload
consequently being served as the empty QueryDict also for DRF. I can't
really say where the actual request._data got reset because of this, but
I did (get reset). I'm guessing DRF tries to parse the data from
scratch, but the stream was consumed already or some such. I didn't
nearly debug this enough to KNOW what went wrong.
I was unable to find the actual culprit for this behaviour, so I
ultimately just exempt the view. But the circumstances of the actual
issue were very unclear: I have a commit where CSRF middleware chose
this path and a commit where it did not. I was unable to find the
culprit by being unable to find the condition that made the middleware
go into the check at all - contrary to the commit before where it did
not. Needless to say, the commits did not deal with anything I perceived
as anything near CSRF or AJAX. They were super small too...
This is the actual section of the code that triggers the POST processing
in the middleware:
if request.method == "POST": try: request_csrf_token =
request.POST.get('csrfmiddlewaretoken', '') except OSError:
IIUC, this code tries to match the token received from the headers with
one that's supposed to be in the form data payload. The code is allowed
to fail just fine, but in this case it has the side-effect mentioned:
the form payload will have been parsed and cannot be parsed again -
while at the same time rejecting the parsed data because it is not form
payload type.
As for the second issue, I must admit I don't understand your reply at
all. I'm a pretty bad n00b while you're one of the Django đombas (tough
big guys) and it's entirely possible I am misinterpreting what I'm
seeing here. I just stated my observation that Django now only serves
the index.html for me, generating a CSRF token along the way and then I
use that CSRF token for all subsequent AJAX requests. I don't even
understand the "visual representation changes" and "looks like it's
different". So, sorry, I'm afraid I can't be of assistance here.
What I was trying to say with that paragraph was that I'd like to
actually figure out a way to START doing token rotation because my
observation is that it's currently NOT rotating and is therefore a lot
less useful as a security measure.
Now I have bit my chunk off and I'm chewing. Hopefully no hooks in there ;)
LP,
Jure
On 20. 04. 23 11:51, Florian Apolloner wrote:
Hi,
On Tuesday, April 18, 2023 at 10:57:55 PM UTC+2 jure.er...@gmail.com
wrote:
Well, TBH, I've just completed dealing with CSRF form in my
projects. I ended up exempting the particular view from CSRF
because I didn't know how to get the stuff to work. The problem
was that django parsed the body payload, which was JSON and thus
rejected its contents (because it wasn't form payload type – POST
method). As a result, DRF then had no payload to work with… I
shouldn't go into too much detail as it's irrelevant to the point.
I do not think this is true. Django only parses the POST data if the
content-type is a form type, so if you are sending JSON properly
Django will not parse the data and DRF can handle it just fine.
But, I've been considering I need a modernised CSRF: currently it
works by generating a new token every page served. But we have
switched our front-end to SPA and that doesn't make much sense any
more since CSRF token itself doesn't change at all, since Django
template system only ever serves one page. AFAIK, DRF doesn't
ganerate new tokens in its pipelines.
That is not accurate either. The token does not change for every page
served, only it's visual representation does. That means that you can
keep using the same CSRF token even though it looks like it is
different (note: This assume that you are not triggering a codepath
that is rotating the token).
Cheers,
Florian
--
You received this message because you are subscribed to the Google
Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-developers/f64582bd-63ea-483a-aebc-2acc5dac6cdbn%40googlegroups.com
<https://groups.google.com/d/msgid/django-developers/f64582bd-63ea-483a-aebc-2acc5dac6cdbn%40googlegroups.com?utm_medium=email&utm_source=footer>.
--
You received this message because you are subscribed to the Google Groups "Django
developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-developers/1dfdaff8-a2b1-08df-4876-246b5660f89b%40gmail.com.