django-data-browser
django-data-browser copied to clipboard
Some Filters Bypass Default Admin Queryset
Normally, the rows that show up in DataBrowser are limited to those returned in the queryset from get_queryset defined in the ModelAdmin for a model. But when filtering on a column in DataBrowser, certain filters seem to enable bypassing that get_queryset method.
Specifically, I find that regex, ends with, starts with, contains, and equals each enable this bypass, whereas the other filters do not.
In my situation, we use the get_queryset to perform an initial filter to only show objects that the user has permission to view. By using the column filter, however, users are able to bypass that filter and access data that should not be accessible to them.
For reference, we are using version 4.2.5. It did not seem like this was fixed in a more recent version, but if it has, my apologies.
That is surprising and concerning. I'm going to need some more details. Are you able to share the URL, and the output when you change the the "html" to "qs" and to "sql"? If you don't want those on a github comment you can send it to gordon wrigley on gmail. Also what are the Python and Django versions? And if possible what exactly is in that get_queryset function.
On Thu, Dec 5, 2024 at 4:33 AM Erik @.***> wrote:
Normally, the rows that show up in DataBrowser are limited to those returned in the queryset from get_queryset defined in the ModelAdmin for a model. But when filtering on a column in DataBrowser, certain filters seem to enable bypassing that get_queryset method.
Specifically, I find that regex, ends with, starts with, contains, and equals each enable this bypass, whereas the other filters do not.
In my situation, we use the get_queryset to perform an initial filter to only show objects that the user has permission to view. By using the column filter, however, users are able to bypass that filter and access data that should not be accessible to them.
For reference, we are using version 4.2.5. It did not seem like this was fixed in a more recent version, but if it has, my apologies.
— Reply to this email directly, view it on GitHub https://github.com/tolomea/django-data-browser/issues/75, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAGERUGGIW4VYNSL22JDPVT2D7JTJAVCNFSM6AAAAABTBTAF56VHI2DSMVQWIX3LMV43ASLTON2WKOZSG4YTSMRZGA4TGMQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>
By reviewing the sql query used, I've realized that the ability to view objects not part of the initial queryset is actually coming from the use of a many to many expansion combined with its reverse relationship. In this case, DataBrowser may (correctly) show rows for the current model that would not be included in the default queryset. For my use case, I will just remove that reverse relationship to avoid that, since it makes sense why DataBrowser behaves in that way for many to many fields.
There is still something unintuitive about the filtering which made me think yesterday that it was enabling the extra data access. For context, the relevant model structure we are using is the following: each user may be assigned to multiple organizations through a many-to-many, and we have a note model where each note also has a many to many relationship with the organization model. Users from separate organizations may sync a note with each other by assigning the note to both their organizations. The initial note queryset filters to only those that share at least one organization with the user making the request.
To explain what I was finding with the filters, suppose we have three organizations: X, Y, and Z; a user who is part of X and Y; and notes with various assignments to those organizations. When the user opens the note model in DataBrowser and select the [many to many] organization->name as a column, initially that column only shows X and Y. Because of this, I was initially under the impression that there were no notes the user had access to that were that were also assigned to Z (though it turned out that there were). When adding any of the following filters to that column: regex, ends with, starts with, contains, and equals, the organization name Z may also show up if it matches the filter. On the other hand, when each of the other filters is used on the column instead (is null, not regex, not endswith, not startswith, not contains, or not equals) then only X and Y still show up (even if the name Z should match that filter pattern).
So, it seems that the filter is not actually bypassing the default queryset, but it is not exactly returning what I would expect. This is not a significant issue, though. If that filter behavior on the many to many column is as is intended, this issue may be closed. Would it still be helpful if I provided the sql queries generated by DataBrowser?
I would be curious to see. I might be able to change the way it deals with m2m fields to mitigate it.
On Thu, Dec 5, 2024 at 2:58 PM Erik @.***> wrote:
By reviewing the sql query used, I've realized that the ability to view objects not part of the initial queryset is actually coming from the use of a many to many expansion combined with its reverse relationship. In this case, DataBrowser may (correctly) show rows for the current model that would not be included in the default queryset. For my use case, I will just remove that reverse relationship to avoid that, since it makes sense why DataBrowser behaves in that way for many to many fields.
There is still something unintuitive about the filtering which made me think yesterday that it was enabling the extra data access. For context, the relevant model structure we are using is the following: each user may be assigned to multiple organizations through a many-to-many, and we have a note model where each note also has a many to many relationship with the organization model. Users from separate organizations may sync a note with each other by assigning the note to both their organizations. The initial note queryset filters to only those that share at least one organization with the user making the request.
To explain what I was finding with the filters, suppose we have three organizations: X, Y, and Z; a user who is part of X and Y; and notes with various assignments to those organizations. When the user opens the note model in DataBrowser and select the [many to many] organization->name as a column, initially that column only shows X and Y. Because of this, I was initially under the impression that there were no notes the user had access to that were that were also assigned to Z (though it turned out that there were). When adding any of the following filters to that column: regex, ends with, starts with, contains, and equals, the organization name Z may also show up if it matches the filter. On the other hand, when each of the other filters is used on the column instead (is null, not regex, not endswith, not startswith, not contains, or not equals) then only X and Y still show up (even if the name Z should match that filter pattern).
So, it seems that the filter is not actually bypassing the default queryset, but it is not exactly returning what I would expect. This is not a significant issue, though. If that filter behavior on the many to many column is as is intended, this issue may be closed. Would it still be helpful if I provided the sql queries generated by DataBrowser?
— Reply to this email directly, view it on GitHub https://github.com/tolomea/django-data-browser/issues/75#issuecomment-2520550841, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAGERUFW3KMERV4YXERRQXL2EBSX5AVCNFSM6AAAAABTBTAF56VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKMRQGU2TAOBUGE . You are receiving this because you commented.Message ID: @.***>