CVE-2024-37896 (published 2024-06-17T20:15Z)

Gin-vue-admin is a backstage management system based on vue and gin. Gin-vue-admin <= v2.6.5 has SQL injection vulnerability. The SQL injection vulnerabilities occur when a web application allows users to input data into SQL queries without sufficiently validating or sanitizing the input. Failing to properly enforce restrictions on user input could mean that even a basic form input field can be used to inject arbitrary and potentially dangerous SQL commands. This could lead to unauthorized access to the database, data leakage, data manipulation, or even complete compromise of the database server. This vulnerability has been addressed in commit `53d033821` which has been included in release version 2.6.6. Users are advised to upgrade. There are no known workarounds for this vulnerability.


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/flipped-aurora/gin-vue-admin
commit_details: repo_url: https://github.com/flipped-aurora/gin-vue-admin
author: pixelmaxQM
author_date: 2024-06-02 21:13:51+08:00
msg: feature:修复已知安全问题。
repository: repo_url: https://github.com/flipped-aurora/gin-vue-admin
repo_name: flipped-aurora/gin-vue-admin
description: 🚀Vite+Vue3+Gin的开发基础平台，支持TS和JS混用。它集成了JWT鉴权、权限管理、动态路由、显隐可控组件、分页封装、多点登录拦截、资源权限、上传下载、代码生成器【可AI辅助】、表单生成器和可配置的导入导出等开发必备功能。
repo_language: Go
owner: flipped-aurora
file_changes: filename: sys_export_template.go
change_type: ModificationType.MODIFY
diff: @@ -203,14 +203,43 @@ func (sysExportTemplateService *SysExportTemplateService) ExportExcel(templateID
 		}
 	}
 
+	// 获取当前表的所有字段
+	table := template.TableName
+	orderColumns, err := global.GVA_DB.Migrator().ColumnTypes(table)
+	if err != nil {
+		return nil, "", err
+	}
+
+	// 创建一个 map 来存储字段名
+	fields := make(map[string]bool)
+
+	for _, column := range orderColumns {
+		fields[column.Name()] = true
+	}
+
 	// 通过参数传入order
 	order := values.Get("order")
-	if order != "" {
-		db = db.Order(order)
-	}
-	// 模板的默认order
+
 	if order == "" && template.Order != "" {
-		db = db.Order(template.Order)
+		// 如果没有order入参，这里会使用模板的默认排序
+		order = template.Order
+	}
+
+	if order != "" {
+		checkOrderArr := strings.Split(order, " ")
+		orderStr := ""
+		// 检查请求的排序字段是否在字段列表中
+		if _, ok := fields[checkOrderArr[0]]; !ok {
+			return nil, "", fmt.Errorf("order by %s is not in the fields", order)
+		}
+		orderStr = checkOrderArr[0]
+		if len(checkOrderArr) > 1 {
+			if checkOrderArr[1] != "asc" && checkOrderArr[1] != "desc" {
+				return nil, "", fmt.Errorf("order by %s is not secure", order)
+			}
+			orderStr = orderStr + " " + checkOrderArr[1]
+		}
+		db = db.Order(orderStr)
 	}
 
 	err = db.Debug().Find(&tableMap).Error

programming_language: Go
filename: vite.config.js
change_type: ModificationType.MODIFY
diff: @@ -11,12 +11,14 @@ import vuePlugin from '@vitejs/plugin-vue'
 import GvaPosition from './vitePlugin/gvaPosition'
 import GvaPositionServer from './vitePlugin/codeServer'
 import fullImportPlugin from './vitePlugin/fullImport/fullImport.js'
-import { svgBuilder } from './vitePlugin/svgIcon/svgIcon.js'
+import { svgBuilder } from 'vite-auto-import-svg'
+import { AddSecret } from './vitePlugin/secret'
 // @see https://cn.vitejs.dev/config/
 export default ({
   command,
   mode
 }) => {
+  AddSecret("")
   const NODE_ENV = mode || 'development'
   const envFiles = [
     `.env.${NODE_ENV}`
@@ -106,13 +108,13 @@ export default ({
     )
   } else {
     config.plugins.push(AutoImport({
-      resolvers: [ElementPlusResolver()]
-    }),
-    Components({
-      resolvers: [ElementPlusResolver({
-        importStyle: 'sass'
-      })]
-    }))
+        resolvers: [ElementPlusResolver()]
+      }),
+      Components({
+        resolvers: [ElementPlusResolver({
+          importStyle: 'sass'
+        })]
+      }))
   }
   return config
 }

programming_language: JavaScript
filename: index.js
change_type: ModificationType.ADD
diff: @@ -0,0 +1,6 @@
+export function AddSecret(secret) {
+  if(!secret){
+    secret = ""
+  }
+  global['gva-secret'] = secret;
+}

programming_language: TypeScript
filename: svgIcon.js
change_type: ModificationType.DELETE
diff: @@ -1,65 +0,0 @@
-import { readFileSync, readdirSync } from 'fs'
-const svgTitle = /<svg([^>+].*?)>/
-const clearHeightWidth = /(width|height)="([^>+].*?)"/g
-const hasViewBox = /(viewBox="[^>+].*?")/g
-const clearReturn = /(\r)|(\n)/g
-function findSvgFile(dir) {
-  const svgRes = []
-  const dirents = readdirSync(dir, {
-    withFileTypes: true
-  })
-  for (const dirent of dirents) {
-    if (dirent.isDirectory()) {
-      svgRes.push(...findSvgFile(dir + dirent.name + '/'))
-    } else {
-      const svg = readFileSync(dir + dirent.name)
-        .toString()
-        .replace(clearReturn, '')
-        .replace(svgTitle, ($1, $2) => {
-          let width = 0
-          let height = 0
-          let content = $2.replace(clearHeightWidth, (s1, s2, s3) => {
-            if (s2 === 'width') {
-              width = s3
-            } else if (s2 === 'height') {
-              height = s3
-            }
-            return ''
-          })
-          if (!hasViewBox.test($2)) {
-            content += `viewBox="0 0 ${width} ${height}"`
-          }
-          return `<symbol id="${dirent.name.replace('.svg', '')}" ${content}>`
-        })
-        .replace('</svg>', '</symbol>')
-      svgRes.push(svg)
-    }
-  }
-  return svgRes
-}
-export const svgBuilder = (path) => {
-  if (path === '') return
-  const res = findSvgFile(path)
-  const timestamp = Date.now()
-  const secretCode = '087AC4D233B64EB0'
-  return {
-    name: 'svg-transform',
-    transformIndexHtml(html) {
-      return html.replace(
-        '<head>',
-        `
-          <head>
-            <meta name="keywords" content="${timestamp},${secretCode}">
-        `
-      ).replace(
-        '<body>',
-        `
-          <body>
-            <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
-              ${res.join('')}
-            </svg>
-        `
-      )
-    }
-  }
-}

programming_language: unknown