SQL Injection via database/sql

CRITICAL

User-controlled input reaches database/sql query methods without parameterization, enabling SQL injection — ranked

Rule Information

Language
Go
Category
Security
Author
Shivasurya
Shivasurya
Last Updated
2026-04-13
Tags
gosecuritysql-injectiondatabase/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-SEC-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
31
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
57
58
59
60
61
62
63
64
65
66
67
68
69
Cross-file analysis: 3 files

About This Rule

Understanding the vulnerability and how it is detected

SQL injection occurs when user-controlled input is concatenated into a SQL query string instead of being passed as a parameterized argument. Go's database/sql package provides safe parameterized queries using placeholder syntax ($1/$2 for PostgreSQL, ? for MySQL and SQLite, @name for named parameters). When developers instead use string concatenation, the database driver interprets user-supplied content as SQL syntax.

**Attack mechanics**: An attacker sends crafted input that closes the current SQL context and injects new SQL statements. For example, in `"SELECT * FROM users WHERE id = " + id`, the attacker provides `1 OR 1=1` to return all rows, or `1; DROP TABLE users; --` on databases that support stacked queries.

**Real-world impact in Go ecosystem**: - "**CVE-2024-35181** (Meshery, CVSS 8.8): SQL injection via parameter manipulation" in the meshery/meshery API, allowing authenticated attackers to read arbitrary data from the database. - "**CVE-2024-35182** (Meshery, CVSS 8.8): Companion vulnerability in the same codebase." - "**CVE-2024-37896** (gin-vue-admin, CVSS 9.8): SQL injection via unsanitized query" parameters in GORM-based queries in the gin-vue-admin administrative framework.

**OWASP testing**: SQL injection is consistently the most frequently tested vulnerability class in penetration tests. The OWASP Go Testing Guide documents Go-specific patterns including ORM-level injections that bypass naive pattern matching.

This rule tracks taint flow from HTTP request sources (net/http, gin, echo, fiber, chi, gorilla/mux) to database/sql sink methods (Query, Exec, QueryRow, and their Context variants). The sanitized_by list includes strconv conversion functions that confirm the value was parsed as a number (making SQL injection impossible for numeric inputs).

Security Implications

Potential attack scenarios if this vulnerability is exploited

1

Authentication Bypass

Injecting ` OR '1'='1` into a login query bypasses credential checks, granting access to any account. Injecting ` OR '1'='1' LIMIT 1` targets the first user (often admin).

2

Full Database Exfiltration

UNION SELECT attacks dump tables not intended for the current query. INFORMATION_SCHEMA allows discovering all table and column names, enabling systematic extraction of the entire database contents.

3

Data Destruction

On databases that support stacked queries (SQL Server, PostgreSQL with some drivers), injected DROP TABLE or DELETE statements destroy production data.

4

Out-of-Band Data Exfiltration

Blind SQL injection via time delays (SLEEP(), pg_sleep()) or DNS callbacks (xp_dirtree on SQL Server, LOAD_FILE on MySQL) allows data extraction without visible query results.

5

Privilege Escalation

Stored procedures with higher privileges (xp_cmdshell on SQL Server) can be invoked through injection, enabling operating system command execution from a database query.

How to Fix

Recommended remediation steps

  • 1Always use parameterized queries: db.Query("... WHERE id = $1", id) not string concat.
  • 2For MySQL/SQLite, use ? placeholder; for PostgreSQL, use $1/$2; for SQL Server, use @p1.
  • 3Use strconv.Atoi or strconv.ParseInt to validate numeric IDs before use (also sanitizes).
  • 4For dynamic ORDER BY columns, validate against an explicit string allowlist.
  • 5Use an ORM like GORM with named parameters for complex queries — see GO-GORM-SQLI rules.
  • 6Apply least-privilege database accounts: read-only accounts cannot DROP TABLE.
  • 7Enable query logging in staging environments to detect unparameterized queries.

Detection Scope

How Code Pathfinder analyzes your code for this vulnerability

Tracks taint from net/http.Request, gin.Context, echo.Context, fiber.Ctx, chi.URLParam, gorilla/mux.Vars to database/sql DB/Tx/Stmt query methods (Query, QueryContext, QueryRow, QueryRowContext, Exec, ExecContext, Prepare, PrepareContext) with global inter-procedural scope.

Compliance & Standards

Industry frameworks and regulations that require detection of this vulnerability

OWASP Top 10
A03:2021 — Injection (SQL injection is the primary sub-category)
CWE Top 25 (2024)
CWE-89 — SQL Injection (ranked #6)
PCI DSS v4.0
Requirement 6.2.4 — Software engineering techniques to prevent or mitigate common software attacks, including injection attacks. SQL injection must be addressed in all applications that handle cardholder data.
NIST SP 800-53 Rev 5
SI-10 — Information Input Validation
HIPAA Security Rule
§164.312(a)(1) — Access control; database access must be protected

References

External resources and documentation

Similar Rules

Explore related security rules for Go

Frequently Asked Questions

Common questions about SQL Injection via database/sql

SQL injection occurs when user-controlled input is concatenated into a SQL query string instead of being passed as a parameterized argument. Go's database/sql package provides safe parameterized queries using placeholder syntax ($1/$2 for PostgreSQL, ? for MySQL and SQLite, @name for named parameters). When developers instead use string concatenation, the database driver interprets user-supplied content as SQL syntax. **Attack mechanics**: An attacker sends crafted input that closes the current SQL context and injects new SQL statements. For example, in `"SELECT * FROM users WHERE id = " + id`, the attacker provides `1 OR 1=1` to return all rows, or `1; DROP TABLE users; --` on databases that support stacked queries. **Real-world impact in Go ecosystem**: - "**CVE-2024-35181** (Meshery, CVSS 8.8): SQL injection via parameter manipulation" in the meshery/meshery API, allowing authenticated attackers to read arbitrary data from the database. - "**CVE-2024-35182** (Meshery, CVSS 8.8): Companion vulnerability in the same codebase." - "**CVE-2024-37896** (gin-vue-admin, CVSS 9.8): SQL injection via unsanitized query" parameters in GORM-based queries in the gin-vue-admin administrative framework. **OWASP testing**: SQL injection is consistently the most frequently tested vulnerability class in penetration tests. The OWASP Go Testing Guide documents Go-specific patterns including ORM-level injections that bypass naive pattern matching. This rule tracks taint flow from HTTP request sources (net/http, gin, echo, fiber, chi, gorilla/mux) to database/sql sink methods (Query, Exec, QueryRow, and their Context variants). The sanitized_by list includes strconv conversion functions that confirm the value was parsed as a number (making SQL injection impossible for numeric inputs).
Use Code Pathfinder to scan your codebase: pathfinder scan --ruleset golang/GO-SEC-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 database/sql rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.

See how it works