SQL Injection via GORM Raw/Exec

CRITICAL

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.

Rule Information

Language
Go
Category
Security
Author
Shivasurya
Shivasurya
Last Updated
2026-04-13
Tags
gosecuritysql-injectiongormraw-sqlCWE-89OWASP-A03
CWE References

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-001 --project .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
rule.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Cross-file analysis: 3 files

About This Rule

Understanding the vulnerability and how it is detected

GORM is the most widely used Go ORM library. Its query builder methods (Where, Find, First, Create, etc.) automatically parameterize struct conditions — those are generally safe. However, GORM provides Raw() and Exec() methods for executing arbitrary SQL, and these are vulnerable to injection when user input is concatenated into the query string rather than passed as parameterized arguments.

GORM's parameterization syntax uses `?` positional placeholders for MySQL/SQLite and `@name` named parameters for all databases. The critical mistake is using fmt.Sprintf or string concatenation to build the query string passed to Raw()/Exec().

**CVE-2024-37896** (gin-vue-admin, CVSS 9.8 Critical): The most prominent recent Go SQL injection CVE involved a GORM-based application where query parameters were passed to GORM methods without sanitization, enabling authenticated attackers to perform full SQL injection. gin-vue-admin has 20,000+ GitHub stars and is used in many production administrative systems.

**GORM Security documentation** explicitly warns: "Raw SQL user inputs should be sanitized to prevent SQL injection." The GORM docs list known unsafe patterns, including passing user input directly to Raw(), Exec(), Order(), Group(), and Having().

**The false sense of security problem**: Developers using GORM often assume the ORM prevents SQL injection everywhere. The Raw/Exec escape hatch is frequently added for complex queries and is not protected by GORM's builder safety.

Security Implications

Potential attack scenarios if this vulnerability is exploited

1

Bypasses ORM Safety Assumptions

GORM's structured query methods (Where with struct, Find, First) are parameterized automatically. The Raw/Exec pattern breaks this guarantee. Developers who trust GORM for safety may not inspect Raw/Exec calls during security review.

2

Full Database Exfiltration via UNION

UNION SELECT injection against a GORM Raw() call can dump arbitrary tables. GORM automatically scans UNION results into the destination struct — making exfiltrated data immediately available to the attacker in the response.

3

Blind Injection via Scan()

Even when Raw().Scan() appears to limit output to the expected struct fields, blind time-based injection (pg_sleep, SLEEP, WAITFOR) enables data exfiltration via timing channels.

How to Fix

Recommended remediation steps

  • 1Use ? positional placeholders in GORM Raw() and Exec(): db.Raw("WHERE id = ?", id).
  • 2Use @name named parameters for complex queries with multiple reused values.
  • 3Prefer GORM's struct-based query builder (Where, Find, First, Create) over Raw/Exec.
  • 4Validate dynamic column/table names against an explicit allowlist before use.
  • 5Enable GORM's Logger in development to review generated SQL for unexpected patterns.
  • 6See GORM security documentation for the authoritative list of unsafe patterns.

Detection Scope

How Code Pathfinder analyzes your code for this vulnerability

Tracks taint from HTTP framework sources (net/http, gin, echo, fiber) to gorm.DB Raw() and Exec() methods with global inter-procedural scope.

Compliance & Standards

Industry frameworks and regulations that require detection of this vulnerability

OWASP Top 10
A03:2021 — Injection
CWE Top 25 (2024)
CWE-89 — SQL Injection (ranked #6)
PCI DSS v4.0
Requirement 6.2.4 — Protect against injection attacks

References

External resources and documentation

Similar Rules

Explore related security rules for Go

Frequently Asked Questions

Common questions about SQL Injection via GORM Raw/Exec

GORM is the most widely used Go ORM library. Its query builder methods (Where, Find, First, Create, etc.) automatically parameterize struct conditions — those are generally safe. However, GORM provides Raw() and Exec() methods for executing arbitrary SQL, and these are vulnerable to injection when user input is concatenated into the query string rather than passed as parameterized arguments. GORM's parameterization syntax uses `?` positional placeholders for MySQL/SQLite and `@name` named parameters for all databases. The critical mistake is using fmt.Sprintf or string concatenation to build the query string passed to Raw()/Exec(). **CVE-2024-37896** (gin-vue-admin, CVSS 9.8 Critical): The most prominent recent Go SQL injection CVE involved a GORM-based application where query parameters were passed to GORM methods without sanitization, enabling authenticated attackers to perform full SQL injection. gin-vue-admin has 20,000+ GitHub stars and is used in many production administrative systems. **GORM Security documentation** explicitly warns: "Raw SQL user inputs should be sanitized to prevent SQL injection." The GORM docs list known unsafe patterns, including passing user input directly to Raw(), Exec(), Order(), Group(), and Having(). **The false sense of security problem**: Developers using GORM often assume the ORM prevents SQL injection everywhere. The Raw/Exec escape hatch is frequently added for complex queries and is not protected by GORM's builder safety.
Use Code Pathfinder to scan your codebase: pathfinder scan --ruleset golang/GO-GORM-SQLI-001 --project .
This vulnerability is rated as CRITICAL severity.
Yes! Code Pathfinder allows you to customize rules. Modify detection patterns, adjust severity levels, add custom sanitizers, and configure the rule to fit your organization's security policies.

New feature

Get these findings posted directly on your GitHub pull requests

The SQL Injection via GORM Raw/Exec rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.

See how it works