CVE-2022-21666 (PHP, published 2022-01-10T20:15Z)
Description: value: Useful Simple Open-Source CMS (USOC) is a content management system (CMS) for programmers. Versions prior to Pb2.4Bfx3 allowed Sql injection in usersearch.php only for users with administrative privileges. Users should replace the file `admin/pages/useredit.php` with a newer version. USOC version Pb2.4Bfx3 contains a fixed version of `admin/pages/useredit.php`.
Severity: MEDIUM (CVSS v3 base score: 7.2)
Weakness: CWE-89 \u2014 Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
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.
Repository: https://github.com/Aaron-Junker/USOC
Files changed:
admin/pages/usersearch.php
Commit message: Update usersearch.php

Vulnerable code:
    if($U->userHasPermission("Backend", "User","Search")){
    <!DOCTYPE html>
    <html lang="<?php echo $U->getSetting("site.lang"); ?>" dir="ltr">
        <head>
            <style>
                tbody > tr > th {
                    font-weight: normal;
                }
            </style>
            <meta charset="utf-8">
            <title><?php echo $U->getLang("admin") ?> - <?php echo $U->getLang("admin.user.search"); ?></title>
        </head>
        <body>
            <a href="javascript:window.close()"><?php echo $U->getLang("admin.exit"); ?></a>
            <p><?php echo $U->getLang("admin.user.search.intro"); ?></p>
            <form>
                <label for="Name"><?php echo $U->getLang("admin.user.field.username"); ?>:</label><br />
                <input type="text" name="Name" /><br />
                <label for="Mail"><?php echo $U->getLang("admin.user.field.mail"); ?>:</label><br />
                <input type="mail" name="Mail" /><br />
                <input type="hidden" name="URL" value="usersearch" />
                <input type="submit" value="<?php echo $U->getLang("admin.user.search.action"); ?>" />
            </form>
            <?php
                if(isset($_GET["Name"])){
                    if($_GET["Name"] !== ""){
                        $sql = "SELECT * FROM User WHERE Username='".mysqli::real_escape_string($_GET["Name"])."';";
                        $dbRes = mysqli_query($U->db_link, $sql);
                    }
                }
                if(isset($_GET["Mail"])){
                    if($_GET["Mail"] !== ""){
                        $sql = "SELECT * FROM User WHERE Mail='".mysqli::real_escape_string($_GET["Mail"])."';";
                        $dbRes = mysqli_query($U->db_link, $sql);
                    }
                }
                if(isset($_GET["Id"])){
                    if($_GET["Id"] !== ""){
                        $sql = "SELECT * FROM User WHERE Id='".mysqli::real_escape_string($_GET["Id"])."';";
                        $dbRes = mysqli_query($U->db_link, $sql);
                    }
                }
                if(isset($_GET["Mail"]) || isset($_GET["Name"]) || isset($_GET["Id"])){
                    $userhere = False;
                    while($row = mysqli_fetch_array($dbRes, MYSQLI_ASSOC)){
                        $userhere = True;
            ?>
                        <h4><?php echo str_replace("%a",$row["Username"],$U->getLang("admin.user.search.title")); ?></h4>
                        <table>
                            <tbody>
                                <tr>
                                    <th>
                                        Id:
                                    </th>
                                    <th>
                                        <?php echo $row["Id"]; ?>
                                    </th>
                                </tr>
                                <tr>
                                    <th>
                                        <?php echo $U->getLang("admin.user.field.mail"); ?>:
                                    </th>
                                    <th>
                                        <?php echo $row["Mail"]; ?>
                                    </th>
                                </tr>
                                <tr>
                                    <th>
                                        <?php echo $U->getLang("admin.user.field.permissionlevel"); ?>
                                    </th>
                                    <th>
                                        <?php echo $U->getPermissionName($row["Type"]); ?>
                                    </th>
                                </tr>
                                <tr>
                                    <th>
                                        <?php echo $U->getLang("admin.user.field.blocked"); ?>
                                    </th>
                                    <th>
                                        <?php echo $row["blocked"]==0?$U->getLang("admin.no"):$U->getLang("admin.yes"); ?>
                                    </th>
                                </tr>
                            </tbody>
                        </table>
            <?php
                    }
                    if(!$userhere&&isset($_GET["Mail"])&&$_GET["Mail"]!==""){
                        echo str_replace("%a", $U->getLang("admin.user.field.mail"), str_replace("%b", $_GET["Mail"], $U->getLang("admin.user.notFound.property")));
                    }
                    if(!$userhere&&isset($_GET["Name"])&&$_GET["Name"]!==""){
                        echo str_replace("%a", $U->getLang("admin.user.field.username"), str_replace("%b", $_GET["Name"], $U->getLang("admin.user.notFound.property")));
                    }
                    if(!$userhere&&isset($_GET["Id"])){
                        echo str_replace("%a", $U->getLang("admin.user.field.id"), str_replace("%b", $_GET["Id"], $U->getLang("admin.user.notFound.property")));
                    }
            ?>
        </body>
    </html>
      <title><?php echo $U->getLang("admin") ?> - <?php echo $U->getLang("admin.settings"); ?></title>
        <a href="javascript:window.close()"><?php echo $U->getLang("admin.exit"); ?></a>

Fixed code:
  if($U->userHasPermission("Backend", "User")){
  <!DOCTYPE html>
  <html lang="<?php echo $U->getSetting("site.lang"); ?>" dir="ltr">
    <head>
      <meta charset="utf-8">
      <title><?php echo $U->getLang("admin") ?> - <?php echo $U->getLang("admin.user.edit"); ?></title>
    </head>
    <body>
      <a href="<?php echo $_SERVER['PHP_SELF']; ?>?URL=mainpage"><?php echo $U->getLang("admin.back"); ?></a>
      <?php
        if(isset($_POST["N"])&& !isset($_POST["Submit"])){
          $sql = "SELECT * FROM user WHERE id='".mysqli::real_escape_string($_POST["N"])."';";
          $dbRes = mysqli_query($U->db_link, $sql);
          $userhere = False;
          while($row = mysqli_fetch_array($dbRes, MYSQLI_ASSOC)){
            $user_Type = $row["Type"];
            $user_Blocked = $row["blocked"];
            $userhere = True;
          }
          if($userhere){
            if($_SESSION["User_ID"] !== md5($_POST["N"])){
    ?>
              <form action="<?php echo $_SERVER['PHP_SELF']; ?>?URL=useredit" method="post">
                <?php
                  if($U->userHasPermission("Backend", "User","Permission")){
                ?>
                  <label for="A"><?php echo $U->getLang("admin.user.permissionLevel"); ?></label>
                  <select name="A" type="checkbox" value="<?php echo $user_Type; ?>">
                    <?php
                      // Creates a select list with all permission levels
                      foreach($U->getPermissionName(-1) as $key => $value){
                        echo "<option name='".$key."'".($key==$user_Type?" selected":"").">".$value."</option>";
                      }
                    ?>
                  </select>
                  <br />
                <?php
                  }
                  if($U->userHasPermission("Backend", "User","Block")){
                ?>
                    <label for="G"><?php echo $U->getLang("admin.user.block"); ?></label>
                    <input name="G" type="checkbox" <?php echo $user_Blocked=="1"?"checked":""; ?> /><br />
                <?php
                  }
                  if($U->userHasPermission("Backend", "User","Permission")||$U->userHasPermission("Backend", "User","Block")){
                ?>
                    <input type="submit" name="Submit"/>
                    <input type='hidden' name='N' value='<?php echo $_POST["N"]; ?>' />
                <?php
                  }
                ?>
              </form>
              <?php
                if($U->userHasPermission("Backend", "User","Search")){
              ?>
                <!-- Link to user search page (Opens in a pop-up) --> 
                <a href="javascript:window.open('index.php?URL=usersearch&Id=<?php echo $_POST["N"]; ?>', 'Search user', 'width=500,height=500,status=no,titlebar=no,location=no,toolbar=no,left=300');"><?php echo $U->getLang("admin.user.moreInformation"); ?></a>
              <?php
              ?>
    <?php            
            }else{
              echo "<br />".$U->getLang("admin.user.yourself");
            }
          }else{
            echo "<br />".str_replace("%a", $_POST["N"], $U->getLang("admin.user.notFound"));
          }
        }elseif(isset($_POST["Submit"])){
          if(isset($_POST["A"])&&$U->userHasPermission("Backend", "User","Permission")){
            $permissionLevel = $_POST["A"];
          }elseif(!$U->userHasPermission("Backend", "User","Permission")){
            $permissionLevel = false;
          }
          if(isset($_POST["G"])&&$U->userHasPermission("Backend", "User","Block")){
            $b = 1;
          }elseif($U->userHasPermission("Backend", "User","Block")){
            $b = 0;
          }else{
            $b = false;
          }
          if($_SESSION["User_ID"] !== md5($_POST["N"])){
            $sql = "UPDATE User ".($permissionLevel === false?"":"SET Type='".$permissionLevel."'".($b==false?"":", ")).($b==false?"":"blocked ='".$b."' ")."WHERE Id='".mysqli::real_escape_string($_POST["N"])."';";
            $dbRes = mysqli_query($U->db_link, $sql);
            echo "<br />".$U->getLang("admin.user.changed");
          }else{
            // When the user tries to edit himself
            echo "<br />".$U->getLang("admin.user.yourself");
          }
        }else{
          $sql = "SELECT * FROM User;";
          $dbRes = mysqli_query($U->db_link, $sql);
          // Allow only values in the range from the lowest Id to the highest id
          $highestId = 0;
          // BUG: #54 Lowest ID don't work if over 10000000000000000000000000 accounts are created
          $lowestId = 10000000000000000000000000;
          while($row = mysqli_fetch_array($dbRes, MYSQLI_ASSOC)){
            if($row["Id"] > $highestId){
              $highestId = $row["Id"];
            }
            if($row["Id"] < $lowestId){
              $lowestId = $row["Id"];
            }
          }
          $text = <<<'HEREDOC'
          <form action="$_SERVER["PHP_SELF"]?URL=useredit" method="post">
            <label for="N">ID:</label><input name="N" type="number" min="%b" max="%a" />
            <input type="submit" />
          </form>
          HEREDOC;
          $text = str_replace('$_SERVER["PHP_SELF"]', $_SERVER['PHP_SELF'], $text);
          $text = str_replace('%a', $highestId, $text);
          $text = str_replace('%b', $lowestId, $text);
          echo $text;
          if($U->userHasPermission("Backend", "User","Search")){
      ?>
            <!-- Link to user search page (Opens in a pop-up) -->
            <a href="javascript:window.open('index.php?URL=usersearch', 'Search user', 'width=500,height=500,status=no,titlebar=no,location=no,toolbar=no,left=300');"><?php echo $U->getLang("admin.user.search"); ?></a>
      <?php
          }
        }
      ?>
    </body>
  </html>
      <title><?php echo $U->getLang("admin") ?> - <?php echo $U->getLang("admin.user"); ?></title>
      <a href="<?php echo $_SERVER['PHP_SELF']; ?>?URL=mainpage"><?php echo $U->getLang("admin.back"); ?></a>