Hi all,
I need to ask for a Technical Board decision on the resolution of Ticket #31747.
Ticket #31747: Avoid potential admin model enumeration
PR #13134: Fixed #31747 -- Fixed model enumeration via admin URLs.
## Summary
The initial issue is that there is a difference in HTTP response code for admin
URLs depending on whether a URL routes to an existing model or not:
In principle an attacker could use this to leak information about the app's
models, which could be part of a further attack.
This was originally reported to the Django Security Team, who declined to take
it as a security issue, but recommended adding a final catch-all view to the
admin, which would redirect all unauthenticated requests to login, thus masking
the private model info.
Jon Dufresne picked this issue up, and submitted a PR, but in so-doing noticed
that a very similar (the same?) issue occurred with APPEND_SLASH behaviour in
the admin too. (Try URLs without the slash, looking for a redirect to the
correct URL **before** being redirected to login.)
The initial thought was that we might need to remove APPEND_SLASH URL
normalisation for the admin. We were able to avoid that by restricting the
append_slash-style URL normalisation for the admin to authenticated staff
users. This addresses the main force of the original report (which is
unauthenticated users remotely probing the site) but Jon noted that it still
allows a staff-user to potentially discover the existence of model for which
they don't have permissions in this way.
In order to avoid this last threat Jon felt that we still needed to disable
append slash URL normalisation for the admin.
In contrast, I felt the threat of a staff user discovering models in this way
would apply to only a tiny fraction of all installations, and that the utility
of URL normalisation vastly outweighs that on balance.
We have a trade-off between balancing privacy and usability here.
After much discussion and thought, Jon and I came to agree (I think 🙂) that an
`AdminSite.append_slash` toggle was needed to control the behaviour here. If
privacy is paramount, you can set that to `False` to disable the URL
normalisation in the admin. If you don't need to keep models secret from staff
users you can have it `True` and still get the benefits of append slash
behaviour.
We felt this was something that everyone could live with. Wherever you are on
the spectrum, for the simplest case, where you're just using the default admin
site, you toggle the behaviour with a single line in your URL conf:
from django.contrib import admin
admin.site.append_slash = ...set True/False as you want here...
(On the way, we also found a way of opting-out for a single ModelAdmin, but
let's not talk about that here.)
All good, except...
## Decision needed
Jon and I still don't agree on the correct default value for
`AdminSite.append_slash`.
Our disagreement is a difference in weighting, which is hard to argue about,
and we don't want to fall out over it either. So we'd like to ask the Technical
Board to decide.
### Option 1 - default `True`
As the PR stands:
* `AdminSite.append_slash` defaults to `True`.
* This is consistent with the past behaviour for authenticated staff users.
### Option 2 - default `False`
* Make `AdminSite.append_slash` defaults to `False`.
* This would be a breaking change, but...
* We could document it in the release notes, and...
* The "fix" is the simple adjustment in the URL conf for most folks.
### Option 3 - default `False` with deprecation
* We could do 2, but somehow with a deprecation period.
I don't think we should do this. It's difficult and a hard break at the end of
the deprecation, but I mention it for completeness (and because the PR
originally included a deprecation of the APPEND_SLASH behaviour for the admin.)
My opinion is that we should opt for Option 1, as consistent with the past
behaviour, and most appropriate for most users. I can live with Option 2 if
that's the decision, but I think we'd artificially elevating an issue that
simply doesn't apply to most installs.
I think Jon's opinion is the counterpart of that. He prefers Option 2, as the
more secure default. He could live with Option 1 if that's the decision, but
thinks we shouldn't be asking opt-in to privacy here, whatever the usability
consequences.
As such, can we ask the TB to choose an option? Thanks.
Jon: hopefully I'e presented your view fairly; if you feel not, please do
follow-up 🙂
Kind Regards,
Carlton
Hi all,
I need to ask for a Technical Board decision on the resolution of Ticket #31747.
Ticket #31747: Avoid potential admin model enumeration
PR #13134: Fixed #31747 -- Fixed model enumeration via admin URLs.
## Summary
The initial issue is that there is a difference in HTTP response code for admin
URLs depending on whether a URL routes to an existing model or not:
In principle an attacker could use this to leak information about the app's
models, which could be part of a further attack.
This was originally reported to the Django Security Team, who declined to take
it as a security issue, but recommended adding a final catch-all view to the
admin, which would redirect all unauthenticated requests to login, thus masking
the private model info.
Jon Dufresne picked this issue up, and submitted a PR, but in so-doing noticed
that a very similar (the same?) issue occurred with APPEND_SLASH behaviour in
the admin too. (Try URLs without the slash, looking for a redirect to the
correct URL **before** being redirected to login.)
The initial thought was that we might need to remove APPEND_SLASH URL
normalisation for the admin. We were able to avoid that by restricting the
append_slash-style URL normalisation for the admin to authenticated staff
users. This addresses the main force of the original report (which is
unauthenticated users remotely probing the site) but Jon noted that it still
allows a staff-user to potentially discover the existence of model for which
they don't have permissions in this way.
In order to avoid this last threat Jon felt that we still needed to disable
append slash URL normalisation for the admin.
In contrast, I felt the threat of a staff user discovering models in this way
would apply to only a tiny fraction of all installations, and that the utility
of URL normalisation vastly outweighs that on balance.
We have a trade-off between balancing privacy and usability here.
After much discussion and thought, Jon and I came to agree (I think 🙂) that an
`AdminSite.append_slash` toggle was needed to control the behaviour here. If
privacy is paramount, you can set that to `False` to disable the URL
normalisation in the admin. If you don't need to keep models secret from staff
users you can have it `True` and still get the benefits of append slash
behaviour.
We felt this was something that everyone could live with. Wherever you are on
the spectrum, for the simplest case, where you're just using the default admin
site, you toggle the behaviour with a single line in your URL conf:
from django.contrib import admin
admin.site.append_slash = ...set True/False as you want here...
(On the way, we also found a way of opting-out for a single ModelAdmin, but
let's not talk about that here.)
All good, except...
## Decision needed
Jon and I still don't agree on the correct default value for
`AdminSite.append_slash`.
Our disagreement is a difference in weighting, which is hard to argue about,
and we don't want to fall out over it either. So we'd like to ask the Technical
Board to decide.
### Option 1 - default `True`
As the PR stands:
* `AdminSite.append_slash` defaults to `True`.
* This is consistent with the past behaviour for authenticated staff users.
### Option 2 - default `False`
* Make `AdminSite.append_slash` defaults to `False`.
* This would be a breaking change, but...
* We could document it in the release notes, and...
* The "fix" is the simple adjustment in the URL conf for most folks.
### Option 3 - default `False` with deprecation
* We could do 2, but somehow with a deprecation period.
I don't think we should do this. It's difficult and a hard break at the end of
the deprecation, but I mention it for completeness (and because the PR
originally included a deprecation of the APPEND_SLASH behaviour for the admin.)
My opinion is that we should opt for Option 1, as consistent with the past
behaviour, and most appropriate for most users. I can live with Option 2 if
that's the decision, but I think we'd artificially elevating an issue that
simply doesn't apply to most installs.
I think Jon's opinion is the counterpart of that. He prefers Option 2, as the
more secure default. He could live with Option 1 if that's the decision, but
thinks we shouldn't be asking opt-in to privacy here, whatever the usability
consequences.
As such, can we ask the TB to choose an option? Thanks.
Jon: hopefully I'e presented your view fairly; if you feel not, please do
follow-up 🙂
Kind Regards,
Carlton