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.
  • Dro... 'Ryan Hiebert' via Django developers (Contributions to Django itself)
    • ... Jacob Rief
    • ... Curtis Maloney
      • ... Jacob Rief
        • ... Jure Erznožnik
          • ... Stratos Moros
            • ... Jacob Rief
              • ... Stratos Moros
                • ... jure.erznoznik
                • ... Florian Apolloner
                • ... Jure Erznožnik
                • ... Florian Apolloner
                • ... 'Ryan Hiebert' via Django developers (Contributions to Django itself)
                • ... Deepak Sain
            • ... 'Ryan Hiebert' via Django developers (Contributions to Django itself)

Reply via email to