New reminder, contact and posting pages, accepting a suggestion: a non-numeric id parameter is a server error #409
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#409
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found on 2026-09-29 in a read-only review of postulo at
95348908d, reading how the views take record ids from the query string and the form, and requesting each with a non-numeric value through the test client.Checked again on 2026-10-01 against
mainat0a5cad587: still present. The code is now atapplications/views.py:715-722(ReminderCreateView.asked_application, which since #316 holds the reminder lookup;get_initialat:724-728calls it, and so doesReminderFormMixin.fallback_urlat:686-691for the Cancel link and the address after saving) andapplications/views.py:1291-1293(SuggestionActionView.post);jobs/views.py,documents/views.py,_as_intand_taghave not moved, and the test client gives the same four answers.Related to #235 (closed), which fixed this fault on the letter preview with
_as_pkindocuments/views.py:53-58; this issue adds the four views that fix did not reach. Each hands a raw request value to a primary-key lookup. Django raisesValueErrorfor a primary key that is not a number and none of the four catches it, so a mistyped link or an altered form answers 500 and logs a traceback where an empty choice or a 404 was meant.applications/views.py:677-685,ReminderCreateView.get_initial:request.GET.get("application")into.filter(pk=application_id).jobs/views.py:694-702,ContactCreateView.get_initial:request.GET.get("company")into.filter(pk=company_id).jobs/views.py:898-906,PostingCreateView.get_initial: the same with?company=.applications/views.py:1251-1253,SuggestionActionView.post:request.POST.get("application")intoget_object_or_404(Application.objects.for_user(request.user), pk=chosen)./applications/reminders/new/?application=abc, or the new contact or new posting page with?company=abc(a truncated bookmark, a link pasted with a trailing character,?application=12a). The query raisesValueError: Field 'id' expected a number but got 'abc'and the response is 500. The company page links to the new contact page with?company=and the application page links to the new reminder page with?application=, so these are links people follow and share. Posting the accept form of a suggestion (suggestions/<pk>/accept/) withapplication=xfails the same way. All four were reproduced with the test client.ERRORrecord with a traceback that the operator has to read and that hides real failures. It affects only the person's own session; the lookups are narrowed withfor_user()and nothing leaks._as_pkindocuments/views.py:53returnsNone, and_as_intinapplications/views.py:339returns0(used byApplicationBulkView._tagat line 313). Move_as_pkintocore(for examplecore/params.py), replace both private helpers with it, and use it in the four places above. InReminderCreateView.asked_applicationand the twoget_initialmethods injobs/views.py, ignore a value that is not a number. InSuggestionActionView.post, answer 404 for one, as for an id that is not the person's.Done when
tests/test_page_coverage.py, or a newtests/test_query_parameters.py) requestsapplications:reminder_createwith?application=abc, andjobs:contact_createandjobs:posting_createwith?company=abc, and expects 200 with nothing preselected; all three answer 500 today.tests/test_suggestions.pyaccepts a pending suggestion withapplication=xand expects 404; it answers 500 today._as_pkand_as_intno longer exist as private helpers indocuments/views.pyandapplications/views.py; the letter preview test for #235 intests/test_documents.pystill passes.