Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions scanpipe/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@
remove_output=request.data.get("remove_output"),
)
except RunInProgressError as error:
return Response(error, status=status.HTTP_400_BAD_REQUEST)
return Response({"status": str(error)}, status=status.HTTP_400_BAD_REQUEST)

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.

Copilot Autofix

AI 2 days ago

To resolve the problem, we need to ensure that the details from the exception are not directly returned to the user. Instead, we should show a generic error message for users while logging the full exception message and stack trace on the server, if needed, for debugging. In scanpipe/api/views.py, within the archive view's except RunInProgressError as error: block (line 426-427), replace the exposure of str(error) to the response with a generic message such as "Cannot archive project while a run is in progress.", and log the error for developers. This may require importing Python's builtin logging module and configuring a logger for the current file.

The required changes:

  • Add a logger import and initialize a logger.
  • In the exception handler at line 427, replace the response content with a generic message (no exception details visible to the user).
  • Log the exception, ideally including the stack trace, so developers still have full details.

Suggested changeset 1
scanpipe/api/views.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/scanpipe/api/views.py b/scanpipe/api/views.py
--- a/scanpipe/api/views.py
+++ b/scanpipe/api/views.py
@@ -28,6 +28,7 @@
 from django.db.models import Q
 from django.http import FileResponse
 
+import logging
 import django_filters
 from rest_framework import mixins
 from rest_framework import renderers
@@ -424,7 +425,11 @@
                 remove_output=request.data.get("remove_output"),
             )
         except RunInProgressError as error:
-            return Response({"status": str(error)}, status=status.HTTP_400_BAD_REQUEST)
+            logger.warning("Run in progress error when archiving project %r: %s", project, error, exc_info=True)
+            return Response(
+                {"status": "Cannot archive project while a run is in progress."},
+                status=status.HTTP_400_BAD_REQUEST
+            )
         else:
             return Response({"status": f"The project {project} has been archived."})
 
EOF
@@ -28,6 +28,7 @@
from django.db.models import Q
from django.http import FileResponse

import logging
import django_filters
from rest_framework import mixins
from rest_framework import renderers
@@ -424,7 +425,11 @@
remove_output=request.data.get("remove_output"),
)
except RunInProgressError as error:
return Response({"status": str(error)}, status=status.HTTP_400_BAD_REQUEST)
logger.warning("Run in progress error when archiving project %r: %s", project, error, exc_info=True)
return Response(
{"status": "Cannot archive project while a run is in progress."},
status=status.HTTP_400_BAD_REQUEST
)
else:
return Response({"status": f"The project {project} has been archived."})

Copilot is powered by AI and may make mistakes. Always verify output.
else:
return Response({"status": f"The project {project} has been archived."})

Expand All @@ -437,13 +437,15 @@
return Response({"status": message})

try:
project.reset(keep_input=True)
project.reset(
keep_input=request.data.get("keep_input", True),
restore_pipelines=request.data.get("restore_pipelines", False),
execute_now=request.data.get("execute_now", False),
)
except RunInProgressError as error:
return Response(error, status=status.HTTP_400_BAD_REQUEST)
return Response({"status": str(error)}, status=status.HTTP_400_BAD_REQUEST)

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.

Copilot Autofix

AI 2 days ago

The correct fix is to replace the direct exposure of str(error) with a generic error message that communicates the error without sharing internal details. Logging the exception message and/or stack trace on the server is advisable for debugging, but the client should only receive an innocuous error statement.
Edits needed:

  • In scanpipe/api/views.py, update the response in the except block of the reset view method so it no longer passes through error details to the client.
  • Optionally, add server-side logging for the actual error to retain debuggability (using Python’s logging module).
  • If logging is added, add an import for logging at the top of the file (if not already present in the shown snippet).

Suggested changeset 1
scanpipe/api/views.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/scanpipe/api/views.py b/scanpipe/api/views.py
--- a/scanpipe/api/views.py
+++ b/scanpipe/api/views.py
@@ -443,7 +443,13 @@
                 execute_now=request.data.get("execute_now", False),
             )
         except RunInProgressError as error:
-            return Response({"status": str(error)}, status=status.HTTP_400_BAD_REQUEST)
+            # Optionally log the error for internal debugging.
+            import logging
+            logging.error(f"Project reset error: {error}")
+            return Response(
+                {"status": "The project could not be reset due to an internal error."},
+                status=status.HTTP_400_BAD_REQUEST
+            )
         else:
             message = f"The {project} project has been reset."
             return Response({"status": message})
EOF
@@ -443,7 +443,13 @@
execute_now=request.data.get("execute_now", False),
)
except RunInProgressError as error:
return Response({"status": str(error)}, status=status.HTTP_400_BAD_REQUEST)
# Optionally log the error for internal debugging.
import logging
logging.error(f"Project reset error: {error}")
return Response(
{"status": "The project could not be reset due to an internal error."},
status=status.HTTP_400_BAD_REQUEST
)
else:
message = f"The {project} project has been reset."
return Response({"status": message})
Copilot is powered by AI and may make mistakes. Always verify output.
else:
message = (
f"All data, except inputs, for the {project} project have been removed."
)
message = f"The {project} project has been reset."
return Response({"status": message})

@action(detail=True, methods=["get"])
Expand Down
5 changes: 1 addition & 4 deletions scanpipe/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -962,10 +962,7 @@ def test_scanpipe_api_project_action_reset(self):

response = self.csrf_client.post(url)
self.assertEqual(status.HTTP_200_OK, response.status_code)
expected = {
"status": "All data, except inputs, for the Analysis project have been "
"removed."
}
expected = {"status": "The Analysis project has been reset."}
self.assertEqual(expected, response.data)
self.assertEqual(0, self.project1.runs.count())
self.assertEqual(0, self.project1.codebaseresources.count())
Expand Down
Loading