Code

Opened 7 years ago

Closed 4 years ago

#3785 closed (fixed)

admin does not valid object id values before using them in database queries

Reported by: anonymous Owned by: nobody
Component: contrib.admin Version: master
Severity: Keywords: admin, urls, invalid url
Cc: root.lastnode@…, crucialfelix@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

Somehow somewhere, while working with the admin i accidentally appended a +/ to a crud url and this raised the following sql error.

While the admin should not be accessible for anonymous users, it does not feel right to me to have a sql exception raised on a invalid url.

Since django.contrib.admin.urls explicitly specifies the append operations history and delete it would seem that it could very well be aware of the fact that '/admin/article/article/12/+/' is not a valid url.

In django.contrib.admin.views.main change_stage and all others, they clearly define the third path element to be an object_id, so why not use:

    ('^([^/]+)/([^/]+)/(\d+)/$', 'django.contrib.admin.views.main.change_stage'),

Instead of:

    ('^([^/]+)/([^/]+)/(.+)/$', 'django.contrib.admin.views.main.change_stage'),

For this and the other url's ? Or at least forbit a another '/' in there.

Url: '/admin/article/article/12/+/'

Traceback:

Traceback (most recent call last):

  File "/usr/lib/python2.4/site-packages/django/core/handlers/base.py", line 77, in get_response
    response = callback(request, *callback_args, **callback_kwargs)

  File "/usr/lib/python2.4/site-packages/django/contrib/admin/views/decorators.py", line 55, in _checklogin
    return view_func(request, *args, **kwargs)

  File "/usr/lib/python2.4/site-packages/django/views/decorators/cache.py", line 39, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)

  File "/usr/lib/python2.4/site-packages/django/contrib/admin/views/main.py", line 315, in change_stage
    manipulator = model.ChangeManipulator(object_id)

  File "/usr/lib/python2.4/site-packages/django/db/models/manipulators.py", line 259, in __init__
    self.original_object = self.manager.get(pk=obj_key)

  File "/usr/lib/python2.4/site-packages/django/db/models/manager.py", line 73, in get
    return self.get_query_set().get(*args, **kwargs)

  File "/usr/lib/python2.4/site-packages/django/db/models/query.py", line 250, in get
    obj_list = list(clone)

  File "/usr/lib/python2.4/site-packages/django/db/models/query.py", line 108, in __iter__
    return iter(self._get_data())

  File "/usr/lib/python2.4/site-packages/django/db/models/query.py", line 470, in _get_data
    self._result_cache = list(self.iterator())

  File "/usr/lib/python2.4/site-packages/django/db/models/query.py", line 183, in iterator
    cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params)

ProgrammingError: invalid input syntax for integer: "12/+"

Thanks for Django and all the good work!

Attachments (1)

patch.django.contrib.admin.urls.py.diff (844 bytes) - added by anonymous 7 years ago.

Download all attachments as: .zip

Change History (10)

Changed 7 years ago by anonymous

comment:1 Changed 7 years ago by mtredinnick

  • Has patch unset
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Summary changed from admin allow invalid urls and tries to execute them to admin does not valid object id values before using them in database queries
  • Triage Stage changed from Unreviewed to Accepted

Not all object ids have to be integers. Custom primary keys can be anything at all, including strings containing slashes and other punctuation. So in some situations "12/+" could be a perfectly valid id.

There is a bug here, though, since, for some reason we are not validating the id value prior to using it in a query. This should cause an error at the form validation stage, not the database query stage of the operation. Changing ticket title to reflect the real problem.

Worth making sure we don't fall into the same trap on the newforms-admin branch.

comment:2 Changed 7 years ago by anonymous

thanks, your absolutely right.

have not thought of that.

i would like to update the patch to something far more sensible,
but i think i'll better leave that to you guys :)

comment:3 Changed 6 years ago by brosner

This needs to be re-tested on trunk currently. The urls.py in the admin application no longer exists, but I suspect this is still not working right.

comment:4 Changed 6 years ago by trbs

Tested it with latest django (r8457) and pinax source.

Exception Type: ValueError at /admin/announcements/announcement/1/@/
Exception Value: invalid literal for int() with base 10: '1/@'

Think we can put this one on post 1.0 ?
Unless brosner (as the authoritive source on NFA ? :) thinks it's an important bug and/or relatively easy and safe patch to get the validation right.

comment:5 Changed 5 years ago by kmtracey

#11678 reported this again.

comment:6 Changed 4 years ago by crucialfelix

  • Cc crucialfelix@… added

I get this coming through all the time.
/admin/nsmailings/maillistings/javascripts/t_tip.js/

no idea what crap browser generates this stuff, I don't even have this javascripts/t_tip.js anywhere on my site.

Its an easy fix, just add ValueError to the caught exceptions :

    def get_object(self, request, object_id):
        """
        Returns an instance matching the primary key provided. ``None``  is
        returned if no match is found (or the object_id failed validation
        against the primary key field).
        """
        queryset = self.queryset(request)
        model = queryset.model
        try:
            object_id = model._meta.pk.to_python(object_id)
            return queryset.get(pk=object_id)
        except (model.DoesNotExist, ValidationError,ValueError):
            return None

line 387, django/contrib/admin/options.py

comment:7 Changed 4 years ago by trbs

Second that problem. Mostly seeing it for "content.css" here.

I'm quite sure that for me it's Windows machines with Internet Explorer that cause this.

Would not be in favor of silently ignoring the error but it's definitely irritating. (potentially causing so many emails that the purpose of the error mails get lost inside of all the junk)

But the big 'scary' part seems to be that the sql driver is reporting this.

  File "/usr/lib/python2.5/site-packages/django/db/models/query.py", line 189, in iterator
    cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params)

DataError: invalid input syntax for integer: "css/content.css"

Now this site does not run the latest Django code, so it might be fixed or get a different exception on trunk ?

comment:8 Changed 4 years ago by crucialfelix

actually it should throw a 404. then we can handle that in the usual fashion, getting emails or not.

    def get_object(self, request, object_id):
        """
        Returns an instance matching the primary key provided. ``None``  is
        returned if no match is found (or the object_id failed validation
        against the primary key field).
        """
        queryset = self.queryset(request)
        model = queryset.model
        try:
            object_id = model._meta.pk.to_python(object_id)
            return queryset.get(pk=object_id)
        except (model.DoesNotExist, ValidationError):
            return None
        except ValueError:
            raise Http404

though I'm not a big fan of catching errors from methods that are polymorphic and could contain ANYTHING. django code makes a lot of assumptions in this fashion, even using it instead of just checking type.

in this case though I think its correct

comment:9 Changed 4 years ago by ramiro

  • Resolution set to fixed
  • Status changed from new to closed

Fixed in r12011.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.