CVE-2021-44663 (published 2022-02-24T19:15Z)

A Remote Code Execution (RCE) vulnerability exists in the Xerte Project Xerte through 3.8.4 via a crafted php file through elfinder in connetor.php.

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

Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/thexerteproject/xerteonlinetoolkits
commit_details: repo_url: https://github.com/thexerteproject/xerteonlinetoolkits
author: Tom Reijnders
author_date: 2020-03-27 13:13:00+01:00
msg: Security patch - Thank you Rik Lutz

 - Fixed and stopped possibility to upload constructed php files throgh
   elfinder
 - Added .htaccess files to try to tighten security on apache servers
 - Always use extension blacklist (ignore management page setting)
 - Stop XSS in print
 - Several other small improvements
repository: repo_url: https://github.com/thexerteproject/xerteonlinetoolkits
repo_name: thexerteproject/xerteonlinetoolkits
description: Xerte Online Toolkits
repo_language: JavaScript
owner: thexerteproject
file_changes: filename: .htaccess
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,8 @@ Options -Indexes
 # Try and tell Apache not to serve out any files within this directory as PHP - 
 # this helps close a potential security flaw - given people can upload almost anything into an LO.
 
-#RemoveHandler .php
-<FilesMatch "\.((php[0-9]?)|p?html?|pl|sh|java|cpp|c|h|js|rc)$">
-    SetHandler None
-</FilesMatch>
+#prevent execution of php code (and other code)
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteRule .*\.(php|php[0-9]|phtml|pl|sh|java|py)$ - [F]
+</IfModule>
\ No newline at end of file

programming_language: Markdown
filename: browse.php
change_type: ModificationType.MODIFY
diff: @@ -22,6 +22,39 @@
  * Created by Tom Reijnders
  */
 
