CVE-2010-10003: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value: A vulnerability classified as critical was found in gesellix titlelink on Joomla. Affected by this vulnerability is an unknown functionality of the file plugin_content_title.php. The manipulation of the argument phrase leads to sql injection. The patch is named b4604e523853965fa981a4e79aef4b554a535db0. It is recommended to apply a patch to fix this issue. The associated identifier of this vulnerability is VDB-217351.
CWE 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.
CVSS v3 base score: 9.8
Published: 2023-01-04T10:15Z
Repository: https://github.com/gesellix/titlelink
Language: PHP
Files changed: j_1_5_x/plugin/changelog.php, j_1_5_x/plugin/titlelink.php, j_1_5_x/plugin/titlelink.xml, j_1_5_x/plugin/titlelink_plugins/plugin_content_title.php
Commit date: 2010-08-08 18:17:54 +0000
Commit message: [#20653] SQL Injection: $phrase is escaped now, yet most of the plugins have to be updated according to plugin_content_title.php


git-svn-id: http://joomlacode.org/svn/titlelink@27 de31ee7e-3f2c-0410-b67e-83f64df8b4ac

Diff: diff --git a/j_1_5_x/plugin/changelog.php b/j_1_5_x/plugin/changelog.php
index 118cc25..cd5072e 100644
--- a/j_1_5_x/plugin/changelog.php
+++ b/j_1_5_x/plugin/changelog.php
@@ -2,10 +2,15 @@
 // Check to ensure this file is included in Joomla!
 defined( '_JEXEC' ) or die('Direct Access to this location is not allowed.');
 
 ?>
 
+2010-08-08:
+
+- [#20653] SQL Injection: $phrase is escaped now, yet most of the plugins have to be updated according to plugin_content_title.php
+
+
 2009-06-06:
 
 - [#16580] Exact Match as default or plugin option
 
 
diff --git a/j_1_5_x/plugin/titlelink.php b/j_1_5_x/plugin/titlelink.php
index f7ac8a6..25a299a 100644
--- a/j_1_5_x/plugin/titlelink.php
+++ b/j_1_5_x/plugin/titlelink.php
@@ -590,14 +590,16 @@ class plgContentTitleLink extends JPlugin
     return $this->startswith($link, "http") && ((isset($domain[3])) and (isset($http[3])) and ($domain[3]!==$http[3]));
 }
 
   function getByPlugins($database, $plugins, $phrase, $partial_match)
   {
+    $phrase_escaped = $database->getEscaped($phrase, true);
+
     $count = count($plugins);
     for ($i = 0; $i < $count; $i++)
     {
-      $result = call_user_func($plugins[$i], $database, $phrase, $partial_match);
+      $result = call_user_func($plugins[$i], $database, $phrase_escaped, $partial_match);
 
       // magix number '2' is the amount of strings we need as result
       if (count($result) == 2)
       {
         return $result;
diff --git a/j_1_5_x/plugin/titlelink.xml b/j_1_5_x/plugin/titlelink.xml
index dbb2f8f..22fbbc4 100644
--- a/j_1_5_x/plugin/titlelink.xml
+++ b/j_1_5_x/plugin/titlelink.xml
@@ -1,15 +1,15 @@
 <?xml version="1.0" encoding="utf-8"?>
 <install version="1.5" type="plugin" group="content" method="upgrade">
 	<name>Content - TitleLink</name>
 	<author>Tobias Gesellchen</author>
 	<creationDate>2008-06-03</creationDate>
-	<copyright>(C) 2005-2009 Tobias Gesellchen. All rights reserved.</copyright>
+	<copyright>(C) 2005-2010 Tobias Gesellchen. All rights reserved.</copyright>
 	<license>http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL</license>
 	<authorEmail>tobias@gesellix.de</authorEmail>
 	<authorUrl>www.gesellix.de</authorUrl>
-	<version>3.2.0 2009-06-06 stable</version>
+	<version>3.2.1 2010-08-08 stable</version>
   <description>DESCTITLELINK</description>
   <files>
     <filename plugin="titlelink">titlelink.php</filename>
     <filename>titlelink_plugins/plugin_content_title.php</filename>
     <filename>titlelink_plugins/plugin_menuitem.php</filename>
diff --git a/j_1_5_x/plugin/titlelink_plugins/plugin_content_title.php b/j_1_5_x/plugin/titlelink_plugins/plugin_content_title.php
index 0f0c900..8abd5b0 100644
--- a/j_1_5_x/plugin/titlelink_plugins/plugin_content_title.php
+++ b/j_1_5_x/plugin/titlelink_plugins/plugin_content_title.php
@@ -25,16 +25,22 @@ function plugin_contentTitle($database, $phrase, $partial_match = true)
   $query .= " LEFT JOIN #__categories AS c ON a.catid = c.id ";
   $query .= " LEFT JOIN #__sections AS s ON a.sectionid = s.id ";
 
   $where_clause = " WHERE a.state=1 ";
 
-  $where_variant = " AND a.alias " . (($partial_match) ? " LIKE '%$phrase%'" : "= '$phrase'");
+  $where_variant = " AND a.alias " .
+  				(($partial_match)
+  					? " LIKE ".$database->quote('%'.$phrase.'%', false)
+    				: "= ".$database->quote($phrase, false));
   $result = findContentInternal($database, $query.$where_clause.$where_variant, false);
 
   if ($result == null)
   {
-    $where_variant = " AND a.title " . (($partial_match) ? " LIKE '%$phrase%'" : "= '$phrase'");
+    $where_variant = " AND a.title " .
+  				(($partial_match)
+  					? " LIKE ".$database->quote('%'.$phrase.'%', false)
+  					: "= ".$database->quote($phrase, false));
   	$result = findContentInternal($database, $query.$where_clause.$where_variant, true);
   }
   
   return $result;
 }

Vulnerable code:       $result = call_user_func($plugins[$i], $database, $phrase, $partial_match);
	<copyright>(C) 2005-2009 Tobias Gesellchen. All rights reserved.</copyright>
	<version>3.2.0 2009-06-06 stable</version>
  $where_variant = " AND a.alias " . (($partial_match) ? " LIKE '%$phrase%'" : "= '$phrase'");
    $where_variant = " AND a.title " . (($partial_match) ? " LIKE '%$phrase%'" : "= '$phrase'");
Fixed code: 2010-08-08:

- [#20653] SQL Injection: $phrase is escaped now, yet most of the plugins have to be updated according to plugin_content_title.php


    $phrase_escaped = $database->getEscaped($phrase, true);

      $result = call_user_func($plugins[$i], $database, $phrase_escaped, $partial_match);
	<copyright>(C) 2005-2010 Tobias Gesellchen. All rights reserved.</copyright>
	<version>3.2.1 2010-08-08 stable</version>
  $where_variant = " AND a.alias " .
  				(($partial_match)
  					? " LIKE ".$database->quote('%'.$phrase.'%', false)
    				: "= ".$database->quote($phrase, false));
    $where_variant = " AND a.title " .
  				(($partial_match)
  					? " LIKE ".$database->quote('%'.$phrase.'%', false)
  					: "= ".$database->quote($phrase, false));