Tencent/WeKnora · error
access to '%s' is not allowed
Error message
access to '%s' is not allowed
What it means
The identifier validator rejected a column whose lowercased name starts with pg_, reserving PostgreSQL's pg_* namespace (system catalogs like pg_catalog, pg_class, pg_attribute). Blocking this prefix prevents injected expressions from referencing catalog tables or shadowing catalog functions for information disclosure. It follows the exact-match system column check in the same function.
Source
Thrown at internal/utils/inject.go:2351
func (v *sqlValidator) validateColumnRef(cr *pg_query.ColumnRef) error {
if !v.checkSystemColumns {
return nil
}
// Check for system column access
for _, field := range cr.Fields {
if s := field.GetString_(); s != nil {
colName := strings.ToLower(s.Sval)
// Block access to system columns
systemColumns := []string{"xmin", "xmax", "cmin", "cmax", "ctid", "tableoid"}
for _, sysCol := range systemColumns {
if colName == sysCol {
return fmt.Errorf("access to system column '%s' is not allowed", colName)
}
}
// Block pg_ prefixed identifiers
if strings.HasPrefix(colName, "pg_") {
return fmt.Errorf("access to '%s' is not allowed", colName)
}
}
}
return nil
}
// getTypeName extracts the type name from a TypeName node
func (v *sqlValidator) getTypeName(tn *pg_query.TypeName) string {
var parts []string
for _, name := range tn.Names {
if s := name.GetString_(); s != nil {
parts = append(parts, s.Sval)
}
}
return strings.Join(parts, ".")
}
View on GitHub (pinned to 988cbb0330)
Solutions
- Rename any application column that starts with pg_ to a non-reserved name
- Remove pg_* function/table references from the expression; use allowlisted equivalents
- For catalog inspection, connect directly with a DBA tool instead of validated expressions
- Audit generated SQL from ORMs/LLMs for pg_-prefixed helpers before submitting
Example fix
// before filter := "pg_sleep(5) IS NULL" // after // remove the call entirely; delay tactics have no valid use in filters filter := "status = 'active'"
Defensive patterns
Strategy: validation
Validate before calling
func usesPgReservedPrefix(ident string) bool {
return strings.HasPrefix(strings.ToLower(ident), "pg_")
}
// reject before submission
if usesPgReservedPrefix(columnName) { return errors.New("identifiers must not start with pg_") } Type guard
func isSafeIdentifier(name string) bool {
if name == "" { return false }
n := strings.ToLower(name)
if strings.HasPrefix(n, "pg_") { return false }
for _, c := range n {
if !(c == '_' || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) { return false }
}
return true
} Try / catch
if err := injector.Validate(expr); err != nil {
if strings.Contains(err.Error(), "is not allowed") && strings.Contains(strings.ToLower(err.Error()), "pg_") {
return fmt.Errorf("identifier uses the reserved pg_ prefix: %w", err)
}
return err
} Prevention
- Lint schemas to forbid pg_-prefixed column/table names at migration time
- Strip catalog references from generated SQL before validation
- Keep an internal lint rule flagging pg_* function calls in expression templates
When it happens
Trigger: An expression or filter containing an identifier like pg_sleep, pg_read_file, pg_catalog.pg_class, or a user column accidentally named pg_owner passed through the identifier validation path (field.GetString_() branch).
Common situations: Time-based injection attempts using pg_sleep; catalog-enumeration queries (pg_tables, pg_user) pasted into filters; legitimate columns whose names collide with the pg_ prefix after a schema rename.
Related errors
- access to system column '%s' is not allowed
- function '%s' is not allowed (dangerous prefix)
- function '%s' is not allowed
- function not allowed: %s
- join request not found
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/9c47bf5523993c12.
Report an issue: GitHub.