JSON Injection

ID

go.json_injection

Severity

high

Resource

Injection

Language

Go

Tags

CWE:116, NIST.SP.800-53, OWASP:2021:A3, PCI-DSS:6.5.1

Description

Improper handling of untrusted data in JSON contexts can lead to injection vulnerabilities, allowing attackers to manipulate JSON structure or inject executable scripts if the output is used insecurely in client-side environments.

Rationale

When user-controlled input is embedded directly into JSON structures without proper validation or encoding, it can lead to JSON injection. In Go, the encoding/json package correctly escapes most special characters, but misuse or unsafe client-side rendering can still create XSS vectors or logic manipulation issues.

A common misuse is when developers concatenate strings into JSON responses rather than fully relying on structured marshaling, or when the response is consumed by browsers or JavaScript engines that might interpret it unsafely.

Consider the following vulnerable code:

func vulnerableHandler(w http.ResponseWriter, r *http.Request) {
	name := r.URL.Query().Get("name")

	resp := map[string]string{
		"message": "Hello " + name,
	}
	jsonBytes, _ := json.Marshal(resp)

	w.Header().Set("Content-Type", "application/json")
	w.Write(jsonBytes)
}

If a user provides a malicious input like </script><script>alert(1)</script>, the resulting JSON would be:

{
  "message": "Hello </script><script>alert(1)</script>"
}

While json.Marshal escapes dangerous characters, if this response is later injected into an HTML page (e.g., via innerHTML), it can lead to XSS. Additionally, logic-based JSON injections are possible if inputs are poorly validated and parsed downstream.

Remediation

  • Never construct JSON via string concatenation — always use json.Marshal or similar structured serializers.

  • Validate and sanitize user inputs before embedding them in any response, especially if the data will eventually be used in client-side scripts or HTML.

  • Ensure proper content-type headers are always used: w.Header().Set("Content-Type", "application/json")

  • Avoid rendering JSON directly into HTML without escaping. If the JSON is embedded into a script or DOM, escape it properly or deliver it via XHR/fetch with strict CSP headers.

  • Prepend JSON responses with a non-executable prefix (optional): w.Write([]byte(")]}',\n"))

This technique helps prevent JSON responses from being executable in certain browser contexts.

  • Apply security headers such as:

    • Content-Security-Policy

    • X-Content-Type-Options: nosniff

These reduce the browser’s ability to interpret JSON as anything other than data.

Configuration

The detector has the following configurable parameters:

  • sources, that indicates the source kinds to check.

  • neutralizations, that indicates the neutralization kinds to check.