CVE-2023-29566 (published 2023-04-24T18:15Z)

huedawn-tesseract 0.3.3 and dawnsparks-node-tesseract 0.4.0 to 0.4.1 was discovered to contain a remote code execution (RCE) vulnerability via the child_process function.

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: CWE-77
cwe_name: Improper Neutralization of Special Elements used in a Command ('Command Injection')
description: The product constructs all or part of a command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended command when it is sent to a downstream component.
extended_description: 
            Many protocols and products have their own custom command language. While OS or shell command strings are frequently discovered and targeted, developers may not realize that these other command languages might also be vulnerable to attacks.
         
         

Fix information:
repo_url: https://github.com/rona-dinihari/dawnsparks-node-tesseract
commit_details: repo_url: https://github.com/rona-dinihari/dawnsparks-node-tesseract
author: Rona Dini Hari
author_date: 2023-03-07 00:43:56+07:00
msg: exec() to execFile()
repository: repo_url: https://github.com/rona-dinihari/dawnsparks-node-tesseract
repo_name: rona-dinihari/dawnsparks-node-tesseract
description: Forked from https://github.com/desmondmorris/node-tesseract/ to support tesseract v4.
repo_language: JavaScript
owner: rona-dinihari
file_changes: filename: tesseract.js
change_type: ModificationType.MODIFY
diff: @@ -4,12 +4,12 @@
  * Module dependencies.
  */
 var utils = require('./utils');
-var exec = require('child_process').exec;
+var execFile = require('child_process').execFile;
 var fs = require('fs');
 var tmpdir = require('os').tmpdir(); // let the os take care of removing zombie tmp files
 var uuid = require('uuid');
 var path = require('path');
-var { glob, } = require("glob");
+var { globSync, } = require("glob");
 
 var Tesseract = {
 
@@ -51,7 +51,7 @@ var Tesseract = {
       callback(Error('Invalid image path'));
       return;
     }
-    
+
     var defaultOptions = utils.merge({}, Tesseract.options);
     options = utils.merge(defaultOptions, options);
 
@@ -65,23 +65,23 @@ var Tesseract = {
     var command = [options.binary, image, output];
 
     if (options.l !== null) {
-      command.push('-l ' + options.l);
+      command.push('-l')
+      command.push(options.l);
     }
 
     if (options.psm !== null) {
-      command.push('--psm ' + options.psm);
+      command.push('--psm')
+      command.push(options.psm);
     }
 
     if (options.config !== null) {
       command.push(options.config);
     }
 
-    command = command.join(' ');
-
     var opts = options.env || {};
 
     // Run the tesseract command
-    exec(command, opts, function(err, stdout, stderr) {
+    execFile(command[0], command.slice(1), opts, function(err, stdout, stderr) {
       if (err) {
         // Something went wrong executing the assembled command
         callback(err, null);
@@ -98,11 +98,9 @@ var Tesseract = {
       }
 
       // Find one of the three possible extension
-      glob(output + '.+(html|hocr|txt)', function(err, files){
-        if (err) {
-          callback(err, null);
-          return;
-        }
+      try {
+        const files = globSync(output + '.{html,hocr,txt}');
+        const readFiles = function(files) {
         fs.readFile(files[0], Tesseract.outputEncoding, function(err, data) {
           if (err) {
             callback(err, null);
@@ -116,7 +114,11 @@ var Tesseract = {
 
           callback(null, data, extra);
         });
-      })
+        };
+        readFiles(files);
+      } catch (err) {
+        callback(err, null);
+      }
     }); // end exec
 
   }

programming_language: JavaScript
filename: package-lock.json
change_type: ModificationType.MODIFY
diff: @@ -1,12 +1,12 @@
 {
-  "name": "dawnsparks-tesseract",
-  "version": "0.4.0",
+  "name": "dawnsparks-node-tesseract",
+  "version": "0.4.1",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
-      "name": "dawnsparks-tesseract",
-      "version": "0.4.0",
+      "name": "dawnsparks-node-tesseract",
+      "version": "0.4.1",
       "license": "MIT",
       "dependencies": {
         "glob": "^9.0.1",

programming_language: JavaScript
filename: package.json
change_type: ModificationType.MODIFY
diff: @@ -1,12 +1,12 @@
 {
   "name": "dawnsparks-node-tesseract",
-  "version": "0.4.0",
+  "version": "0.4.1",
   "author": "Rona Dini Hari <hari.ronadini@gmail.com>",
   "description": "A fork of a simple wrapper for the Tesseract OCR package",
   "main": "index.js",
   "repository": {
     "type": "git",
-    "url": "https://rona_dinihari@bitbucket.org/dawnsparks/dawnsparks-node-tesseract.git"
+    "url": "https://github.com/rona-dinihari/dawnsparks-node-tesseract.git"
   },
   "keywords": [
     "tesseract",

programming_language: JavaScript
filename: tesseract.js
change_type: ModificationType.MODIFY
diff: @@ -9,28 +9,32 @@ const fs = require('fs');
 describe('process', function(){
   it('should return the string "node-tesseract"', function(done){
 
-    var testImage = "\"" + __dirname + '/test.png' + "\"";
+    var testImage = path.join(__dirname, 'test with spaces.png');
 
     tesseract.process(testImage, function(err, text) {
-      text.trim().should.equal('node-tesseract');
-      done();
+      if (err) {
+        done(err);
+      } else {
+        text.trim().should.equal('node-tesseract');
+        done();
+      }
     });
-
-    done();
   })
 })
 
 describe('orientation', function(){
   it('returns orientation equal to 0 using psm 1', function(done){
 
-    var testImage = "\"" + __dirname + '/test.png' + "\"";
+    var testImage = path.join(__dirname, 'test with spaces.png');
 
     tesseract.process(testImage, { psm: 1 }, function(err, text, extra) {
-      extra.orientation.should.equal(0);
-      done();
+      if (err) {
+        done(err);
+      } else {
+        extra.orientation.should.equal(0);
+        done();
+      }
     });
-
-    done();
   })
 })
 

programming_language: JavaScript