CVE-2021-41148 (published 2021-10-15T14:15Z)

Tuleap Open ALM is a libre and open source tool for end to end traceability of application and system developments. Prior to version 11.16.99.173 of Community Edition and versions 11.16-6 and 11.15-8 of Enterprise Edition, an attacker with the ability to add one the CI widget to its personal dashboard could execute arbitrary SQL queries. Tuleap Community Edition 11.16.99.173, Tuleap Enterprise Edition 11.16-6, and Tuleap Enterprise Edition 11.15-8 contain a patch for this issue.

Severity: MEDIUM
CVSS v2 base score: 6.5 (AV:N/AC:L/Au:S/C:P/I:P/A:P)
CVSS v3 base score: 8.8, HIGH (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-89
cwe_name: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
description: The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
extended_description: 
            
            
         
         

Fix information:
repo_url: https://github.com/Enalean/tuleap
commit_details: repo_url: https://github.com/Enalean/tuleap
author: Thomas Gerbet
author_date: 2020-06-26 15:27:50+02:00
msg: request #15028: The update of the CI job targeted by a widget is vulnerable to blind SQL injections

Change-Id: Ib02a01586740b990feb675a8728a006ea20f7777
repository: repo_url: https://github.com/Enalean/tuleap
repo_name: Enalean/tuleap
description: Tuleap is an Open Source Suite to improve management of software developments and collaboration. With a single web-based solution, project managers, developers & quality managers can easily build, deploy software projects.
repo_language: PHP
owner: Enalean
file_changes: filename: HudsonJobWidget.class.php
change_type: ModificationType.MODIFY
diff: @@ -42,17 +42,29 @@ abstract class HudsonJobWidget extends HudsonWidget
         $vId->required();
         if ($request->valid($vId)) {
             $job_id = $request->get($this->widget_id . '_job_id');
-            $sql = 'INSERT INTO plugin_hudson_widget (widget_name, owner_id, owner_type, job_id) VALUES ("' . $this->id . '", ' . $this->owner_id . ", '" . $this->owner_type . "', " . db_escape_int($job_id) . " )";
-            $res = db_query($sql);
-            $content_id = db_insertid($res);
+            $db = \Tuleap\DB\DBFactory::getMainTuleapDBConnection()->getDB();
+            $content_id = (int) $db->insertReturnId(
+                'plugin_hudson_widget',
+                [
+                    'widget_name' => $this->id,
+                    'owner_id'    => $this->owner_id,
+                    'owner_type'  => $this->owner_type,
+                    'job_id'      => $job_id
+                ]
+            );
         }
         return $content_id;
     }
 
     public function destroy($id)
     {
-        $sql = 'DELETE FROM plugin_hudson_widget WHERE id = ' . $id . ' AND owner_id = ' . $this->owner_id . " AND owner_type = '" . $this->owner_type . "'";
-        db_query($sql);
+        $db = \Tuleap\DB\DBFactory::getMainTuleapDBConnection()->getDB();
+        $db->run(
+            'DELETE FROM plugin_hudson_widget WHERE id = ? AND owner_id = ? AND owner_type = ?',
+            $id,
+            $this->owner_id,
+            $this->owner_type,
+        );
     }
 
     public function getPreferences($widget_id)
@@ -120,8 +132,14 @@ abstract class HudsonJobWidget extends HudsonWidget
         $request->valid(new Valid_String('cancel'));
         if (!$request->exist('cancel')) {
             $job_id = $request->get($this->widget_id . '_job_id');
-            $sql = "UPDATE plugin_hudson_widget SET job_id=" . $job_id . " WHERE owner_id = " . $this->owner_id . " AND owner_type = '" . $this->owner_type . "' AND id = " . (int) $request->get('content_id');
-            $res = db_query($sql);
+            $db = \Tuleap\DB\DBFactory::getMainTuleapDBConnection()->getDB();
+            $db->run(
+                'UPDATE plugin_hudson_widget SET job_id=? WHERE owner_id = ? AND owner_type = ? AND id = ?',
+                $job_id,
+                $this->owner_id,
+                $this->owner_type,
+                $this->content_id,
+            );
         }
         return true;
     }
@@ -133,19 +151,19 @@ abstract class HudsonJobWidget extends HudsonWidget
      */
     protected function getJobIdFromWidgetConfiguration()
     {
-        $sql = "SELECT *
-                    FROM plugin_hudson_widget
-                    WHERE widget_name = '" . db_es($this->widget_id) . "'
-                      AND owner_id = " . db_ei($this->owner_id) . "
-                      AND owner_type = '" . db_es($this->owner_type) . "'
-                      AND id = " . db_ei($this->content_id);
-
-        $res = db_query($sql);
-        if ($res && db_numrows($res)) {
-            $data   = db_fetch_array($res);
-            return $data['job_id'];
+        $db = \Tuleap\DB\DBFactory::getMainTuleapDBConnection()->getDB();
+        $job_id = $db->cell(
+            'SELECT job_id FROM plugin_hudson_widget WHERE widget_name = ? AND owner_id = ? AND owner_type = ? AND id = ?',
+            $this->widget_id,
+            $this->owner_id,
+            $this->owner_type,
+            $this->content_id,
+        );
+
+        if ($job_id === false) {
+            return null;
         }
 
-        return null;
+        return $job_id;
     }
 }

programming_language: PHP