CVE-2013-10012: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value: A vulnerability, which was classified as critical, was found in antonbolling clan7ups. Affected is an unknown function of the component Login/Session. The manipulation leads to sql injection. The name of the patch is 25afad571c488291033958d845830ba0a1710764. It is recommended to apply a patch to fix this issue. The identifier of this vulnerability is VDB-218388.
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-16T11:15Z
Repository: https://github.com/antonbolling/clan7ups
Language: Perl
Files changed: www/cgi-bin/login.pl, www/cgi-bin/session.pl
Commit date: 2013-02-12 21:51:52 -0500
Commit message: this codebase is riddled with sql injection vulnerabilities; fix some of the key vulnerabilities in login/session code

Diff: diff --git a/www/cgi-bin/login.pl b/www/cgi-bin/login.pl
index 842242c..9b04869 100644
--- a/www/cgi-bin/login.pl
+++ b/www/cgi-bin/login.pl
@@ -51,21 +51,21 @@ if ($sth->rows) {
   print "Cannot login using your alias, login with $name instead";
 #  invalid_login($q);
 }
 
 #login is real, check the password
-$sth = $dbh->prepare("select id from users where name='$login' and pass=PASSWORD('$pass')");
-$sth->execute;
+my $login_sql = $dbh->prepare("select id from users where name=? and pass=PASSWORD(?)");
+$login_sql->execute($login,$pass);
 
