Saturday, January 8, 2022

Re: Eliminating inter-request race conditions

I thought I'd post a little update, as I'm fairly happy with my progress:

Here's the repo's readme. I haven't actually pushed the package to pypi so don't try to follow the instructions yet, but any feedback on the README's content is very welcome: https://github.com/nicois/nango/blob/develop/README.md . Hopefully in the next couple of days I'll push the package to pypi so anyone who's interested can make sure it works as advertised.

But still I wonder if client-side validation and feedback should be optional? That is, if I had to do this myself, I'd hope to find a solution first that works 100 % without client-side effects. This would also help a lot with correctness and testing. Then I'd put all eye candy on top, but keeping it strictly optional.

The client-side validation is latent in this release. That is, there is some code which will provide client-side validation with websockets, but it is disabled unless explicitly enabled in settings.py. I've put in the beginnings of some automated tests, which I can expand as I proceed. I agree that the server-side data integrity is more important, lower risk and easier to test.
 
> There are only two ways I can see of to achieve this: use a full-blown "rowversion" CAS pattern, where there is a dedicated monotonic column on each table which automatically increases with each update, or the method I propose/use, where the original form values are provided via the user agent when the form is POSTed.

Then this would have to be temper-proof, wouldn't it?
(e.g. using https://itsdangerous.palletsprojects.com )
No, the (current) intention is not to make this tamper-proof. If you think about it, there is no value from trying to protect against an authenticated and authorised user who wants to submit incorrect values. While there could be HMACs etc, I don't see any value at all, as a malicious user does not need to tamper with the original values to submit bad data.
 
It might even be possible to serialize the entire state of the object into a single hidden field and sign it on GET, then check the signature and deserialize on POST. Or maybe, depending on the exact requirements, even the checksum of the old state would be enough in order to detect that something changed between the old version of the model (as it was when the user started editing it) and the current version (at the time the POST request arrives). This would roughly correspond to a version number without requiring an explicit field on the model.
Remember also that there is little to no value in checking that fields on the model have changed, if those fields are not shown on the model: firstly because the form will not update those fields in the database, and secondly because if only those "invisible" fields change, the end-user would see the same thing on the form, and would not alter their behaviour. 

The value here is in showing a user that one of the fields they are in the process of editing has changed while they have had the form open, and ensuring that they do not accidentally clobber someone else's changes.

Thanks for your feedback so far. 
 
Nick

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/a449bb5f-c834-457e-83f5-02eec2e0e784n%40googlegroups.com.

No comments:

Post a Comment