-
-
Notifications
You must be signed in to change notification settings - Fork 288
[fix] Ensure malformed UUID URLs return 404 #682 #1154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 2 commits
ed5eb49
b764e67
0348df0
8a96299
7e30f8c
22b354f
b860b75
fd3641d
083c900
8977a73
d3fbb24
b6239c9
40789e3
4d79d4f
b700608
d3ded63
96955e3
9189fa6
5828d87
54d2df9
465f19d
12565e9
056609b
c9ef2a3
e8ce4c8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1405,6 +1405,52 @@ def test_change_device_malformed_uuid(self): | |
| response = self.client.get(path) | ||
| self.assertEqual(response.status_code, 404) | ||
|
|
||
| def test_malformed_admin_urls_return_404(self): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this test is missing the point. The issue is about the endpoints to download configurations, but these tests are not focusing on the main issue but on other URLs. Please focus on replicating the bug reported in the issue description: the download URL, which affects device, template and vpn. The other admin URLs are fine.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll modify this test to only assert that the status code isnt 500 for the download url for device, template and vpn. |
||
| device = self._create_device() | ||
| template = self._create_template() | ||
| vpn = self._create_vpn() | ||
| test_cases = [ | ||
| ("device", device.pk, "config_device"), | ||
| ("template", template.pk, "config_template"), | ||
| ("vpn", vpn.pk, "config_vpn"), | ||
| ] | ||
| junk_path = "some/junk/path/here/" | ||
| original_bug_junk = "history/1564/undefinedadmin/img/icon-deletelink.svg" | ||
|
|
||
| for model_name, valid_pk, model_admin_name in test_cases: | ||
| with self.subTest(model=model_name): | ||
| change_url_name = f"admin:{model_admin_name}_change" | ||
| valid_change_url = reverse(change_url_name, args=[valid_pk]) | ||
| malformed_change_url = f"{valid_change_url}{junk_path}" | ||
| response_change = self.client.get(malformed_change_url, follow=False) | ||
|
|
||
| self.assertEqual( | ||
| response_change.status_code, | ||
| 404, | ||
| (f'Malformed "change" URL for {model_name} did not return 404. '), | ||
| ) | ||
| history_url_name = f"admin:{model_admin_name}_history" | ||
| valid_history_url = reverse(history_url_name, args=[valid_pk]) | ||
| malformed_history_url = f"{valid_history_url}{junk_path}" | ||
| response_history = self.client.get(malformed_history_url, follow=False) | ||
|
|
||
| self.assertEqual( | ||
| response_history.status_code, | ||
| 404, | ||
| (f'Malformed "history" URL for {model_name} did not return 404. '), | ||
| ) | ||
| original_bug_url = f"{valid_history_url}{original_bug_junk}" | ||
| response_original_bug = self.client.get(original_bug_url, follow=False) | ||
|
|
||
| self.assertEqual( | ||
| response_original_bug.status_code, | ||
| 404, | ||
| ( | ||
| f"Original bug URL for {model_name} did not return 404. " | ||
| "This may be a regression of bug #682." | ||
| ), | ||
| ) | ||
|
|
||
| def test_uuid_field_in_change(self): | ||
| t = Template.objects.first() | ||
| d = self._create_device() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see these being added back below. Why is this being done, what problems does this solve?
At minimum we need an explanatory comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nemesifier
these 3 default urls which operate at the object level accept an object_id for which the default matching is rather permissive, which allowed malformed paths to be captured and routed to the view layer. This is what caused the 500 instead of returning a 404 in the first place. So to fix the two safe (non-object) urls are left unchanged and the three object-level urls are overriden using a strict uuid-compatible pattern.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this was a real issue, we should open a bug report to Django and we should fix a lot more URLs than these. But I don't think this is a real issue.
I removed this code and brought back the original admin URLs, then changed the assertions to print:
Status code is 302, which is fine.
The issue is specifically asking about a case in which the response is 500 internal server error, those are the case we must focus on, this issue is casued by the URLs defined by us, not Django, we shouldn't spend effort trying to fix problems that do not exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the reason I did these changes was because when I was manually testing that url after the minimal fix for /download it fallbacks to the same garbage url appended with /change and the same NoReverseMatch error. But you are right thats out of the scope of the bug we are trying to fix which is for /download. I'll keep the changes minimal in the next commit and post photo of what happened when I manually tested it.