+require_once "../../config.php";
+
+if(empty($_SESSION['toolkits_logon_id'])) {
+    die("Please login");
+}
+
+// if there are GET paramters, put them in session and restart
+if (isset($_GET['uploadDir']) && isset($_GET['uploadURL']))
+{
+    $_SESSION['uploadDir'] = $_REQUEST['uploadDir'];
+    $_SESSION['uploadURL'] = $_REQUEST['uploadURL'];
+
+    $params = "?";
+    foreach($_GET as $key => $param)
+    {
+        if ($key != "uploadDir" && $key != "uploadURL")
+        {
+            if (strlen($params) > 1)
+            {
+                $params .= "&";
+            }
+            $params .= $key . "=" . $param;
+        }
+    }
+
+    header("Location: " . $_SERVER["SCRIPT_NAME"] . $params);
+}
+
+if (strpos($_SESSION['uploadDir'], 'USER-FILES') === false || strpos($_SESSION['uploadURL'], 'USER-FILES') === false)
+{
+    die("Invalid upload location");
+}
+
 $mode = 'standalone';
 if (isset($_REQUEST['mode']) && $_REQUEST['mode']=='cke') {
     $mode = 'cke';
@@ -88,7 +121,7 @@ if (isset($_REQUEST['langCode']))
             ?>
 
             $('#elfinder').elfinder({
-                url : 'php/connector.php?uploadDir=<?php echo $_REQUEST['uploadDir'];?>&uploadURL=<?php echo $_REQUEST['uploadURL'];?>',       // connector URL (REQUIRED)
+                url : 'php/connector.php?uploadDir=<?php echo $_SESSION['uploadDir'];?>&uploadURL=<?php echo $_SESSION['uploadURL'];?>',       // connector URL (REQUIRED)
                 lang: '<?php echo $lang;?>',     // language (OPTIONAL)
                 uiOptions : {
                     // toolbar configuration

programming_language: PHP
filename: connector.php
change_type: ModificationType.MODIFY
diff: @@ -90,10 +90,10 @@ $opts = array(
 			'path'          => $rootpath . "/media",         // path to files (REQUIRED)
 			'URL'           => $rooturl . "/media", // URL to files (REQUIRED)
 			'accessControl' => 'access',             // disable and hide dot starting files (OPTIONAL)
-            'tmbPath'       => $rootpath . "/media//.tmb",
+            'tmbPath'       => $rootpath . "/media/.tmb",
             'tmbURL'        => $rooturl . "/media/.tmb",
             'tmbCrop'       => false,
-            'uploadDeny' => array('text/x-php'),
+            'uploadDeny' => array('text/x-php','application/x-php'),
             'attributes' => array(
                 array( // hide readmes
                     'pattern' => '/\.(txt|html|php|php5|php*|py|pl|sh|xml)$/i',

programming_language: PHP
filename: elFinderVolumeDriver.class.php
change_type: ModificationType.MODIFY
diff: @@ -2193,6 +2193,10 @@ abstract class elFinderVolumeDriver {
 				if ($ext && preg_match('~^application/(?:octet-stream|(?:x-)?zip)~', $type)) {
 					if (isset(elFinderVolumeDriver::$mimetypes[$ext])) $type = elFinderVolumeDriver::$mimetypes[$ext];
 				}
+				if ($ext && strpos($type, "text/plain") === 0)
+                {
+                    if (isset(elFinderVolumeDriver::$mimetypes[$ext])) $type = elFinderVolumeDriver::$mimetypes[$ext];
+                }
 			}
 		} elseif ($type == 'mime_content_type') {
 			$type = mime_content_type($path);

programming_language: PHP
filename: mime.types
change_type: ModificationType.MODIFY
diff: @@ -227,7 +227,7 @@ application/x-palm-database pdb prc
 application/x-par2 PAR2 par2
 application/x-pef-executable
 application/x-perl pl pm al perl
-application/x-php php php3 php4
+application/x-php php php3 php4 php5
 application/x-pkcs12 p12 pfx
 application/x-planner planner mrproject
 application/x-planperfect pln

programming_language: TeX
filename: .htaccess
change_type: ModificationType.ADD
diff: @@ -0,0 +1,12 @@
+# Stop Apache doing directory indexing.
+Options -Indexes 
+
+
+# Try and tell Apache not to serve out any files within this directory as PHP - 
+# this helps close a potential security flaw - given people can upload almost anything into an LO.
+
+#prevent execution of php code (and other code)
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteRule .*\.(php|php[0-9]|phtml|pl|sh|java|py|log)$ - [F]
+</IfModule>
\ No newline at end of file

programming_language: Markdown
filename: .htaccess
change_type: ModificationType.ADD
diff: @@ -0,0 +1,12 @@
+# Stop Apache doing directory indexing.
+Options -Indexes 
+
+
+# Try and tell Apache not to serve out any files within this directory as PHP - 
+# this helps close a potential security flaw - given people can upload almost anything into an LO.
+
+#prevent execution of php code (and other code)
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteRule .*\.(php|php[0-9]|phtml|pl|sh|java|py)$ - [F]
+</IfModule>
\ No newline at end of file

programming_language: Markdown
filename: .htaccess
change_type: ModificationType.ADD
diff: @@ -0,0 +1,12 @@
+# Stop Apache doing directory indexing.
+Options -Indexes 
+
+
+# Try and tell Apache not to serve out any files within this directory as PHP - 
+# this helps close a potential security flaw - given people can upload almost anything into an LO.
+
+#prevent execution of php code (and other code)
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteRule .*\.(php|php[0-9]|phtml|pl|sh|java|py)$ - [F]
+</IfModule>
\ No newline at end of file

programming_language: Markdown
filename: .htaccess
change_type: ModificationType.ADD
diff: @@ -0,0 +1,12 @@
+# Stop Apache doing directory indexing.
+Options -Indexes 
+
+
+# Try and tell Apache not to serve out any files within this directory as PHP - 
+# this helps close a potential security flaw - given people can upload almost anything into an LO.
+
+#prevent execution of php code (and other code)
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteRule .*\.(php|php[0-9]|phtml|pl|sh|java|py)$ - [F]
+</IfModule>
\ No newline at end of file

programming_language: Markdown
filename: .htaccess
change_type: ModificationType.ADD
diff: @@ -0,0 +1,12 @@
+# Stop Apache doing directory indexing.
+Options -Indexes 
+
+
+# Try and tell Apache not to serve out any files within this directory as PHP - 
+# this helps close a potential security flaw - given people can upload almost anything into an LO.
+
+#prevent execution of php code (and other code)
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteRule .*\.(php|php[0-9]|phtml|pl|sh|java|py)$ - [F]
+</IfModule>
\ No newline at end of file

programming_language: Markdown
filename: .htaccess
change_type: ModificationType.ADD
diff: @@ -0,0 +1,12 @@
+# Stop Apache doing directory indexing.
+Options -Indexes 
+
+
+# Try and tell Apache not to serve out any files within this directory as PHP - 
+# this helps close a potential security flaw - given people can upload almost anything into an LO.
+
+#prevent execution of php code (and other code)
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteRule .*\.(php|php[0-9]|phtml|pl|sh|java|py)$ - [F]
+</IfModule>
\ No newline at end of file

programming_language: Markdown
filename: .htaccess
change_type: ModificationType.ADD
diff: @@ -0,0 +1,12 @@
+# Stop Apache doing directory indexing.
+Options -Indexes 
+
+
+# Try and tell Apache not to serve out any files within this directory as PHP - 
+# this helps close a potential security flaw - given people can upload almost anything into an LO.
+
+#prevent execution of php code (and other code)
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteRule .*\.(php|php[0-9]|phtml|pl|sh|java|py)$ - [F]
+</IfModule>
\ No newline at end of file

programming_language: Markdown
filename: .htaccess
change_type: ModificationType.ADD
diff: @@ -0,0 +1,12 @@
+# Stop Apache doing directory indexing.
+Options -Indexes 
+
+
+# Try and tell Apache not to serve out any files within this directory as PHP - 
+# this helps close a potential security flaw - given people can upload almost anything into an LO.
+
+#prevent execution of php code (and other code)
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteRule .*\.(php|php[0-9]|phtml|pl|sh|java|py)$ - [F]
+</IfModule>
\ No newline at end of file

programming_language: Markdown
filename: .htaccess
change_type: ModificationType.ADD
diff: @@ -0,0 +1,12 @@
+# Stop Apache doing directory indexing.
+Options -Indexes 
+
+
+# Try and tell Apache not to serve out any files within this directory as PHP - 
+# this helps close a potential security flaw - given people can upload almost anything into an LO.
+
+#prevent execution of php code (and other code)
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteRule .*\.(php|php[0-9]|phtml|pl|sh|java|py)$ - [F]
+</IfModule>
\ No newline at end of file

programming_language: Markdown
filename: .htaccess
change_type: ModificationType.ADD
diff: @@ -0,0 +1,12 @@
+# Stop Apache doing directory indexing.
+Options -Indexes 
+
+
+# Try and tell Apache not to serve out any files within this directory as PHP - 
+# this helps close a potential security flaw - given people can upload almost anything into an LO.
+
+#prevent execution of php code (and other code)
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteRule .*\.(php|php[0-9]|phtml|pl|sh|java|py)$ - [F]
+</IfModule>
\ No newline at end of file

programming_language: Markdown
filename: file_uploading-extension-check.php
change_type: ModificationType.MODIFY
diff: @@ -84,7 +84,10 @@ function filter_by_extension_name() {
     return $args[0];
 }
 
-if (Xerte_Validate_FileExtension::canRun() && $xerte_toolkits_site->enable_file_ext_check) {
+// TOR 2020-03-24
+// Force extension check, so DO NOT CHECK $xerte_toolkits_site->enable_file_ext_check
+//if (Xerte_Validate_FileExtension::canRun() && $xerte_toolkits_site->enable_file_ext_check) {
+if (Xerte_Validate_FileExtension::canRun()) {
     Xerte_Validate_FileExtension::$BLACKLIST = $xerte_toolkits_site->file_extensions;
     add_filter('editor_upload_file', 'filter_by_extension_name');
 }

programming_language: PHP
filename: index.php
change_type: ModificationType.MODIFY
diff: @@ -35,8 +35,8 @@ body {
     <form id="form1" name="form1" method="get" action="print.php">
       <p>To see how this works use the example below or paste the full link to your own LO.</p>
       <p>
-        <label>Link to LO:
-          <input name="link" type="text" id="link" value="http://training.mitchellmedia.co.uk/xerte/play.php?template_id=96" size="100" />
+        <label>The template id of the LO, :
+          <input name="template_id" type="text" id="template_id" value="" size="80" />
         </label>
       </p>
       <p>Print LO pages: 

programming_language: HTML
filename: print.php
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,6 @@
+<?php
+require_once("../config.php");
+?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
@@ -30,12 +33,14 @@ body {
 
 <div id="container">
   <div id="mainContent">
-    <h1><?php 
+    <p><?php
 	$hide=$_GET["hide"];
-	$link=$_GET["link"];
+	$template_id=$_GET["template_id"];
 	$from=$_GET["from"];
 	$to=$_GET["to"];
-	
+
+	// Create the link
+    $link = $xerte_toolkits_site->site_url . "play.php?template_id=" . $template_id;
 	#echo $link."<br>";
 while($from <= $to)
   {

programming_language: PHP
filename: htaccess.conf
change_type: ModificationType.MODIFY
diff: @@ -1,4 +1,4 @@
-Options +FollowSymLinks
+Options +FollowSymLinks -Indexes
 
 rewriteEngine on
 

programming_language: Shell
filename: fileupload.php
change_type: ModificationType.MODIFY
diff: @@ -20,6 +20,12 @@
 require_once "../../../config.php";
 require_once "../../../plugins.php";
 
+if (!isset($_SESSION['toolkits_logon_username']))
+{
+    _debug("Session is invalid or expired");
+    die("Session is invalid or expired");
+}
+
 _load_language_file("/website_code/php/import/fileupload.inc");
 
 if(apply_filters('editor_upload_file', $_FILES)){

programming_language: PHP
filename: upload.php
change_type: ModificationType.MODIFY
diff: @@ -17,6 +17,12 @@ _load_language_file("/website_code/php/management/upload.inc");
 global $xerte_toolkits_site;
 $prefix = $xerte_toolkits_site->database_table_prefix;
 
+if (!isset($_SESSION['toolkits_logon_username']))
+{
+    _debug("Session is invalid or expired");
+    die("Session is invalid or expired");
+}
+
 if($_FILES['fileToUpload']['error'] == 4)
 {
     exit(TEMPLATE_UPLOAD_NO_FILE_SELECTED);

programming_language: PHP