Format String Injection

ID

go.format_string_injection

Severity

low

Resource

Injection

Language

Go

Tags

CWE:134, NIST.SP.800-53, PCI-DSS:6.5.1

Description

User-controlled input is used as a format string in functions like fmt.Printf, fmt.Sprintf, or fmt.Fprintf, leading to potential injection of unintended format specifiers, which can cause runtime panics or information disclosure.

Rationale

Format string injection occurs when an attacker can control the format string parameter of formatting functions. In Go, functions such as fmt.Printf, fmt.Sprintf, fmt.Fprintf, and others interpret the first argument as a format string. If this argument is derived from user input, the attacker can inject format verbs (like %s, %x, %v) that alter output behavior, leading to:

  • Program crashes due to missing expected arguments.

  • Disclosure of internal memory layout or structure through verbose or hexadecimal format specifiers.

  • Misleading or manipulated output, potentially exploited in logging or error-handling contexts.

This vulnerability is less severe in Go compared to C/C++, as it does not allow direct memory access. However, it is still a reliability and logging integrity risk, especially in APIs and web services that log user-controlled data.

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    msg := r.URL.Query().Get("msg")
    fmt.Fprintf(w, msg) // FLAW: attacker controls format string
}

Remediation

Always separate user-controlled data from the format string. The format string should be a constant defined by the developer. Interpolated values should be passed as additional arguments.

Prefer format strings like "%s" or safer alternatives like fmt.Print, fmt.Println, or structured logging where format strings are not dynamically constructed.

Safe examples:

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    msg := r.URL.Query().Get("msg")
    fmt.Fprintf(w, "%s", msg) // Safe: user input is data, not format
}

Configuration

The detector has the following configurable parameters:

  • sources, that indicates the source kinds to check.

  • neutralizations, that indicates the neutralization kinds to check.