From 0bf45fd5de08a652dffbfb517318a64c2fdbc5cf Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Fri, 20 Sep 2024 15:56:18 +0300 Subject: [PATCH] Merge commit from fork When a view returns an `HttpResponseNotFound` object, the `Content-Type` header is set to `text/html` by default. Therefore, including external data (in this case, the request ID) in the output without any escaping or validation leads to a vulnerability. If an attacker can trick a user into following a malicious link, they can include HTML elements in the request ID that execute malicious JavaScript code in the victim's browser. That code will be able to make requests to the CVAT API with the user's privileges. The simplest fix for this is to not include variable data in the error message, which is what I did. In the long run, I think we need to get rid of these HTML responses, since it doesn't make sense for a JSON API to return HTML. --- changelog.d/20240912_201524_roman_xss_requests.md | 4 ++++ cvat/apps/engine/views.py | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 changelog.d/20240912_201524_roman_xss_requests.md diff --git a/changelog.d/20240912_201524_roman_xss_requests.md b/changelog.d/20240912_201524_roman_xss_requests.md new file mode 100644 index 00000000000..584291de39a --- /dev/null +++ b/changelog.d/20240912_201524_roman_xss_requests.md @@ -0,0 +1,4 @@ +### Security + +- Fixed an XSS vulnerability in request-related endpoints + () diff --git a/cvat/apps/engine/views.py b/cvat/apps/engine/views.py index 05a50857b28..528c8314b67 100644 --- a/cvat/apps/engine/views.py +++ b/cvat/apps/engine/views.py @@ -3391,7 +3391,7 @@ def retrieve(self, request: HttpRequest, pk: str): job = self._get_rq_job_by_id(pk) if not job: - return HttpResponseNotFound(f"There is no request with specified id: {pk}") + return HttpResponseNotFound("There is no request with specified id") self.check_object_permissions(request, job) @@ -3428,7 +3428,7 @@ def cancel(self, request: HttpRequest, pk: str): rq_job = self._get_rq_job_by_id(pk) if not rq_job: - return HttpResponseNotFound(f"There is no request with specified id: {pk!r}") + return HttpResponseNotFound("There is no request with specified id") self.check_object_permissions(request, rq_job)