Every CVESearch/Get API key

GHSA-rjwr-m7qx-3fjr

oapi-codegen: OpenAPI Server Description Escapes Generated Go Comment and Injects Executable Code

0.0 NoneFix available

GHSA-rjwr-m7qx-3fjr is a none vulnerability (CVSS 0.0) in github.com/oapi-codegen/oapi-codegen/v2, published July 17, 2026. No source lists public exploit code. Fixed in github.com/oapi-codegen/oapi-codegen/v2 2.7.1.

What does this mean?
Severity
0.0 NoneCVSS 3.1, GitHub Advisories
Exploit chance
UnscoredNo EPSS score yet
Exploitation
None knownNot on CISA’s or ENISA’s lists

Description

Summary

The vulnerability in oapi-codegen seems to be similar with CVE-2026-22785, which is a generated-code injection issue where untrusted OpenAPI summary text is embedded into generated TypeScript MCP server source without proper escaping. oapi-codegen has a similar vulnerability in its server URL generator: untrusted OpenAPI servers[].description text is inserted into a generated Go line comment without normalizing embedded newlines. A crafted description can break out of the comment, add imports through goimports, and emit executable Go declarations into the generated package.

[!NOTE] A vulnerability like this requires that it is missed in code review and that you then call the malicious method.

Using an init() function could be enough to not require a direct call to the code, and instead rely on you importing the package, but either way, code review should be performed before any oapi-codegen generated code is executed.

We strongly recommend all users to be reviewing changes to their generated code before they execute anything within it, to protect against supply chain attacks or malicious injected code.

This is also why we recommend oapi-codegen generated code is committed to source control.

Details

The vulnerable sink is in pkg/codegen/templates/server-urls.tmpl.

// {{ .GoName }} defines the Server URL for {{ if len .OAPISchema.Description }}{{ .OAPISchema.Description }}{{ else }}{{ .OAPISchema.URL }}{{ end }}
const {{ .GoName}} = "{{ .OAPISchema.URL }}"

This template assumes the OpenAPI server description remains inside a single Go line comment. However, OpenAPI descriptions are attacker-controlled strings and may contain newlines. Once a newline is present, the next line is no longer part of the comment.

The same raw description is also used in the function form of server URL generation:

