MERC 6: Lower information disclose
- MERC:
6
- Author:
Michael Price
- Status:
Accepted
- Type:
Feature
- Created:
2018-12-30
- Last-Modified:
2018-12-31
Abstract
This MERC proposes the use of errors that don’t disclose the existence of a resource in the event that the requester doesn’t have the required credentials.
Motivation
When an user tries to perform an action like opening a view to a document for which the required permission is missing, a permission required or access denied error is presented. This is semantically correct, but from the stand point of security it is still failing because it is letting the user know that such document exists in the first place. This MERC proposes changing the error message for existing resource to one that doesn’t divulge any information to unauthorized parties, like “Not Found”.
Specification
Out of the 4 basic CRUD operations, Read, Update and Delete should return an HTTP 404 error instead of an HTTP 403 error. Only the Create operation will continue returning the current HTTP 403 error, unless it is creating a new resource that is related to an existing resource.
Since most view use the internal custom CRUD classes making a change to the
ObjectPermissionCheckMixin
class to raise an HTTP 404 on object access
failure will fulfill the proposal of this MERC.
Adding the object_permission_raise_404
class attribute and setting it
to default to False will allow fulfilling the goal of this MERC while
keeping the existing functionality intact.
Example:
class ObjectPermissionCheckMixin:
"""
If object_permission_raise_404 is True an HTTP 404 error will be raised
instead of the normal 403.
"""
object_permission = None
object_permission_raise_404 = False
def get_permission_object(self):
return self.get_object()
def dispatch(self, request, *args, **kwargs):
if self.object_permission:
try:
AccessControlList.objects.check_access(
permissions=self.object_permission, user=request.user,
obj=self.get_permission_object(),
related=getattr(self, 'object_permission_related', None)
)
except PermissionDenied:
if self.object_permission_raise_404:
raise Http404
else:
raise
return super(
ObjectPermissionCheckMixin, self
).dispatch(request, *args, **kwargs)