nav
nav copied to clipboard
[BUG] Maintenance calendar form does not validate input
Describe the bug
The maintenance calendar "search" form has two input fields:
- Year
- Month

These are basically integer fields. However, the view function does not validate the values submited through this form before attempting a redirect to a calendar view function (it instead relies on the browser to "validate" on the client side):
https://github.com/Uninett/nav/blob/e6634e512c8ecf283c85a701366620e724806ab7/python/nav/web/maintenance/views.py#L58-L62
Lately, we are receiving tons of Django e-mails with 500 errors + tracebacks from customers who are running vulnerability scanners against their NAV installations. These scanners submit invalid data through this form (similar to what an attacker would do). While there doesn't seem to be a vulnerability in the NAV code, the input values should be validated, rather than crashing with an unhandled exception.
The resulting exception is due to the fact that the input data is fed directly into a django.shortcuts.redirect
call without validation, causing a NoReverseMatch
exception.
To Reproduce
Steps to reproduce the behavior:
- Browser the maintenance tool from the NAV toolbox
- Use the browser's developer tools to enter an invalid value in the
year
field (e.g.foo
) - Submit the form
- See error
Expected behavior
If the form input is invalid, the calendar should just be re-rendered with an error message, just like any other form in NAV.
The underlying issue here is that there is no Django form that processes the input, it is just used to construct a new URL to which the user is redirected.
Tracebacks
If applicable, add a full traceback message.
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.9/dist-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/source/python/nav/web/maintenance/views.py", line 58, in calendar
return redirect(
File "/usr/local/lib/python3.9/dist-packages/django/shortcuts.py", line 41, in redirect
return redirect_class(resolve_url(to, *args, **kwargs))
File "/usr/local/lib/python3.9/dist-packages/django/shortcuts.py", line 130, in resolve_url
return reverse(to, args=args, kwargs=kwargs)
File "/usr/local/lib/python3.9/dist-packages/django/urls/base.py", line 86, in reverse
return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
File "/usr/local/lib/python3.9/dist-packages/django/urls/resolvers.py", line 698, in _reverse_with_prefix
raise NoReverseMatch(msg)
Exception Type: NoReverseMatch at /maintenance/calendar/
Exception Value: Reverse for 'maintenance-calendar' with keyword arguments '{'year': 'foo', 'month': '6'}' not found. 2 pattern(s) tried: ['maintenance/calendar/(?P<year>\\d{4})/(?P<month>\\d{1,2})$', 'maintenance/calendar/$']
Environment (please complete the following information):
- NAV version installed: 5.4.0
Other considerations
The calendar()
view function does perform some input validation when the year/month data was part of the URL path rather than GET arguments, since it needs to calculate the next/previous months. It would be prudent for the validation code to be extracted from the view function so that it can be applied regardless of whether the data was part of the URL path or passed as GET arguments.