// New{{ .GoName }} constructs the Server URL for {{ .OAPISchema.Description }}, with the provided variables.
func New{{ .GoName }}({{ .NewServerFunctionParams }}) (string, error) {

Identifier generation does not protect this sink. In pkg/codegen/server_urls.go, the description is normalized only for the generated Go identifier:

suffix := server.Description
if suffix == "" {
	suffix = nameNormalizer(server.URL)
}
name = serverURLPrefix + UppercaseFirstCharacter(suffix)
name = nameNormalizer(name)

The identifier is sanitized, but the raw server.Description is still rendered in the comment template. This leaves the code-generation context vulnerable.

The generated file is then formatted with goimports in pkg/codegen/codegen.go:

goCode := SanitizeCode(buf.String())

outBytes, err := imports.Process(opts.PackageName+".go", []byte(goCode), nil)

SanitizeCode only removes byte-order marks:

func SanitizeCode(goCode string) string {
	return strings.ReplaceAll(goCode, "\uFEFF", "")
}

It does not escape comments, replace newlines, or otherwise serialize untrusted text for a Go source-code context. As a result, attacker-controlled source can be preserved and formatted as valid Go.

How to Reproduce

The attacker-controlled input is an OpenAPI document whose servers[].description contains a newline followed by Go declarations:

openapi: "3.0.0"
info:
  title: oapi-codegen server URL description injection
  version: "1.0.0"
servers:
  - url: https://api.example.com
    description: |
      benign
      var _ = func() int {
          panic("oapi-codegen generated-code execution")
          return 0
      }()
      //
paths: {}

Generate Go source with server URL generation enabled. No special local path or helper file is required for the vulnerability; the malicious description is copied into the generated source-code context.

The generated source contains attacker-controlled executable code:

// ServerUrlBenignvarFuncIntPanicOapiCodegenGeneratedCodeExecutionReturn0 defines the Server URL for benign
var _ = func() int {
	panic("oapi-codegen generated-code execution")
	return 0
}()

//

const ServerUrlBenignvarFuncIntPanicOapiCodegenGeneratedCodeExecutionReturn0 = "https://api.example.com"

Impact

An attacker who can supply or influence an OpenAPI document consumed by oapi-codegen can inject arbitrary Go source into the generated package. In common API-client/server generation workflows, this can lead to build-time or runtime code execution in developer machines, CI systems, or downstream applications that trust generated code.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
None
Availability
None

Affected packages

Affected packages
PackageAffectedFixed
github.com/oapi-codegen/oapi-codegen/v2
Go
through 2.7.0
2.7.1
github.com/oapi-codegen/oapi-codegen/v2
Go
before 2.7.1
2.7.1
github.com/oapi-codegen/oapi-codegen
Go
All versionsNone known

What each source reports

GitHub Advisories Score used0.0

oapi-codegen: OpenAPI Server Description Escapes Generated Go Comment and Injects Executable Code

Summary

The vulnerability in oapi-codegen seems to be similar with CVE-2026-22785, which is a generated-code injection issue where untrusted OpenAPI summary text is embedded into generated TypeScript MCP server source without proper escaping. oapi-codegen has a similar vulnerability in its server URL generator: untrusted OpenAPI servers[].description text is inserted into a generated Go line comment without normalizing embedded newlines. A crafted description can break out of the comment, add imports through goimports, and emit executable Go declarations into the generated package.

[!NOTE] A vulnerability like this requires that it is missed in code review and that you then call the malicious method.

Using an init() function could be enough to not require a direct call to the code, and instead rely on you importing the package, but either way, code review should be performed before any oapi-codegen generated code is executed.

We strongly recommend all users to be reviewing changes to their generated code before they execute anything within it, to protect against supply chain attacks or malicious injected code.

This is also why we recommend oapi-codegen generated code is committed to source control.

Details

The vulnerable sink is in pkg/codegen/templates/server-urls.tmpl.

// {{ .GoName }} defines the Server URL for {{ if len .OAPISchema.Description }}{{ .OAPISchema.Description }}{{ else }}{{ .OAPISchema.URL }}{{ end }}
const {{ .GoName}} = "{{ .OAPISchema.URL }}"

This template assumes the OpenAPI server description remains inside a single Go line comment. However, OpenAPI descriptions are attacker-controlled strings and may contain newlines. Once a newline is present, the next line is no longer part of the comment.

The same raw description is also used in the function form of server URL generation:

// New{{ .GoName }} constructs the Server URL for {{ .OAPISchema.Description }}, with the provided variables.
func New{{ .GoName }}({{ .NewServerFunctionParams }}) (string, error) {

Identifier generation does not protect this sink. In pkg/codegen/server_urls.go, the description is normalized only for the generated Go identifier:

suffix := server.Description
if suffix == "" {
	suffix = nameNormalizer(server.URL)
}
name = serverURLPrefix + UppercaseFirstCharacter(suffix)
name = nameNormalizer(name)

The identifier is sanitized, but the raw server.Description is still rendered in the comment template. This leaves the code-generation context vulnerable.

The generated file is then formatted with goimports in pkg/codegen/codegen.go:

goCode := SanitizeCode(buf.String())

outBytes, err := imports.Process(opts.PackageName+".go", []byte(goCode), nil)

SanitizeCode only removes byte-order marks:

func SanitizeCode(goCode string) string {
	return strings.ReplaceAll(goCode, "\uFEFF", "")
}

It does not escape comments, replace newlines, or otherwise serialize untrusted text for a Go source-code context. As a result, attacker-controlled source can be preserved and formatted as valid Go.

How to Reproduce

The attacker-controlled input is an OpenAPI document whose servers[].description contains a newline followed by Go declarations:

openapi: "3.0.0"
info:
  title: oapi-codegen server URL description injection
  version: "1.0.0"
servers:
  - url: https://api.example.com
    description: |
      benign
      var _ = func() int {
          panic("oapi-codegen generated-code execution")
          return 0
      }()
      //
paths: {}

Generate Go source with server URL generation enabled. No special local path or helper file is required for the vulnerability; the malicious description is copied into the generated source-code context.

The generated source contains attacker-controlled executable code:

// ServerUrlBenignvarFuncIntPanicOapiCodegenGeneratedCodeExecutionReturn0 defines the Server…
Record
GHSA-rjwr-m7qx-3fjr
CVSS 3.1
0.0 NoneCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N
Weakness
CWE-74
Updated
2026-11-02
OSV0.0

oapi-codegen: OpenAPI Server Description Escapes Generated Go Comment and Injects Executable Code

Summary

The vulnerability in oapi-codegen seems to be similar with CVE-2026-22785, which is a generated-code injection issue where untrusted OpenAPI summary text is embedded into generated TypeScript MCP server source without proper escaping. oapi-codegen has a similar vulnerability in its server URL generator: untrusted OpenAPI servers[].description text is inserted into a generated Go line comment without normalizing embedded newlines. A crafted description can break out of the comment, add imports through goimports, and emit executable Go declarations into the generated package.

[!NOTE] A vulnerability like this requires that it is missed in code review and that you then call the malicious method.

Using an init() function could be enough to not require a direct call to the code, and instead rely on you importing the package, but either way, code review should be performed before any oapi-codegen generated code is executed.

We strongly recommend all users to be reviewing changes to their generated code before they execute anything within it, to protect against supply chain attacks or malicious injected code.

This is also why we recommend oapi-codegen generated code is committed to source control.

Details

The vulnerable sink is in pkg/codegen/templates/server-urls.tmpl.

// {{ .GoName }} defines the Server URL for {{ if len .OAPISchema.Description }}{{ .OAPISchema.Description }}{{ else }}{{ .OAPISchema.URL }}{{ end }}
const {{ .GoName}} = "{{ .OAPISchema.URL }}"

This template assumes the OpenAPI server description remains inside a single Go line comment. However, OpenAPI descriptions are attacker-controlled strings and may contain newlines. Once a newline is present, the next line is no longer part of the comment.

The same raw description is also used in the function form of server URL generation:

// New{{ .GoName }} constructs the Server URL for {{ .OAPISchema.Description }}, with the provided variables.
func New{{ .GoName }}({{ .NewServerFunctionParams }}) (string, error) {

Identifier generation does not protect this sink. In pkg/codegen/server_urls.go, the description is normalized only for the generated Go identifier:

suffix := server.Description
if suffix == "" {
	suffix = nameNormalizer(server.URL)
}
name = serverURLPrefix + UppercaseFirstCharacter(suffix)
name = nameNormalizer(name)

The identifier is sanitized, but the raw server.Description is still rendered in the comment template. This leaves the code-generation context vulnerable.

The generated file is then formatted with goimports in pkg/codegen/codegen.go:

goCode := SanitizeCode(buf.String())

outBytes, err := imports.Process(opts.PackageName+".go", []byte(goCode), nil)

SanitizeCode only removes byte-order marks:

func SanitizeCode(goCode string) string {
	return strings.ReplaceAll(goCode, "\uFEFF", "")
}

It does not escape comments, replace newlines, or otherwise serialize untrusted text for a Go source-code context. As a result, attacker-controlled source can be preserved and formatted as valid Go.

How to Reproduce

The attacker-controlled input is an OpenAPI document whose servers[].description contains a newline followed by Go declarations:

openapi: "3.0.0"
info:
  title: oapi-codegen server URL description injection
  version: "1.0.0"
servers:
  - url: https://api.example.com
    description: |
      benign
      var _ = func() int {
          panic("oapi-codegen generated-code execution")
          return 0
      }()
      //
paths: {}

Generate Go source with server URL generation enabled. No special local path or helper file is required for the vulnerability; the malicious description is copied into the generated source-code context.

The generated source contains attacker-controlled executable code:

// ServerUrlBenignvarFuncIntPanicOapiCodegenGeneratedCodeExecutionReturn0 defines the Server…
Record
GHSA-rjwr-m7qx-3fjr
CVSS 3.1
0.0 NoneCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N
Weakness
CWE-74
Updated
2026-11-02
OSVGO-2026-6016No score

oapi-codegen: OpenAPI Server Description Escapes Generated Go Comment and Injects Executable Code in github.com/oapi-codegen/oapi-codegen

oapi-codegen: OpenAPI Server Description Escapes Generated Go Comment and Injects Executable Code in github.com/oapi-codegen/oapi-codegen

Record
GO-2026-6016
Updated
2026-11-02

History

History
RecordedChangedSources
first indexedGitHub Advisories, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open