{"record":{"id":"a7ef635cd8ddd10f","repo":"Tencent/WeKnora","slug":"function-s-is-not-allowed-dangerous-prefix","errorCode":null,"errorMessage":"function '%s' is not allowed (dangerous prefix)","messagePattern":"function '(.+?)' is not allowed \\(dangerous prefix\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/utils/inject.go","lineNumber":2208,"sourceCode":"\t\t}\n\t\tif schemaName != \"\" && schemaName != \"pg_catalog\" {\n\t\t\treturn fmt.Errorf(\"schema-qualified function calls are not allowed: %s\", schemaName)\n\t\t}\n\t}\n\n\t// Block dangerous function prefixes\n\tif v.checkDangerousFuncs {\n\t\tdangerousPrefixes := []string{\n\t\t\t\"pg_\",     // All pg_* functions (pg_read_file, pg_reload_conf, pg_stat_*, etc.)\n\t\t\t\"lo_\",     // Large object functions (lo_import, lo_export, lo_from_bytea, lo_put, etc.)\n\t\t\t\"dblink\",  // Database link functions\n\t\t\t\"file_\",   // File functions\n\t\t\t\"copy_\",   // Copy functions\n\t\t\t\"binary_\", // Binary functions\n\t\t}\n\t\tfor _, prefix := range dangerousPrefixes {\n\t\t\tif strings.HasPrefix(funcName, prefix) {\n\t\t\t\treturn fmt.Errorf(\"function '%s' is not allowed (dangerous prefix)\", funcName)\n\t\t\t}\n\t\t}\n\n\t\t// Block specific dangerous functions - comprehensive list for RCE prevention\n\t\tdangerousFunctions := map[string]bool{\n\t\t\t// Configuration and settings\n\t\t\t\"current_setting\": true,\n\t\t\t\"set_config\":      true,\n\n\t\t\t// XML/XPath functions (XXE risks)\n\t\t\t\"query_to_xml\":       true,\n\t\t\t\"xpath\":              true,\n\t\t\t\"xmlparse\":           true,\n\t\t\t\"xmlroot\":            true,\n\t\t\t\"xmlelement\":         true,\n\t\t\t\"xmlforest\":          true,\n\t\t\t\"xmlconcat\":          true,\n\t\t\t\"xmlagg\":             true,","sourceCodeStart":2190,"sourceCodeEnd":2226,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/utils/inject.go#L2190-L2226","documentation":"The SQL injection validator rejects any function whose name starts with a known-dangerous prefix (file_, copy_, binary_, etc.). This library parses untrusted SQL expressions before injecting them into queries, and prefixed functions can read/write files or execute binaries, so they are blocked outright. The check runs before the explicit dangerous-function blocklist and the whitelist.","triggerScenarios":"Calling the expression validation/injection API with a function call node whose funcName begins with one of the dangerousPrefixes entries (e.g. file_read('/etc/passwd'), copy_to(...), binary_exec(...)) in a column default, computed column, or filter expression.","commonSituations":"Developers porting DuckDB/postgres-flavored SQL that uses file_ or copy_ table functions to load CSVs; generated SQL from ORMs or LLMs that emit import/export helpers; users pasting data-loading snippets into filter or computed-field inputs.","solutions":["Remove the file_/copy_/binary_ function call and pre-load or pre-compute the data outside the injected expression","Use an allowed scalar function or a parameter placeholder instead of a file/binary function","If the operation is legitimately required, perform it via a dedicated server-side API endpoint rather than SQL injection into the expression","Check the dangerousPrefixes list in internal/utils/inject.go to see which prefix matched and rename nothing — never bypass it; restructure the query"],"exampleFix":"// before\nexpr := \"copy_('data.csv')\"\nValidateExpression(expr)\n// after\ndata := loadDataFromFile(\"data.csv\") // server-side, outside SQL\nexpr := fmt.Sprintf(\"value IN (%s)\", placeholdersFrom(data))","handlingStrategy":"validation","validationCode":"var dangerousPrefixes = []string{\"file_\", \"copy_\", \"binary_\"}\nfunc hasDangerousPrefix(fn string) bool {\n    for _, p := range dangerousPrefixes {\n        if strings.HasPrefix(fn, p) { return true }\n    }\n    return false\n}\n// call before submitting the expression\nif hasDangerousPrefix(extractedFuncName(expr)) { return errors.New(\"expression uses a blocked function prefix\") }","typeGuard":"func isSafeFunctionName(name string) bool {\n    return !strings.HasPrefix(name, \"file_\") &&\n        !strings.HasPrefix(name, \"copy_\") &&\n        !strings.HasPrefix(name, \"binary_\")\n}","tryCatchPattern":"err := injector.Validate(expr)\nif err != nil && strings.Contains(err.Error(), \"dangerous prefix\") {\n    http.Error(w, \"expression contains a disallowed function\", http.StatusBadRequest)\n    return\n}","preventionTips":["Never expose file/copy/binary table functions in user-editable expressions; pre-compute such data server-side","Sanitize LLM/ORM-generated SQL with the validator before injection","Maintain a unit test asserting your app's expression corpus contains no dangerous prefixes"],"tags":["sql-injection","security","validation","rce-prevention"],"backgroundTag":"dangerous-sql-function-blocked","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}