CVE-2023-27485: Incorrect Authorization (CWE-863)
value: thmmniii/fbs-core is an open source feedback system for students. In versions prior to 1.5.3 when querying `subresults`, it is possible to query `subresults` from other users due to insufficient authorisation. This is only possible for logged-in users and it is not possible to associate the subresults with a specific user. This bug was fixed in commit `f1ae67d8bb2`and released with version 1.5.3. Users are advised to upgrade. There are no known workarounds for this issue.
CWE description: The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.
CVSS v3 base score: 4.3
Published: 2023-03-07T19:15Z
Repository: https://github.com/thm-mni-ii/feedbacksystem
Language: Scala
Files changed: modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/controller/SubmissionController.scala, modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/services/persistence/CheckrunnerSubTaskService.scala
Commit date: 2023-03-07 13:21:08 +0100
Commit message: Merge pull request from GHSA-fhq8-p3w6-mmgr


Diff: diff --git a/modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/controller/SubmissionController.scala b/modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/controller/SubmissionController.scala
index ddec1605..9ec39958 100644
--- a/modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/controller/SubmissionController.scala
+++ b/modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/controller/SubmissionController.scala
@@ -95,11 +95,11 @@ class SubmissionController {
 
     if (task.hideResult && !adminPrivileged) {
       List()
     } else {
       checkerConfigurationService.getAll(cid, tid).headOption match {
-        case Some(cc) => checkrunnerSubTaskServer.listResultsWithTasks(cc.id, sid)
+        case Some(cc) => checkrunnerSubTaskServer.listResultsWithTasks(uid, cc.id, sid)
         case None => throw new ResourceNotFoundException()
       }
     }
   }
 
diff --git a/modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/services/persistence/CheckrunnerSubTaskService.scala b/modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/services/persistence/CheckrunnerSubTaskService.scala
index 4c809f99..e1315e34 100644
--- a/modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/services/persistence/CheckrunnerSubTaskService.scala
+++ b/modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/services/persistence/CheckrunnerSubTaskService.scala
@@ -109,16 +109,17 @@ class CheckrunnerSubTaskService {
     * Get a list of all subtask results with task information
     * @param configurationId The configuration id for which to get the results
     * @param submissionId The id of the submission to get the subtasks results
     * @return List of subtasks results with tasks
     */
-  def listResultsWithTasks(configurationId: Int, submissionId: Int): List[SubTaskResult] = DB.query(
-    "SELECT st.name, st.points AS max_points, str.points FROM checkrunner_sub_task_result str JOIN " +
-      "checkrunner_sub_task st ON str.sub_task_id = st.sub_task_id " +
-      "WHERE str.configuration_id = ? AND str.submission_id = ?",
+  def listResultsWithTasks(userId: Int, configurationId: Int, submissionId: Int): List[SubTaskResult] = DB.query(
+    "SELECT st.name, st.points AS max_points, str.points FROM checkrunner_sub_task_result str " +
+      "JOIN checkrunner_sub_task st ON str.sub_task_id = st.sub_task_id " +
+      "JOIN user_task_submission uts ON str.submission_id = uts.submission_id " +
+      "WHERE str.configuration_id = ? AND str.submission_id = ? AND uts.user_id = ?",
     (res, _) => parseSubTaskResultWithSubTask(res),
-    configurationId, submissionId
+    configurationId, submissionId, userId
   )
 
   /**
     * Parse SQL Query sub task results
     * @param res SQL Query result

Vulnerable code:         case Some(cc) => checkrunnerSubTaskServer.listResultsWithTasks(cc.id, sid)
  def listResultsWithTasks(configurationId: Int, submissionId: Int): List[SubTaskResult] = DB.query(
    "SELECT st.name, st.points AS max_points, str.points FROM checkrunner_sub_task_result str JOIN " +
      "checkrunner_sub_task st ON str.sub_task_id = st.sub_task_id " +
      "WHERE str.configuration_id = ? AND str.submission_id = ?",
    configurationId, submissionId
Fixed code:         case Some(cc) => checkrunnerSubTaskServer.listResultsWithTasks(uid, cc.id, sid)
  def listResultsWithTasks(userId: Int, configurationId: Int, submissionId: Int): List[SubTaskResult] = DB.query(
    "SELECT st.name, st.points AS max_points, str.points FROM checkrunner_sub_task_result str " +
      "JOIN checkrunner_sub_task st ON str.sub_task_id = st.sub_task_id " +
      "JOIN user_task_submission uts ON str.submission_id = uts.submission_id " +
      "WHERE str.configuration_id = ? AND str.submission_id = ? AND uts.user_id = ?",
    configurationId, submissionId, userId