HIGH sql injectionginapi keys

Sql Injection in Gin with Api Keys

Sql Injection in Gin with Api Keys — how this specific combination creates or exposes the vulnerability

SQL injection in a Gin API that uses API keys can occur when user-controlled input is concatenated into SQL queries, even when an API key is required for access. An API key typically identifies the caller and may be used for authorization, but it does not sanitize or validate other inputs. If a developer retrieves the API key from headers (e.g., Authorization or a custom header) and then builds SQL queries using string concatenation with other parameters such as user_id or resource_id, the API key does not protect against malicious input in those parameters.

For example, consider a route that includes a numeric identifier supplied by the client and an API key used only for authentication. If the handler does not use parameterized queries and instead interpolates the identifier into the SQL string, an attacker who knows or guesses a valid API key can still exploit the injection path. The API key grants the request passes authentication checks, but the underlying query remains vulnerable because the identifier is not properly escaped or parameterized. This situation maps to common weaknesses such as `CWE-89` and is a frequent finding in OWASP API Top 10 related to broken object-level authorization and injection flaws.

In a black-box scan, middleBrick tests unauthenticated endpoints by attempting to infer whether input is reflected in error messages or behavior. When an API key is required, middleBrick can first attempt to obtain a valid key through discovery or use a placeholder to evaluate whether authentication is enforced. If authentication is weak or bypassed, or if the key is leaked in logs or error responses, the attack surface grows. Even when authentication is enforced, SQL injection remains possible if the endpoint mixes authenticated context with unsafe query construction. The presence of an API key should not create a false sense of security; it must be paired with strict input validation and safe query practices.

Real-world examples include queries that concatenate identifiers, search terms, or sorting fields. An attacker may supply a payload such as 1 OR 1=1 in a parameter like category_id, and if the query is built by string formatting, the API key does not mitigate the impact. Additionally, error messages returned by the database may disclose schema details, aiding further exploitation. Because Gin does not automatically parameterize queries, developers must explicitly use prepared statements or an ORM that enforces parameterization to prevent injection regardless of the presence of API keys.

Api Keys-Specific Remediation in Gin — concrete code fixes

To remediate SQL injection in Gin when using API keys, always enforce authentication first, then use parameterized queries for any user-controlled data. Below are concrete patterns that combine API key validation with safe database access.

1. Use middleware to validate the API key and attach identity to the context, then use parameterized queries in handlers:

func APIKeyMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        key := c.GetHeader("X-API-Key")
        if !isValidKey(key) {
            c.AbortWithStatusJSON(401, gin.H{"error": "invalid api key"})
            return
        }
        c.Set("api_key", key)
        c.Next()
    }
}

func isValidKey(key string) bool {
    // compare against a secure store; keep this simple for example
    return key == "trusted-key-123"
}

2. In the handler, use parameterized queries with database/sql (assuming a PostgreSQL driver) to avoid SQL injection:

import (
    "database/sql"
    "net/http"
    "github.com/gin-gonic/gin"
)

func GetItem(c *gin.Context) {
    apiKey, _ := c.Get("api_key")
    _ = apiKey // use as needed for logging or audit

    itemID := c.Query("item_id")
    if itemID == "" {
        c.JSON(400, gin.H{"error": "missing item_id"})
        return
    }

    var name string
    // Safe: parameterized query, itemID is not interpolated into SQL text
    err := db.QueryRow("SELECT name FROM items WHERE id = $1", itemID).Scan(&name)
    if err != nil {
        c.JSON(500, gin.H{"error": "server error"})
        return
    }
    c.JSON(200, gin.H{"name": name})
}

3. If you use an ORM like GORM, ensure you rely on its built-in parameterization and avoid raw SQL with concatenation:

import (
    "github.com/gin-gonic/gin"
    "gorm.io/gorm"
)

type Item struct {
    ID   uint `json:"id"`
    Name string `json:"name"`
}

func GetItemGORM(c *gin.Context) {
    apiKey, _ := c.Get("api_key")
    _ = apiKey

    var item Item
    // GORM automatically parameterizes; do not use raw string concatenation
    if err := db.Where("id = ?", c.Query("item_id")).First(&item).Error; err != nil {
        c.JSON(404, gin.H{"error": "not found"})
        return
    }
    c.JSON(200, gin.H{"item": item})
}

These patterns ensure that the API key is validated early and that user inputs are never directly interpolated into SQL. The API key controls who can call the endpoint, while parameterized queries control how inputs are interpreted by the database, eliminating injection regardless of the API key’s presence.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Does using an API key automatically prevent SQL injection in Gin APIs?
No. An API key can authenticate requests, but it does not prevent SQL injection. Injection occurs when user input is improperly concatenated into SQL queries. You must use parameterized queries or an ORM to safely handle inputs, regardless of API key usage.
Can middleBrick detect SQL injection in authenticated Gin endpoints that require API keys?
Yes. middleBrick can first validate the presence and validity of an API key, then test authenticated endpoints for SQL injection by probing parameter handling. Findings will highlight whether authentication protects only entry points while leaving downstream queries vulnerable.