Security scanner flags unhandled errors in generated MarshalGQL methods
First, thank you for this excellent library - it's been a pleasure to work with.
I'm reaching out because our security scanning tools (OWASP dependency check) have flagged an issue in the auto-generated code, specifically related to A4:2021 - Insecure Design. I wanted to bring this to your attention in case you'd like to address it in future releases.
Issue Details The generated MarshalGQL methods for enum types don't handle the error returned by fmt.Fprint(). While this is unlikely to cause issues in practice (since it's typically writing to a buffer), security scanners flag unhandled errors as potential vulnerabilities.
Example from generated code:
The fmt.Fprint function returns (n int, err error), but both return values are currently ignored.
Impact
- Security scanners flag this as a potential security issue
- Compliance requirements may require all errors to be explicitly handled
- Silent failures could theoretically occur if the writer fails (though rare)
Environment
- gqlgen version: v0.17.x (adjust to your version)
- Go version: go1.25.x (adjust to your version)
- Security scanner: OWASP Dependency Check / SonarQube / etc.
Additional Context This affects all generated enum types in graphql.go. The same pattern appears in:
MarshalGQL methods for all enum types Similar patterns in MarshalJSON methods (which use bytes.Buffer, so less likely to fail) I understand this might be considered a false positive by some, but I wanted to report it in case it helps others facing similar compliance requirements.
Thank you for considering this.
Thanks for writing up this report, and I'm sorry for any inconvenience this has caused. I would welcome a PR to address it so that you and others are no longer inconvenienced. I have some thoughts as to two different possible solutions. Do you mind scanning the two alternative implementation code samples described below and telling me what the results are?
Do you know if these scanners will still flag _,_ = fmt.Fprint( (where the return values are explicitly ignored) the same way it will flag the current implicitly ignored returned values? For example, this might be a convenience wrapper we could add as a write.go file to the graphql package:
package graphql
import (
"fmt"
"io"
)
// Fprintf is like fmt.Fprintf but returns nothing
func Fprintf(w io.Writer, format string, a ...any) {
_, _ = fmt.Fprintf(w, format, a...)
}
If so, it would be a very simple fix to change the templates to generate code that uses the convenience wrapper above or to just explicitly _,_ = fmt.Fprint(. I would gladly merge any PR that you made that would do either if it helps you and others.
However, if instead you find these scanners require explicitly assigning the returned error to a variable, checking its value, and handling the error, then that is annoying to me personally. I will still begrudgingly suggest some workarounds, even though many others have judged that labelling such as "Insecure Design" is an instance of inflexibly and mechanically applying an overly broad rule to a situation where it very clearly does not apply. I don't need to cause problems for people just to make some sort of point.
Since writing to a buffer is never going to cause an actual error (unless you have a bigger issue like you are out of memory or something equally dire), you might create a helper function file write.go inside the graphql package:
package graphql
import (
"fmt"
"io"
)
// Fprintf is like fmt.Fprintf but panics if any write error is encountered.
func Fprintf(w io.Writer, format string, a ...any) {
_, err := fmt.Fprintf(w, format, a...)
if err != nil {
panic(err)
}
}
If the templates absolutely had to, then they could use that instead of fmt.Fprintf to avoid triggering this false positive.