CVE-2017-20171 (published 2023-01-17T23:15Z)

A vulnerability classified as critical has been found in PrivateSky apersistence. This affects an unknown part of the file db/sql/mysqlUtils.js. The manipulation leads to sql injection. The identifier of the patch is 954425f61634b556fe644837a592a5b8fcfca068. It is recommended to apply a patch to fix this issue. The identifier VDB-218457 was assigned to this vulnerability.

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-89
cwe_name: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
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.
extended_description: 
            
            
         
         

Fix information:
repo_url: https://github.com/PrivateSky/apersistence
commit_details: repo_url: https://github.com/PrivateSky/apersistence
author: ciprian
author_date: 2017-04-10 09:29:58+03:00
msg: fixed SQL injection bug and changed type boolean from bit to tinyint
repository: repo_url: https://github.com/PrivateSky/apersistence
repo_name: PrivateSky/apersistence
repo_language: JavaScript
owner: PrivateSky
file_changes: filename: MySqlPersistence.js
change_type: ModificationType.MODIFY
diff: @@ -21,14 +21,13 @@ function sqlPersistenceStrategy(mysqlPool) {
 
             var validModel = true;
             var model = new modelUtil.ModelDescription(typeName,description,self);
-
+            
             tableStructure[0].forEach(function(column){
-                column['Type'] = column['Type'].split('(')[0];   //ignore size specifications such as INT(10)
+                column['Type'] = column['Type'].split('(')[0];   //ignore size specifications such as INT(10) ... not neccesarily reccomender
             });
 
             model.persistentProperties.some(function(modelProperty){
                 var expectedDbType = self.getDatabaseType(model.getFieldType(modelProperty));
-
                 if(expectedDbType === undefined){
                     validModel = false;
                     return true;
@@ -97,8 +96,7 @@ function sqlPersistenceStrategy(mysqlPool) {
                 callback(err);
             }else{
                 var model = modelUtil.getModel(typeName);
-                
-                var deserialized_id = modelUtil.deserialiseField(typeName,model.getPKField(),serialized_id,self)
+                var deserialized_id = modelUtil.deserialiseField(typeName,model.getPKField(),serialized_id,self);
                 var retObj = createRawObject(typeName, deserialized_id);
                 if (result.length>0) {
                     modelUtil.load(retObj, result[0], self);

programming_language: JavaScript
filename: mysqlUtils.js
change_type: ModificationType.MODIFY
diff: @@ -2,7 +2,7 @@
  * Created by ctalmacel on 12/21/15.
  */
 
-
+var mysql = require('mysql');
 var Q = require('q');
 var modelUtil = require("../../lib/ModelDescription.js");
 
@@ -58,14 +58,7 @@ exports.insertRow = function(tableName,serializedData){
 
 
     for(var field in serializedData){
-        
-        if(model.getFieldDescription(field).type === 'boolean') {
-            query+=' b\''+serializedData[field]+'\',';
-        }else{
-            query+=' \''+serializedData[field]+'\',';
-        }
-
-
+        query+= mysql.escape(serializedData[field])+',';
     }
     query = query.slice(0, -1);
     query+=');';

programming_language: JavaScript
filename: BasicStrategy.js
change_type: ModificationType.MODIFY
diff: @@ -14,7 +14,7 @@ function BasicStrategy(){
         if(dbType !== undefined) {
 
             if(dbType.indexOf(')') != -1){
-                dbType = dbType.slice(dbType.indexOf('('));
+                dbType = dbType.slice(0,dbType.indexOf('('));
             }
             typeToDbTypeCorrespondence[typeName] = dbType;
             dbTypeToTypeCorrespondence[dbType] = typeName;

programming_language: JavaScript
filename: ModelDescription.js
change_type: ModificationType.MODIFY
diff: @@ -132,7 +132,6 @@ function ModelDescription(typeName, description, strategy){
 
         // throw erros if trying to access lazy fields that are not loaded or setting fields #this is not OOP:)
         self.transientProperties.forEach(function(field){
-
             Object.defineProperty(res,field,{
                 get:function(field){
                     return null;
@@ -249,7 +248,7 @@ exports.load = function( rawObject, from , strategy){
     var rawModel = models[rawObject.__meta.typeName];
     var props = rawModel.persistentProperties;
     props.forEach(function(p){
-        if(from[p] || from[p]===false) {
+        if(from.hasOwnProperty(p)) {
             var value = convertFrom(strategy, rawObject.__meta.typeName, p, from[p]);
             rawObject[p] = value;
             rawObject.__meta.savedValues[p] = value;

programming_language: JavaScript
filename: basicSQLTypes.js
change_type: ModificationType.MODIFY
diff: @@ -45,8 +45,7 @@ exports.registerTypeConverters = function(persistence){
 
     persistence.registerConverter('boolean',
         function(value){
-            
-            if(value[0] != '0') {
+            if(value == 1) {
                 return true;
             }
             else {
@@ -54,14 +53,14 @@ exports.registerTypeConverters = function(persistence){
             }
         },
         function(value){
-            if(value){
-                return "1"
+            if(value == true){
+                return 1
             }
             else{
-                return "0"
+                return 0
             }
         },
-        "bit"
+        "tinyint(1)"
     );
 
     persistence.registerConverter('date',
@@ -100,12 +99,6 @@ exports.registerTypeConverters = function(persistence){
             if(arrayOfStuff == "null"){
                 return null;
             }
-            if(arrayOfStuff.length>0&&arrayOfStuff[0].__meta){
-                //the array is of lazy objects and was filled
-                arrayOfStuff = arrayOfStuff.map(function(lazyLoadedObject){
-                    return lazyLoadedObject.__meta.getPK()
-                })
-            }
 
             return JSON.stringify(arrayOfStuff)
         },

programming_language: JavaScript
filename: fillLazyTest.js
change_type: ModificationType.MODIFY
diff: @@ -109,7 +109,7 @@ assert.steps("Load lazy objects test",[
                 });
             })
         })
-    }]);
+    }],1000);
 
 
 

programming_language: JavaScript