Interactive Playground
Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.
pathfinder scan --ruleset golang/GO-GORM-SQLI-002 --project .About This Rule
Understanding the vulnerability and how it is detected
GORM's query builder methods — Order(), Group(), Having(), Where() with string arguments, Select(), Distinct(), Pluck() — accept raw SQL string fragments for clause construction. Unlike GORM's struct-based conditions which are automatically parameterized, these string-accepting methods pass the argument directly into the SQL clause without escaping.
**ORDER BY injection** is the most common pattern: sorting direction and column selection are frequently exposed as API parameters (`?sort=name&direction=asc`). ORDER BY cannot be parameterized in SQL (placeholders only work for values, not identifiers like column names). This creates a structural injection risk unless column names are validated against an allowlist before being passed to GORM.
**GORM's own documentation** explicitly warns about this pattern in the Security section: "User's inputs should be validated before being used as a query parameter. When using Order(), Group(), or Having() with user input, use allowlist validation."
**Attack example**: `db.Order(r.FormValue("sort"))` with sort value `(SELECT SLEEP(3))` causes a time delay, confirming blind injection. With `name; DROP TABLE users;--` on MySQL, stacked queries may execute.
**Real-world pattern — Fleet**: Fleet (open-source device management platform, 25k+ GitHub stars) has historically exposed API sort parameters directly to GORM's Order() method without allowlist validation. ORDER BY injection is a structural risk in any data-table API that exposes sort column parameters to users.
Security Implications
Potential attack scenarios if this vulnerability is exploited
Blind Time-Based SQL Injection
Injecting `(SELECT SLEEP(5))` (MySQL) or `(SELECT pg_sleep(5))` (PostgreSQL) into an Order() call causes a response delay, confirming injection. Attackers can then exfiltrate data character-by-character via timing channels without any visible output change.
ORDER BY Column Enumeration
Injecting column names not in the SELECT list (e.g., `password ASC`) causes a database error revealing schema information. This enables attackers to discover table columns for targeted UNION attacks.
Stacked Query Execution
On MySQL and SQL Server where stacked queries are supported, injected semicolons can terminate the ORDER BY clause and execute additional SQL statements, enabling data manipulation or schema changes.
Authenticated API Exploitation
These vulnerabilities often appear in administrative API endpoints that expose sort/filter parameters for data tables. Authenticated attackers (including low-privilege users) can exploit these endpoints to access data they should not see.
How to Fix
Recommended remediation steps
- 1Validate all user-supplied ORDER BY column names against an explicit string allowlist.
- 2Never pass raw user input to Order(), Group(), Having(), or Select() as a string.
- 3Use GORM struct conditions for WHERE clauses: db.Where(&Model{Field: value}).
- 4Use ? placeholder for string-based Where with values: db.Where("col = ?", value).
- 5For complex filtering APIs, define a mapping from API parameter names to SQL column names.
- 6Enable GORM logging in staging to inspect all generated SQL.
Detection Scope
How Code Pathfinder analyzes your code for this vulnerability
Tracks taint from HTTP framework sources to GORM query builder methods that accept raw SQL strings: Order(), Group(), Having(), Where() with string first argument, Select(), Joins(), with global inter-procedural scope.
Compliance & Standards
Industry frameworks and regulations that require detection of this vulnerability
References
External resources and documentation
Similar Rules
Explore related security rules for Go
SQL Injection via GORM Raw/Exec
User-controlled input flows into GORM Raw() or Exec() raw SQL methods without parameterization — GORM's ORM safety guarantees do not apply to Raw/Exec with string concatenation.
SQL Injection via database/sql
User-controlled input reaches database/sql query methods without parameterization, enabling SQL injection — ranked
Frequently Asked Questions
Common questions about SQL Injection via GORM Query Builder Methods
New feature
Get these findings posted directly on your GitHub pull requests
The SQL Injection via GORM Query Builder Methods rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.