{"record":{"id":"f45be0744cac3b97","repo":"flipped-aurora/gin-vue-admin","slug":"order-by-s-is-not-secure","errorCode":null,"errorMessage":"order by %s is not secure","messagePattern":"order by (.+?) is not secure","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_export_template.go","lineNumber":305,"sourceCode":"\t\t// 通过参数传入order\n\t\torder := paramsValues.Get(\"order\")\n\n\t\tif order == \"\" && template.Order != \"\" {\n\t\t\t// 如果没有order入参，这里会使用模板的默认排序\n\t\t\torder = template.Order\n\t\t}\n\n\t\tif order != \"\" {\n\t\t\tcheckOrderArr := strings.Split(order, \" \")\n\t\t\torderStr := \"\"\n\t\t\t// 检查请求的排序字段是否在字段列表中\n\t\t\tif _, ok := fields[checkOrderArr[0]]; !ok {\n\t\t\t\treturn nil, \"\", fmt.Errorf(\"order by %s is not in the fields\", order)\n\t\t\t}\n\t\t\torderStr = checkOrderArr[0]\n\t\t\tif len(checkOrderArr) > 1 {\n\t\t\t\tif checkOrderArr[1] != \"asc\" && checkOrderArr[1] != \"desc\" {\n\t\t\t\t\treturn nil, \"\", fmt.Errorf(\"order by %s is not secure\", order)\n\t\t\t\t}\n\t\t\t\torderStr = orderStr + \" \" + checkOrderArr[1]\n\t\t\t}\n\t\t\tdb = db.Order(orderStr)\n\t\t}\n\n\t\terr = db.Find(&tableMap).Error\n\t\tif err != nil {\n\t\t\treturn nil, \"\", err\n\t\t}\n\t}\n\n\tvar rows [][]string\n\trows = append(rows, tableTitle)\n\tfor _, exTable := range tableMap {\n\t\tvar row []string\n\t\tfor _, column := range columns {\n\t\t\tcolumn = strings.ReplaceAll(column, \"\\\"\", \"\")","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_export_template.go#L287-L323","documentation":"After validating the sort column, ExportExcel checks the sort direction: if the order parameter has a second token it must be exactly 'asc' or 'desc'. Anything else returns this error, again to prevent injecting arbitrary SQL into the ORDER BY clause.","triggerScenarios":"Export request with order like 'created_at ASCENDING', 'id; drop table x', or 'name ASC extra' — any second token that is not the literal lowercase asc or desc.","commonSituations":"Frontend sending uppercase 'DESC' or localized sort words; concatenated query strings accidentally appending extra tokens; attempted SQL injection probes.","solutions":["Send only 'asc' or 'desc' (lowercase) as the direction","Normalize direction to lowercase in the client before building params","Omit the direction token entirely if default ordering is acceptable"],"exampleFix":"// before\nparams: 'order=CreatedAt DESC' // uppercase rejected\n// after\nconst dir = sortDir.toLowerCase()\nif (dir === 'asc' || dir === 'desc') {\n  params = `order=CreatedAt ${dir}`\n}","handlingStrategy":"validation","validationCode":"const safeDir = ['asc', 'desc'].includes(dir) ? dir : 'asc'","typeGuard":null,"tryCatchPattern":"try {\n  await exportExcel(templateId, params)\n} catch (e) {\n  if (e.message.includes('not secure')) {\n    ElMessage.error('排序方向只能是 asc 或 desc')\n  }\n}","preventionTips":["Whitelist directions at the call site","Never interpolate user text into the order token"],"tags":["go","export","sql-injection","validation"],"backgroundTag":"invalid-order-direction","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}