-my $valid_login = $sth->rows;
-my ($uid) = $sth->fetchrow_array;
+my $valid_login = $login_sql->rows;
+my ($uid) = $login_sql->fetchrow_array;
 
 if ($valid_login) {
   # Login was valid, get the current time.
-  my $sth = $dbh->prepare("select unix_timestamp(now())");
-  $sth->execute;
-  my ($time) = $sth->fetchrow_array;
+  my $time_sql = $dbh->prepare("select unix_timestamp(now())");
+  $time_sql->execute;
+  my ($time) = $time_sql->fetchrow_array;
 
   my $magic = new_session($dbh, $uid);
   my $CGI_params = $q->Vars;
   $CGI_params->{'magic'} = $magic;
   $CGI_params->{'uid'} = $uid;
diff --git a/www/cgi-bin/session.pl b/www/cgi-bin/session.pl
index fd9823d..5d837ea 100644
--- a/www/cgi-bin/session.pl
+++ b/www/cgi-bin/session.pl
@@ -15,12 +15,14 @@ sub new_session {
 #  print "<p>Starting new session for uid $uid.</p>\n";
 
   # Make sequence numbers random.
   my $magic = int rand(2147483648);
 
-  $dbh->do("update users set magic=$magic where id=$uid");
-  $dbh->do("update users set session_stamp=now() where id=$uid");
+  my $sql = $dbh->prepare("update users set magic=? where id=?");
+	$sql->execute($magic,$uid);
+  $sql = $dbh->prepare("update users set session_stamp=now() where id=?");
+	$sql->execute($uid);
 
   return $magic;
 }
 
 # STACK:  $dbh, $q, $time
@@ -32,25 +34,22 @@ sub get_session {
   my $uid = cook_int($q->param('uid'));
   my $cgi_magic = cook_int($q->param('magic'));
 
 #  print "<p>PASSED uid, magic: $uid, $cgi_magic</p>";
 
-  my $sth = $dbh->prepare("select magic, UNIX_TIMESTAMP(now())-UNIX_TIMESTAMP(session_stamp) as elapsed from users where id=$uid");
-  $sth->execute;
+  my $sth = $dbh->prepare("select magic, UNIX_TIMESTAMP(now())-UNIX_TIMESTAMP(session_stamp) as elapsed from users where id=?");
+  $sth->execute($uid);
   my ($db_magic, $elapsed) = $sth->fetchrow_array;
 
 #  print "<p>FOUND magic, elapsed: $db_magic, $elapsed</p>\n";
 
   if (($db_magic == $cgi_magic) and ($elapsed < $session_timeout)) {
     # Set a new session timestamp, update magic.
     my $new_magic = int rand(2147483648);
-    $dbh->do("update users set session_stamp=now(), magic=$new_magic where id=$uid");
+    my $sql = $dbh->prepare("update users set session_stamp=now(), magic=? where id=?");
+		$sql->execute($new_magic,$uid);
 
-    # Put magic into cgi query.
-#    my $vars = $q->Vars;
-#    $vars->{'magic'} = $new_magic;
-    # Successfully continued session...
     return 1;
   }
   else {
     # Couldn't get a session.
     return 0;
@@ -61,12 +60,12 @@ sub get_session {
 # Return: access string. 'user' 'gate' 'admin'
 sub get_access {
   my ($dbh, $q, $view_time) = @_;
   my $uid = cook_int($q->param('uid'));
 
-  my $sth = $dbh->prepare("select access from users where id=$uid");
-  $sth->execute;
+  my $sth = $dbh->prepare("select access from users where id=?");
+  $sth->execute($uid);
   my ($access) = $sth->fetchrow_array;
 
   return $access;
 }
 
@@ -74,12 +73,12 @@ sub no_access {
   my ($dbh, $q, $view_time) = @_;
   my $uid = cook_int($q->param('uid'));
   my $action = cook_word($q->param('action'));
 
   # Log it.
-  my $sth = $dbh->prepare("insert into log (user,action,cdata1) values($uid,'accessdenied','$action')");
-  $sth->execute;
+  my $sth = $dbh->prepare("insert into log (user,action,cdata1) values(?,'accessdenied','$action')");
+  $sth->execute($uid);
 
   # Notify the user.
   print <<EOT;
     <p> You do not have access to this page. Please let an
     administrator know what you did to reach this message; you have
@@ -94,12 +93,12 @@ sub get_session_info {
   my ($dbh, $q, $view_time) = @_;
 
   my $uid = cook_int($q->param('uid'));
   my $magic = cook_int($q->param('magic'));
 
-  my $sth = $dbh->prepare("select magic from users where id=$uid");
-  $sth->execute;
+  my $sth = $dbh->prepare("select magic from users where id=?");
+  $sth->execute($uid);
   my ($nextmagic) = $sth->fetchrow_array;
 
   return "<input type='hidden' name='uid' value='$uid'>\n<input type='hidden' name='magic' value='$nextmagic'>\n";
 }
 

Vulnerable code: $sth = $dbh->prepare("select id from users where name='$login' and pass=PASSWORD('$pass')");
$sth->execute;
my $valid_login = $sth->rows;
my ($uid) = $sth->fetchrow_array;
  my $sth = $dbh->prepare("select unix_timestamp(now())");
  $sth->execute;
  my ($time) = $sth->fetchrow_array;
  $dbh->do("update users set magic=$magic where id=$uid");
  $dbh->do("update users set session_stamp=now() where id=$uid");
  my $sth = $dbh->prepare("select magic, UNIX_TIMESTAMP(now())-UNIX_TIMESTAMP(session_stamp) as elapsed from users where id=$uid");
  $sth->execute;
    $dbh->do("update users set session_stamp=now(), magic=$new_magic where id=$uid");
    # Put magic into cgi query.
#    my $vars = $q->Vars;
#    $vars->{'magic'} = $new_magic;
    # Successfully continued session...
  my $sth = $dbh->prepare("select access from users where id=$uid");
  $sth->execute;
  my $sth = $dbh->prepare("insert into log (user,action,cdata1) values($uid,'accessdenied','$action')");
  $sth->execute;
  my $sth = $dbh->prepare("select magic from users where id=$uid");
  $sth->execute;
Fixed code: my $login_sql = $dbh->prepare("select id from users where name=? and pass=PASSWORD(?)");
$login_sql->execute($login,$pass);
my $valid_login = $login_sql->rows;
my ($uid) = $login_sql->fetchrow_array;
  my $time_sql = $dbh->prepare("select unix_timestamp(now())");
  $time_sql->execute;
  my ($time) = $time_sql->fetchrow_array;
  my $sql = $dbh->prepare("update users set magic=? where id=?");
	$sql->execute($magic,$uid);
  $sql = $dbh->prepare("update users set session_stamp=now() where id=?");
	$sql->execute($uid);
  my $sth = $dbh->prepare("select magic, UNIX_TIMESTAMP(now())-UNIX_TIMESTAMP(session_stamp) as elapsed from users where id=?");
  $sth->execute($uid);
    my $sql = $dbh->prepare("update users set session_stamp=now(), magic=? where id=?");
		$sql->execute($new_magic,$uid);
  my $sth = $dbh->prepare("select access from users where id=?");
  $sth->execute($uid);
  my $sth = $dbh->prepare("insert into log (user,action,cdata1) values(?,'accessdenied','$action')");
  $sth->execute($uid);
  my $sth = $dbh->prepare("select magic from users where id=?");
  $sth->execute($uid);